From 536c687d5a110d1c52f83eeb98d6ee6c05391ba7 Mon Sep 17 00:00:00 2001 From: James Frost Date: Mon, 16 May 2016 14:01:43 +0100 Subject: [PATCH 1/5] Added keyboard shortcuts by implementing `keyCommands` in EditorVC. --- Classes/WPEditorFormatbarView.h | 8 ++++ Classes/WPEditorFormatbarView.m | 15 ++++++++ Classes/WPEditorViewController.m | 64 +++++++++++++++++++++++++++++--- 3 files changed, 81 insertions(+), 6 deletions(-) diff --git a/Classes/WPEditorFormatbarView.h b/Classes/WPEditorFormatbarView.h index d84852d..8b08abc 100644 --- a/Classes/WPEditorFormatbarView.h +++ b/Classes/WPEditorFormatbarView.h @@ -147,6 +147,14 @@ typedef enum */ - (void)toolBarItemWithTag:(WPEditorViewControllerElementTag)tag setVisible:(BOOL)visible; +/** + * @brief Selects or deselects a toolbar item + * + * @param tag WPEditorViewControllerElementTag of the item to alter. + * @param selected YES to make the item selected, NO to deselect it. + */ +- (void)toolBarItemWithTag:(WPEditorViewControllerElementTag)tag setSelected:(BOOL)selected; + /** * @brief Enables and disables the toolbar items. * diff --git a/Classes/WPEditorFormatbarView.m b/Classes/WPEditorFormatbarView.m index c1638c6..b9f7f1f 100644 --- a/Classes/WPEditorFormatbarView.m +++ b/Classes/WPEditorFormatbarView.m @@ -203,6 +203,21 @@ - (void)toolBarItemWithTag:(WPEditorViewControllerElementTag)tag setVisible:(BOO } } +- (void)toolBarItemWithTag:(WPEditorViewControllerElementTag)tag setSelected:(BOOL)selected +{ + for (ZSSBarButtonItem *item in self.leftToolbar.items) { + if (item.tag == tag) { + item.selected = selected; + } + } + + for (ZSSBarButtonItem *item in self.regularToolbar.items) { + if (item.tag == tag) { + item.selected = selected; + } + } +} + - (void)enableToolbarItems:(BOOL)enable shouldShowSourceButton:(BOOL)showSource { diff --git a/Classes/WPEditorViewController.m b/Classes/WPEditorViewController.m index 0de2c54..3edeb18 100644 --- a/Classes/WPEditorViewController.m +++ b/Classes/WPEditorViewController.m @@ -174,6 +174,55 @@ - (void)willTransitionToTraitCollection:(UITraitCollection *)newCollection withT [self.toolbarView setNeedsLayout]; } +#pragma mark - Keyboard shortcuts + +- (BOOL)canBecomeFirstResponder +{ + return YES; +} + +- (NSArray *)keyCommands +{ + return @[ + [UIKeyCommand keyCommandWithInput:@"I" + modifierFlags:UIKeyModifierCommand|UIKeyModifierShift + action:@selector(didTouchMediaOptions) + discoverabilityTitle:NSLocalizedString(@"Insert Image", @"Discoverability title for insert image keyboard shortcut.")], + [UIKeyCommand keyCommandWithInput:@"B" + modifierFlags:UIKeyModifierCommand + action:@selector(setBold) + discoverabilityTitle:NSLocalizedString(@"Bold", @"Discoverability title for bold formatting keyboard shortcut.")], + [UIKeyCommand keyCommandWithInput:@"I" + modifierFlags:UIKeyModifierCommand + action:@selector(setItalic) + discoverabilityTitle:NSLocalizedString(@"Italic", @"Discoverability title for italic formatting keyboard shortcut.")], + [UIKeyCommand keyCommandWithInput:@"-" + modifierFlags:UIKeyModifierCommand|UIKeyModifierShift + action:@selector(setStrikethrough) + discoverabilityTitle:NSLocalizedString(@"Strikethrough", @"Discoverability title for strikethrough formatting keyboard shortcut.")], + [UIKeyCommand keyCommandWithInput:@"B" + modifierFlags:UIKeyModifierCommand|UIKeyModifierShift + action:@selector(setBlockQuote) + discoverabilityTitle:NSLocalizedString(@"Block Quote", @"Discoverability title for block quote keyboard shortcut.")], + [UIKeyCommand keyCommandWithInput:@"K" + modifierFlags:UIKeyModifierCommand + action:@selector(linkBarButtonTapped) + discoverabilityTitle:NSLocalizedString(@"Insert Link", @"Discoverability title for insert link keyboard shortcut.")], + [UIKeyCommand keyCommandWithInput:@"L" + modifierFlags:UIKeyModifierCommand + action:@selector(setUnorderedList) + discoverabilityTitle:NSLocalizedString(@"Unordered List", @"Discoverability title for unordered list keyboard shortcut.")], + [UIKeyCommand keyCommandWithInput:@"L" + modifierFlags:UIKeyModifierCommand|UIKeyModifierShift + action:@selector(setOrderedList) + discoverabilityTitle:NSLocalizedString(@"Ordered List", @"Discoverability title for ordered list keyboard shortcut.")], + [UIKeyCommand keyCommandWithInput:@"H" + modifierFlags:UIKeyModifierCommand|UIKeyModifierShift + action:@selector(showHTMLSource:) + discoverabilityTitle:NSLocalizedString(@"Toggle HTML Source ", @"Discoverability title for HTML keyboard shortcut.")] + ]; +} + #pragma mark - Toolbar: helper methods - (void)clearToolbar @@ -428,24 +477,27 @@ - (void)editorToolbarView:(WPEditorFormatbarView*)editorToolbarView - (void)editorToolbarView:(WPEditorFormatbarView*)editorToolbarView insertLink:(UIBarButtonItem *)barButtonItem { - [self linkBarButtonTapped:(WPEditorToolbarButton *)barButtonItem]; + [self linkBarButtonTapped]; } #pragma mark - Editor Interaction - (void)showHTMLSource:(UIBarButtonItem *)barButtonItem -{ +{ if ([self.editorView isInVisualMode]) { if ([self askOurDelegateShouldDisplaySourceView]) { [self.editorView showHTMLSource]; - barButtonItem.tintColor = [self barButtonItemSelectedDefaultColor]; + [self.toolbarView toolBarItemWithTag:kWPEditorViewControllerElementShowSourceBarButton + setSelected:YES]; } else { // Deselect the HTML button so it is in the proper state - [(UIButton *)barButtonItem setSelected:NO]; + [self.toolbarView toolBarItemWithTag:kWPEditorViewControllerElementShowSourceBarButton + setSelected:NO]; } } else { [self.editorView showVisualEditor]; - barButtonItem.tintColor = [self.toolbarView itemTintColor]; + [self.toolbarView toolBarItemWithTag:kWPEditorViewControllerElementShowSourceBarButton + setSelected:NO]; } [WPAnalytics track:WPAnalyticsStatEditorTappedHTML]; @@ -621,7 +673,7 @@ - (void)redo:(ZSSBarButtonItem *)barButtonItem [self.editorView redo]; } -- (void)linkBarButtonTapped:(WPEditorToolbarButton*)button +- (void)linkBarButtonTapped { if ([self.editorView isSelectionALink]) { [self removeLink]; From 7b0be2fd4823614f287e2d5de24ba5924d701b43 Mon Sep 17 00:00:00 2001 From: James Frost Date: Tue, 17 May 2016 11:19:13 +0100 Subject: [PATCH 2/5] Added keyboard shortcut support to the legacy editor. --- Classes/WPLegacyEditorStyledTextView.h | 25 +++++++ Classes/WPLegacyEditorStyledTextView.m | 33 +++++++++ Classes/WPLegacyEditorViewController.m | 76 +++++++++++++++++++-- Example/Pods/Pods.xcodeproj/project.pbxproj | 8 +++ 4 files changed, 136 insertions(+), 6 deletions(-) create mode 100644 Classes/WPLegacyEditorStyledTextView.h create mode 100644 Classes/WPLegacyEditorStyledTextView.m diff --git a/Classes/WPLegacyEditorStyledTextView.h b/Classes/WPLegacyEditorStyledTextView.h new file mode 100644 index 0000000..8a7622c --- /dev/null +++ b/Classes/WPLegacyEditorStyledTextView.h @@ -0,0 +1,25 @@ +#import + +/** + UITextView subclass that allows basic styling of text using the floating format + menu or via keyboard shortcuts (which may be defined in a containing view + controller by implementing `keyCommands`). + + Defers marking up or styling the text to another class through a number of + blocks. These are executed whenever the user uses the format menu or presses + the standard keyboard shortcut associated with a particular formatting action. + + This is necessary to add keyboard shortcut functionality to the legacy editor, + because of an iOS 9 bug where http://www.openradar.me/25463955 shortcuts for + bold, italic, and underline don't work correctly. The workaround is to set + `allowsEditingTextAttributes` to YES on the textview, and implement + `toggleBoldface:`, `toggleItalics:`, and `toggleUnderline:` on the textview to + handle the actions. + */ +@interface WPLegacyEditorStyledTextView : UITextView + +@property (nonatomic, copy) void (^toggleBoldBlock)(); +@property (nonatomic, copy) void (^toggleItalicBlock)(); +@property (nonatomic, copy) void (^toggleUnderlineBlock)(); + +@end diff --git a/Classes/WPLegacyEditorStyledTextView.m b/Classes/WPLegacyEditorStyledTextView.m new file mode 100644 index 0000000..3aab958 --- /dev/null +++ b/Classes/WPLegacyEditorStyledTextView.m @@ -0,0 +1,33 @@ +#import "WPLegacyEditorStyledTextView.h" + +@implementation WPLegacyEditorStyledTextView + +- (instancetype)initWithFrame:(CGRect)frame +{ + if (self = [super initWithFrame:frame]) { + self.allowsEditingTextAttributes = YES; + } + + return self; +} + +- (void)toggleBoldface:(id)sender +{ + if (self.toggleBoldBlock) { + self.toggleBoldBlock(); + } +} +- (void)toggleItalics:(id)sender +{ + if (self.toggleItalicBlock) { + self.toggleItalicBlock(); + } +} +- (void)toggleUnderline:(id)sender +{ + if (self.toggleUnderlineBlock) { + self.toggleUnderlineBlock(); + } +} + +@end diff --git a/Classes/WPLegacyEditorViewController.m b/Classes/WPLegacyEditorViewController.m index ddfc340..bf4f627 100644 --- a/Classes/WPLegacyEditorViewController.m +++ b/Classes/WPLegacyEditorViewController.m @@ -1,11 +1,13 @@ #import "WPLegacyEditorViewController.h" #import "WPLegacyEditorFormatToolbar.h" #import "WPLegacyEditorFormatAction.h" +#import "WPLegacyEditorStyledTextView.h" #import CGFloat const WPLegacyEPVCStandardOffset = 15.0; CGFloat const WPLegacyEPVCTextViewOffset = 10.0; + @interface WPLegacyEditorViewController () @property (nonatomic) CGPoint scrollOffsetRestorePoint; @@ -154,13 +156,22 @@ - (void)setupTextView // Height should never be smaller than what is required to display its text. if (!self.textView) { - self.textView = [[UITextView alloc] initWithFrame:frame]; - self.textView.autoresizingMask = mask; - self.textView.delegate = self; - self.textView.font = self.bodyFont; - self.textView.textColor = self.bodyColor; - self.textView.accessibilityLabel = NSLocalizedString(@"Content", @"Post content"); + WPLegacyEditorStyledTextView *textView = [[WPLegacyEditorStyledTextView alloc] initWithFrame:frame]; + textView.autoresizingMask = mask; + textView.delegate = self; + textView.font = self.bodyFont; + textView.textColor = self.bodyColor; + textView.allowsEditingTextAttributes = YES; + textView.accessibilityLabel = NSLocalizedString(@"Content", @"Post content"); + + __weak typeof(self) weakSelf = self; + textView.toggleBoldBlock = ^{ [weakSelf setBold]; }; + textView.toggleItalicBlock = ^{ [weakSelf setItalic]; }; + textView.toggleUnderlineBlock = ^{ [weakSelf setUnderline]; }; + + self.textView = textView; } + [self.view addSubview:self.textView]; // Formatting bar for the textView's inputAccessoryView. @@ -269,6 +280,59 @@ - (void)didTouchMediaOptions } } +#pragma mark - Keyboard Shortcuts + +- (NSArray *)keyCommands +{ + if (![self.textView isFirstResponder]) { + return @[]; + } + + return @[ + [UIKeyCommand keyCommandWithInput:@"B" + modifierFlags:UIKeyModifierCommand + action:@selector(setBold) + discoverabilityTitle:NSLocalizedString(@"Bold", @"Discoverability title for bold formatting keyboard shortcut.")], + [UIKeyCommand keyCommandWithInput:@"I" + modifierFlags:UIKeyModifierCommand + action:@selector(setItalic) + discoverabilityTitle:NSLocalizedString(@"Italic", @"Discoverability title for italic formatting keyboard shortcut.")], + [UIKeyCommand keyCommandWithInput:@"U" + modifierFlags:UIKeyModifierCommand + action:@selector(setUnderline) + discoverabilityTitle:NSLocalizedString(@"Underline", @"Discoverability title for underline formatting keyboard shortcut.")], + [UIKeyCommand keyCommandWithInput:@"-" + modifierFlags:UIKeyModifierCommand|UIKeyModifierShift + action:@selector(setStrikethrough) + discoverabilityTitle:NSLocalizedString(@"Strikethrough", @"Discoverability title for strikethrough formatting keyboard shortcut.")], + [UIKeyCommand keyCommandWithInput:@"B" + modifierFlags:UIKeyModifierCommand|UIKeyModifierShift + action:@selector(setBlockQuote) + discoverabilityTitle:NSLocalizedString(@"Block Quote", @"Discoverability title for block quote keyboard shortcut.")], + [UIKeyCommand keyCommandWithInput:@"K" + modifierFlags:UIKeyModifierCommand + action:@selector(insertLink) + discoverabilityTitle:NSLocalizedString(@"Insert Link", @"Discoverability title for insert link keyboard shortcut.")], + [UIKeyCommand keyCommandWithInput:@"M" + modifierFlags:UIKeyModifierCommand + action:@selector(insertMedia) + discoverabilityTitle:NSLocalizedString(@"Insert Media", @"Discoverability title for insert media keyboard shortcut.")], + [UIKeyCommand keyCommandWithInput:@"M" + modifierFlags:UIKeyModifierCommand|UIKeyModifierShift + action:@selector(insertMore) + discoverabilityTitle:NSLocalizedString(@"Insert More Tag ", @"Discoverability title for insert more tag keyboard shortcut.")] + ]; +} + +- (void)setBold { [self formatToolbar:self.editorToolbar actionPressed:WPLegacyEditorFormatActionBold]; } +- (void)setItalic { [self formatToolbar:self.editorToolbar actionPressed:WPLegacyEditorFormatActionItalic]; } +- (void)setUnderline { [self formatToolbar:self.editorToolbar actionPressed:WPLegacyEditorFormatActionUnderline]; } +- (void)setStrikethrough { [self formatToolbar:self.editorToolbar actionPressed:WPLegacyEditorFormatActionDelete]; } +- (void)insertMedia { [self formatToolbar:self.editorToolbar actionPressed:WPLegacyEditorFormatActionMedia]; } +- (void)insertLink { [self formatToolbar:self.editorToolbar actionPressed:WPLegacyEditorFormatActionLink]; } +- (void)setBlockQuote { [self formatToolbar:self.editorToolbar actionPressed:WPLegacyEditorFormatActionQuote]; } +- (void)insertMore { [self formatToolbar:self.editorToolbar actionPressed:WPLegacyEditorFormatActionMore]; } + #pragma mark - Editor and Misc Methods - (void)startEditing diff --git a/Example/Pods/Pods.xcodeproj/project.pbxproj b/Example/Pods/Pods.xcodeproj/project.pbxproj index efb4e73..69e8ddd 100644 --- a/Example/Pods/Pods.xcodeproj/project.pbxproj +++ b/Example/Pods/Pods.xcodeproj/project.pbxproj @@ -24,6 +24,8 @@ 166EA9FA08D588A3C37BAA233CC71A1F /* CYRToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 30953A5CC1F7C15B2B2569E2B86234B7 /* CYRToken.m */; }; 16AA82DC3E4AC2696DA0931F390E5FC7 /* ZSSh5.png in Resources */ = {isa = PBXBuildFile; fileRef = DD385AEE15545E35E75E9C0D559B2764 /* ZSSh5.png */; }; 170E608BCFB5A7701BBEEA00DEF6889D /* HRCgUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D266ADA1ED925AEE6DFF2EEE04B7A88 /* HRCgUtil.m */; }; + 173BCE6F1CEB205000AE8817 /* WPLegacyEditorStyledTextView.h in Headers */ = {isa = PBXBuildFile; fileRef = 173BCE6D1CEB205000AE8817 /* WPLegacyEditorStyledTextView.h */; }; + 173BCE701CEB205000AE8817 /* WPLegacyEditorStyledTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 173BCE6E1CEB205000AE8817 /* WPLegacyEditorStyledTextView.m */; }; 17ED9445B95C990DC7F77217C2A372C0 /* Merriweather-Italic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 8629C93CB036BC2B431FEAF8EC7A5E88 /* Merriweather-Italic.ttf */; }; 17F91B9CE2CEBFE09A4A7D9470CE0765 /* icon_format_html@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = A80A6F496A0753421F82AD38EAFA3CDC /* icon_format_html@2x.png */; }; 183C87703915312EE7B716FA107B2683 /* DDTTYLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 8A49E19FFA5287CF0054F9FF3F093557 /* DDTTYLogger.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0 -w -Xanalyzer -analyzer-disable-all-checks"; }; }; @@ -372,6 +374,8 @@ 1424C9017E4F9B1766D1E50E4BB296F4 /* NSObject-SafeExpectations-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "NSObject-SafeExpectations-umbrella.h"; sourceTree = ""; }; 169C2E37D8CA323642A8E9D4211FAFE3 /* WPEditorField.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = WPEditorField.m; sourceTree = ""; }; 16FE5F287F1CF6A31EDD264A3EA7F9A3 /* WPStyleGuide.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = WPStyleGuide.m; path = "WordPress-iOS-Shared/Core/WPStyleGuide.m"; sourceTree = ""; }; + 173BCE6D1CEB205000AE8817 /* WPLegacyEditorStyledTextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WPLegacyEditorStyledTextView.h; sourceTree = ""; }; + 173BCE6E1CEB205000AE8817 /* WPLegacyEditorStyledTextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WPLegacyEditorStyledTextView.m; sourceTree = ""; }; 1866E384D9C1BE78E2048F59DADD3BBC /* WPNUXUtility.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = WPNUXUtility.m; path = "WordPress-iOS-Shared/Core/WPNUXUtility.m"; sourceTree = ""; }; 18A435085C70CE4B4601475CB8EFC8CC /* icon_format_keyboard.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = icon_format_keyboard.png; sourceTree = ""; }; 1923CE5DAF984F860E3559547A252308 /* rangy-highlighter.js */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.javascript; path = "rangy-highlighter.js"; sourceTree = ""; }; @@ -1127,6 +1131,8 @@ 2CE62E271066C69FD730291EA4E5AF73 /* WPLegacyEditorFormatToolbar.m */, DE33BBE2AB47600A211CB2D833904605 /* WPLegacyEditorViewController.h */, B174D434444FFD56027D2FBA78A4820C /* WPLegacyEditorViewController.m */, + 173BCE6D1CEB205000AE8817 /* WPLegacyEditorStyledTextView.h */, + 173BCE6E1CEB205000AE8817 /* WPLegacyEditorStyledTextView.m */, A347E40B351E562043797CF5C4F29CAB /* ZSSBarButtonItem.h */, 30864D2D85CCD7AECE8C682FB118243C /* ZSSBarButtonItem.m */, 8AE3843844D187A314FC9BC3917FC457 /* ZSSTextView.h */, @@ -1230,6 +1236,7 @@ 5A7C1352685E2C5DC5305CD490DCFD22 /* UIWebView+GUIFixes.h in Headers */, 7CA0D9CF43973132AF4B5B33764D2184 /* WordPress-iOS-Editor-umbrella.h in Headers */, 9E1A2CA25668BA959253C4D0B3A70BE6 /* WPEditorField.h in Headers */, + 173BCE6F1CEB205000AE8817 /* WPLegacyEditorStyledTextView.h in Headers */, DD9308ADBDA819DB2D4DC6472C125AA9 /* WPEditorFormatbarView.h in Headers */, 8ECC1D04A94121E9E4C80530D5CA39F1 /* WPEditorLoggingConfiguration.h in Headers */, 3D381BDB5478D52BD5046D52E8F181A6 /* WPEditorToolbarButton.h in Headers */, @@ -1720,6 +1727,7 @@ 60FA1EB2D6C6B16B8ACCD2D8B8EB5BB6 /* WPEditorViewController.m in Sources */, 3D1D840F42D18C7D9005788C56F98320 /* WPImageMeta.m in Sources */, BA78A51E19BEC0FD3C88C6224D8FA256 /* WPLegacyEditorFormatAction.m in Sources */, + 173BCE701CEB205000AE8817 /* WPLegacyEditorStyledTextView.m in Sources */, 37CB8DE501F08F4758090D9AF27708E7 /* WPLegacyEditorFormatToolbar.m in Sources */, EDFC4D71DB3E62F3885E88AC2EB50B0E /* WPLegacyEditorViewController.m in Sources */, 7333D70FB963FB8B93076EE128004039 /* ZSSBarButtonItem.m in Sources */, From 6ba99430f88f6fd221ed13c36d99f8b483ae344e Mon Sep 17 00:00:00 2001 From: James Frost Date: Tue, 17 May 2016 11:19:51 +0100 Subject: [PATCH 3/5] Keyboard shortcuts now only show if the main editor has focus. --- Classes/WPEditorViewController.m | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/Classes/WPEditorViewController.m b/Classes/WPEditorViewController.m index 3edeb18..157f7f7 100644 --- a/Classes/WPEditorViewController.m +++ b/Classes/WPEditorViewController.m @@ -24,6 +24,7 @@ @interface WPEditorViewController () *)keyCommands { + if (self.isEditingTitle) { + return @[]; + } + return @[ - [UIKeyCommand keyCommandWithInput:@"I" - modifierFlags:UIKeyModifierCommand|UIKeyModifierShift - action:@selector(didTouchMediaOptions) - discoverabilityTitle:NSLocalizedString(@"Insert Image", @"Discoverability title for insert image keyboard shortcut.")], [UIKeyCommand keyCommandWithInput:@"B" modifierFlags:UIKeyModifierCommand action:@selector(setBold) @@ -208,6 +209,10 @@ - (BOOL)canBecomeFirstResponder modifierFlags:UIKeyModifierCommand action:@selector(linkBarButtonTapped) discoverabilityTitle:NSLocalizedString(@"Insert Link", @"Discoverability title for insert link keyboard shortcut.")], + [UIKeyCommand keyCommandWithInput:@"M" + modifierFlags:UIKeyModifierCommand + action:@selector(didTouchMediaOptions) + discoverabilityTitle:NSLocalizedString(@"Insert Media", @"Discoverability title for insert media keyboard shortcut.")], [UIKeyCommand keyCommandWithInput:@"L" modifierFlags:UIKeyModifierCommand action:@selector(setUnorderedList) @@ -953,9 +958,11 @@ - (void)editorView:(WPEditorView*)editorView { [self.toolbarView enableToolbarItems:NO shouldShowSourceButton:YES]; if (field == self.editorView.titleField) { + self.editingTitle = YES; [self.toolbarView enableToolbarItems:NO shouldShowSourceButton:YES]; [self tellOurDelegateFormatBarStatusHasChanged:NO]; } else { + self.editingTitle = NO; [self.toolbarView enableToolbarItems:YES shouldShowSourceButton:YES]; [self tellOurDelegateFormatBarStatusHasChanged:YES]; } @@ -964,8 +971,10 @@ - (void)editorView:(WPEditorView*)editorView - (void)editorView:(WPEditorView*)editorView sourceFieldFocused:(UIView*)view { if (view == self.editorView.sourceViewTitleField) { + self.editingTitle = YES; [self.toolbarView enableToolbarItems:NO shouldShowSourceButton:YES]; } else { + self.editingTitle = NO; [self.toolbarView enableToolbarItems:YES shouldShowSourceButton:YES]; } } From 01eb67a6fcaded98fe4fad19baea13f973c58f93 Mon Sep 17 00:00:00 2001 From: James Frost Date: Fri, 27 May 2016 17:17:04 +0100 Subject: [PATCH 4/5] Revert "Added keyboard shortcut support to the legacy editor." This reverts commit 7b0be2fd4823614f287e2d5de24ba5924d701b43. --- Classes/WPLegacyEditorStyledTextView.h | 25 ------- Classes/WPLegacyEditorStyledTextView.m | 33 --------- Classes/WPLegacyEditorViewController.m | 76 ++------------------- Example/Pods/Pods.xcodeproj/project.pbxproj | 8 --- 4 files changed, 6 insertions(+), 136 deletions(-) delete mode 100644 Classes/WPLegacyEditorStyledTextView.h delete mode 100644 Classes/WPLegacyEditorStyledTextView.m diff --git a/Classes/WPLegacyEditorStyledTextView.h b/Classes/WPLegacyEditorStyledTextView.h deleted file mode 100644 index 8a7622c..0000000 --- a/Classes/WPLegacyEditorStyledTextView.h +++ /dev/null @@ -1,25 +0,0 @@ -#import - -/** - UITextView subclass that allows basic styling of text using the floating format - menu or via keyboard shortcuts (which may be defined in a containing view - controller by implementing `keyCommands`). - - Defers marking up or styling the text to another class through a number of - blocks. These are executed whenever the user uses the format menu or presses - the standard keyboard shortcut associated with a particular formatting action. - - This is necessary to add keyboard shortcut functionality to the legacy editor, - because of an iOS 9 bug where http://www.openradar.me/25463955 shortcuts for - bold, italic, and underline don't work correctly. The workaround is to set - `allowsEditingTextAttributes` to YES on the textview, and implement - `toggleBoldface:`, `toggleItalics:`, and `toggleUnderline:` on the textview to - handle the actions. - */ -@interface WPLegacyEditorStyledTextView : UITextView - -@property (nonatomic, copy) void (^toggleBoldBlock)(); -@property (nonatomic, copy) void (^toggleItalicBlock)(); -@property (nonatomic, copy) void (^toggleUnderlineBlock)(); - -@end diff --git a/Classes/WPLegacyEditorStyledTextView.m b/Classes/WPLegacyEditorStyledTextView.m deleted file mode 100644 index 3aab958..0000000 --- a/Classes/WPLegacyEditorStyledTextView.m +++ /dev/null @@ -1,33 +0,0 @@ -#import "WPLegacyEditorStyledTextView.h" - -@implementation WPLegacyEditorStyledTextView - -- (instancetype)initWithFrame:(CGRect)frame -{ - if (self = [super initWithFrame:frame]) { - self.allowsEditingTextAttributes = YES; - } - - return self; -} - -- (void)toggleBoldface:(id)sender -{ - if (self.toggleBoldBlock) { - self.toggleBoldBlock(); - } -} -- (void)toggleItalics:(id)sender -{ - if (self.toggleItalicBlock) { - self.toggleItalicBlock(); - } -} -- (void)toggleUnderline:(id)sender -{ - if (self.toggleUnderlineBlock) { - self.toggleUnderlineBlock(); - } -} - -@end diff --git a/Classes/WPLegacyEditorViewController.m b/Classes/WPLegacyEditorViewController.m index bf4f627..ddfc340 100644 --- a/Classes/WPLegacyEditorViewController.m +++ b/Classes/WPLegacyEditorViewController.m @@ -1,13 +1,11 @@ #import "WPLegacyEditorViewController.h" #import "WPLegacyEditorFormatToolbar.h" #import "WPLegacyEditorFormatAction.h" -#import "WPLegacyEditorStyledTextView.h" #import CGFloat const WPLegacyEPVCStandardOffset = 15.0; CGFloat const WPLegacyEPVCTextViewOffset = 10.0; - @interface WPLegacyEditorViewController () @property (nonatomic) CGPoint scrollOffsetRestorePoint; @@ -156,22 +154,13 @@ - (void)setupTextView // Height should never be smaller than what is required to display its text. if (!self.textView) { - WPLegacyEditorStyledTextView *textView = [[WPLegacyEditorStyledTextView alloc] initWithFrame:frame]; - textView.autoresizingMask = mask; - textView.delegate = self; - textView.font = self.bodyFont; - textView.textColor = self.bodyColor; - textView.allowsEditingTextAttributes = YES; - textView.accessibilityLabel = NSLocalizedString(@"Content", @"Post content"); - - __weak typeof(self) weakSelf = self; - textView.toggleBoldBlock = ^{ [weakSelf setBold]; }; - textView.toggleItalicBlock = ^{ [weakSelf setItalic]; }; - textView.toggleUnderlineBlock = ^{ [weakSelf setUnderline]; }; - - self.textView = textView; + self.textView = [[UITextView alloc] initWithFrame:frame]; + self.textView.autoresizingMask = mask; + self.textView.delegate = self; + self.textView.font = self.bodyFont; + self.textView.textColor = self.bodyColor; + self.textView.accessibilityLabel = NSLocalizedString(@"Content", @"Post content"); } - [self.view addSubview:self.textView]; // Formatting bar for the textView's inputAccessoryView. @@ -280,59 +269,6 @@ - (void)didTouchMediaOptions } } -#pragma mark - Keyboard Shortcuts - -- (NSArray *)keyCommands -{ - if (![self.textView isFirstResponder]) { - return @[]; - } - - return @[ - [UIKeyCommand keyCommandWithInput:@"B" - modifierFlags:UIKeyModifierCommand - action:@selector(setBold) - discoverabilityTitle:NSLocalizedString(@"Bold", @"Discoverability title for bold formatting keyboard shortcut.")], - [UIKeyCommand keyCommandWithInput:@"I" - modifierFlags:UIKeyModifierCommand - action:@selector(setItalic) - discoverabilityTitle:NSLocalizedString(@"Italic", @"Discoverability title for italic formatting keyboard shortcut.")], - [UIKeyCommand keyCommandWithInput:@"U" - modifierFlags:UIKeyModifierCommand - action:@selector(setUnderline) - discoverabilityTitle:NSLocalizedString(@"Underline", @"Discoverability title for underline formatting keyboard shortcut.")], - [UIKeyCommand keyCommandWithInput:@"-" - modifierFlags:UIKeyModifierCommand|UIKeyModifierShift - action:@selector(setStrikethrough) - discoverabilityTitle:NSLocalizedString(@"Strikethrough", @"Discoverability title for strikethrough formatting keyboard shortcut.")], - [UIKeyCommand keyCommandWithInput:@"B" - modifierFlags:UIKeyModifierCommand|UIKeyModifierShift - action:@selector(setBlockQuote) - discoverabilityTitle:NSLocalizedString(@"Block Quote", @"Discoverability title for block quote keyboard shortcut.")], - [UIKeyCommand keyCommandWithInput:@"K" - modifierFlags:UIKeyModifierCommand - action:@selector(insertLink) - discoverabilityTitle:NSLocalizedString(@"Insert Link", @"Discoverability title for insert link keyboard shortcut.")], - [UIKeyCommand keyCommandWithInput:@"M" - modifierFlags:UIKeyModifierCommand - action:@selector(insertMedia) - discoverabilityTitle:NSLocalizedString(@"Insert Media", @"Discoverability title for insert media keyboard shortcut.")], - [UIKeyCommand keyCommandWithInput:@"M" - modifierFlags:UIKeyModifierCommand|UIKeyModifierShift - action:@selector(insertMore) - discoverabilityTitle:NSLocalizedString(@"Insert More Tag ", @"Discoverability title for insert more tag keyboard shortcut.")] - ]; -} - -- (void)setBold { [self formatToolbar:self.editorToolbar actionPressed:WPLegacyEditorFormatActionBold]; } -- (void)setItalic { [self formatToolbar:self.editorToolbar actionPressed:WPLegacyEditorFormatActionItalic]; } -- (void)setUnderline { [self formatToolbar:self.editorToolbar actionPressed:WPLegacyEditorFormatActionUnderline]; } -- (void)setStrikethrough { [self formatToolbar:self.editorToolbar actionPressed:WPLegacyEditorFormatActionDelete]; } -- (void)insertMedia { [self formatToolbar:self.editorToolbar actionPressed:WPLegacyEditorFormatActionMedia]; } -- (void)insertLink { [self formatToolbar:self.editorToolbar actionPressed:WPLegacyEditorFormatActionLink]; } -- (void)setBlockQuote { [self formatToolbar:self.editorToolbar actionPressed:WPLegacyEditorFormatActionQuote]; } -- (void)insertMore { [self formatToolbar:self.editorToolbar actionPressed:WPLegacyEditorFormatActionMore]; } - #pragma mark - Editor and Misc Methods - (void)startEditing diff --git a/Example/Pods/Pods.xcodeproj/project.pbxproj b/Example/Pods/Pods.xcodeproj/project.pbxproj index 69e8ddd..efb4e73 100644 --- a/Example/Pods/Pods.xcodeproj/project.pbxproj +++ b/Example/Pods/Pods.xcodeproj/project.pbxproj @@ -24,8 +24,6 @@ 166EA9FA08D588A3C37BAA233CC71A1F /* CYRToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 30953A5CC1F7C15B2B2569E2B86234B7 /* CYRToken.m */; }; 16AA82DC3E4AC2696DA0931F390E5FC7 /* ZSSh5.png in Resources */ = {isa = PBXBuildFile; fileRef = DD385AEE15545E35E75E9C0D559B2764 /* ZSSh5.png */; }; 170E608BCFB5A7701BBEEA00DEF6889D /* HRCgUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 3D266ADA1ED925AEE6DFF2EEE04B7A88 /* HRCgUtil.m */; }; - 173BCE6F1CEB205000AE8817 /* WPLegacyEditorStyledTextView.h in Headers */ = {isa = PBXBuildFile; fileRef = 173BCE6D1CEB205000AE8817 /* WPLegacyEditorStyledTextView.h */; }; - 173BCE701CEB205000AE8817 /* WPLegacyEditorStyledTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 173BCE6E1CEB205000AE8817 /* WPLegacyEditorStyledTextView.m */; }; 17ED9445B95C990DC7F77217C2A372C0 /* Merriweather-Italic.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 8629C93CB036BC2B431FEAF8EC7A5E88 /* Merriweather-Italic.ttf */; }; 17F91B9CE2CEBFE09A4A7D9470CE0765 /* icon_format_html@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = A80A6F496A0753421F82AD38EAFA3CDC /* icon_format_html@2x.png */; }; 183C87703915312EE7B716FA107B2683 /* DDTTYLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 8A49E19FFA5287CF0054F9FF3F093557 /* DDTTYLogger.m */; settings = {COMPILER_FLAGS = "-DOS_OBJECT_USE_OBJC=0 -w -Xanalyzer -analyzer-disable-all-checks"; }; }; @@ -374,8 +372,6 @@ 1424C9017E4F9B1766D1E50E4BB296F4 /* NSObject-SafeExpectations-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "NSObject-SafeExpectations-umbrella.h"; sourceTree = ""; }; 169C2E37D8CA323642A8E9D4211FAFE3 /* WPEditorField.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = WPEditorField.m; sourceTree = ""; }; 16FE5F287F1CF6A31EDD264A3EA7F9A3 /* WPStyleGuide.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = WPStyleGuide.m; path = "WordPress-iOS-Shared/Core/WPStyleGuide.m"; sourceTree = ""; }; - 173BCE6D1CEB205000AE8817 /* WPLegacyEditorStyledTextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WPLegacyEditorStyledTextView.h; sourceTree = ""; }; - 173BCE6E1CEB205000AE8817 /* WPLegacyEditorStyledTextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WPLegacyEditorStyledTextView.m; sourceTree = ""; }; 1866E384D9C1BE78E2048F59DADD3BBC /* WPNUXUtility.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = WPNUXUtility.m; path = "WordPress-iOS-Shared/Core/WPNUXUtility.m"; sourceTree = ""; }; 18A435085C70CE4B4601475CB8EFC8CC /* icon_format_keyboard.png */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = image.png; path = icon_format_keyboard.png; sourceTree = ""; }; 1923CE5DAF984F860E3559547A252308 /* rangy-highlighter.js */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.javascript; path = "rangy-highlighter.js"; sourceTree = ""; }; @@ -1131,8 +1127,6 @@ 2CE62E271066C69FD730291EA4E5AF73 /* WPLegacyEditorFormatToolbar.m */, DE33BBE2AB47600A211CB2D833904605 /* WPLegacyEditorViewController.h */, B174D434444FFD56027D2FBA78A4820C /* WPLegacyEditorViewController.m */, - 173BCE6D1CEB205000AE8817 /* WPLegacyEditorStyledTextView.h */, - 173BCE6E1CEB205000AE8817 /* WPLegacyEditorStyledTextView.m */, A347E40B351E562043797CF5C4F29CAB /* ZSSBarButtonItem.h */, 30864D2D85CCD7AECE8C682FB118243C /* ZSSBarButtonItem.m */, 8AE3843844D187A314FC9BC3917FC457 /* ZSSTextView.h */, @@ -1236,7 +1230,6 @@ 5A7C1352685E2C5DC5305CD490DCFD22 /* UIWebView+GUIFixes.h in Headers */, 7CA0D9CF43973132AF4B5B33764D2184 /* WordPress-iOS-Editor-umbrella.h in Headers */, 9E1A2CA25668BA959253C4D0B3A70BE6 /* WPEditorField.h in Headers */, - 173BCE6F1CEB205000AE8817 /* WPLegacyEditorStyledTextView.h in Headers */, DD9308ADBDA819DB2D4DC6472C125AA9 /* WPEditorFormatbarView.h in Headers */, 8ECC1D04A94121E9E4C80530D5CA39F1 /* WPEditorLoggingConfiguration.h in Headers */, 3D381BDB5478D52BD5046D52E8F181A6 /* WPEditorToolbarButton.h in Headers */, @@ -1727,7 +1720,6 @@ 60FA1EB2D6C6B16B8ACCD2D8B8EB5BB6 /* WPEditorViewController.m in Sources */, 3D1D840F42D18C7D9005788C56F98320 /* WPImageMeta.m in Sources */, BA78A51E19BEC0FD3C88C6224D8FA256 /* WPLegacyEditorFormatAction.m in Sources */, - 173BCE701CEB205000AE8817 /* WPLegacyEditorStyledTextView.m in Sources */, 37CB8DE501F08F4758090D9AF27708E7 /* WPLegacyEditorFormatToolbar.m in Sources */, EDFC4D71DB3E62F3885E88AC2EB50B0E /* WPLegacyEditorViewController.m in Sources */, 7333D70FB963FB8B93076EE128004039 /* ZSSBarButtonItem.m in Sources */, From 30aef16cf4482408936ffbcfb328d95ca13b617b Mon Sep 17 00:00:00 2001 From: James Frost Date: Tue, 31 May 2016 17:22:32 +0200 Subject: [PATCH 5/5] Added underline key command, and ensured that shortcuts match Calypso. --- Classes/WPEditorFormatbarView.h | 7 ++++++ Classes/WPEditorFormatbarView.m | 15 ++++++++++++ Classes/WPEditorViewController.m | 40 +++++++++++++++++++++----------- 3 files changed, 49 insertions(+), 13 deletions(-) diff --git a/Classes/WPEditorFormatbarView.h b/Classes/WPEditorFormatbarView.h index 8b08abc..2a2441e 100644 --- a/Classes/WPEditorFormatbarView.h +++ b/Classes/WPEditorFormatbarView.h @@ -155,6 +155,13 @@ typedef enum */ - (void)toolBarItemWithTag:(WPEditorViewControllerElementTag)tag setSelected:(BOOL)selected; +/** + * @brief Toggles the on / off selection state for a toolbar item + * + * @param tag WPEditorViewControllerElementTag of the item to alter. + */ +- (void)toggleSelectionForToolBarItemWithTag:(WPEditorViewControllerElementTag)tag; + /** * @brief Enables and disables the toolbar items. * diff --git a/Classes/WPEditorFormatbarView.m b/Classes/WPEditorFormatbarView.m index b9f7f1f..f549aae 100644 --- a/Classes/WPEditorFormatbarView.m +++ b/Classes/WPEditorFormatbarView.m @@ -218,6 +218,21 @@ - (void)toolBarItemWithTag:(WPEditorViewControllerElementTag)tag setSelected:(BO } } +- (void)toggleSelectionForToolBarItemWithTag:(WPEditorViewControllerElementTag)tag +{ + for (ZSSBarButtonItem *item in self.leftToolbar.items) { + if (item.tag == tag) { + item.selected = !item.selected; + } + } + + for (ZSSBarButtonItem *item in self.regularToolbar.items) { + if (item.tag == tag) { + item.selected = !item.selected; + } + } +} + - (void)enableToolbarItems:(BOOL)enable shouldShowSourceButton:(BOOL)showSource { diff --git a/Classes/WPEditorViewController.m b/Classes/WPEditorViewController.m index 157f7f7..dbee89a 100644 --- a/Classes/WPEditorViewController.m +++ b/Classes/WPEditorViewController.m @@ -187,7 +187,9 @@ - (BOOL)canBecomeFirstResponder if (self.isEditingTitle) { return @[]; } - + + // Note that due to an iOS 9 bug, the custom methods for bold and italic + // don't actually get called: http://www.openradar.me/25463955 return @[ [UIKeyCommand keyCommandWithInput:@"B" modifierFlags:UIKeyModifierCommand @@ -197,12 +199,16 @@ - (BOOL)canBecomeFirstResponder modifierFlags:UIKeyModifierCommand action:@selector(setItalic) discoverabilityTitle:NSLocalizedString(@"Italic", @"Discoverability title for italic formatting keyboard shortcut.")], - [UIKeyCommand keyCommandWithInput:@"-" - modifierFlags:UIKeyModifierCommand|UIKeyModifierShift - action:@selector(setStrikethrough) + [UIKeyCommand keyCommandWithInput:@"D" + modifierFlags:UIKeyModifierCommand|UIKeyModifierAlternate + action:@selector(handleKeyCommandStrikethrough) discoverabilityTitle:NSLocalizedString(@"Strikethrough", @"Discoverability title for strikethrough formatting keyboard shortcut.")], - [UIKeyCommand keyCommandWithInput:@"B" - modifierFlags:UIKeyModifierCommand|UIKeyModifierShift + [UIKeyCommand keyCommandWithInput:@"U" + modifierFlags:UIKeyModifierCommand + action:@selector(setUnderline) + discoverabilityTitle:NSLocalizedString(@"Underline", @"Discoverability title for underline formatting keyboard shortcut.")], + [UIKeyCommand keyCommandWithInput:@"Q" + modifierFlags:UIKeyModifierCommand|UIKeyModifierAlternate action:@selector(setBlockQuote) discoverabilityTitle:NSLocalizedString(@"Block Quote", @"Discoverability title for block quote keyboard shortcut.")], [UIKeyCommand keyCommandWithInput:@"K" @@ -210,17 +216,17 @@ - (BOOL)canBecomeFirstResponder action:@selector(linkBarButtonTapped) discoverabilityTitle:NSLocalizedString(@"Insert Link", @"Discoverability title for insert link keyboard shortcut.")], [UIKeyCommand keyCommandWithInput:@"M" - modifierFlags:UIKeyModifierCommand + modifierFlags:UIKeyModifierCommand|UIKeyModifierAlternate action:@selector(didTouchMediaOptions) discoverabilityTitle:NSLocalizedString(@"Insert Media", @"Discoverability title for insert media keyboard shortcut.")], - [UIKeyCommand keyCommandWithInput:@"L" - modifierFlags:UIKeyModifierCommand + [UIKeyCommand keyCommandWithInput:@"U" + modifierFlags:UIKeyModifierCommand|UIKeyModifierAlternate action:@selector(setUnorderedList) - discoverabilityTitle:NSLocalizedString(@"Unordered List", @"Discoverability title for unordered list keyboard shortcut.")], - [UIKeyCommand keyCommandWithInput:@"L" - modifierFlags:UIKeyModifierCommand|UIKeyModifierShift + discoverabilityTitle:NSLocalizedString(@"Bullet List", @"Discoverability title for bullet list keyboard shortcut.")], + [UIKeyCommand keyCommandWithInput:@"O" + modifierFlags:UIKeyModifierCommand|UIKeyModifierAlternate action:@selector(setOrderedList) - discoverabilityTitle:NSLocalizedString(@"Ordered List", @"Discoverability title for ordered list keyboard shortcut.")], + discoverabilityTitle:NSLocalizedString(@"Numbered List", @"Discoverability title for numbered list keyboard shortcut.")], [UIKeyCommand keyCommandWithInput:@"H" modifierFlags:UIKeyModifierCommand|UIKeyModifierShift action:@selector(showHTMLSource:) @@ -228,6 +234,14 @@ - (BOOL)canBecomeFirstResponder ]; } +- (void)handleKeyCommandStrikethrough +{ + [self setStrikethrough]; + + // Ensure that the toolbar button is appropriately selected / deselected + [self.toolbarView toggleSelectionForToolBarItemWithTag:kWPEditorViewControllerElementStrikeThroughBarButton]; +} + #pragma mark - Toolbar: helper methods - (void)clearToolbar