@@ -223,6 +223,12 @@ open class TextView: UITextView {
223223 // MARK: - Properties: Text Lists
224224
225225 var maximumListIndentationLevels = 7
226+
227+ // MARK: - Properties: Blockquotes
228+
229+ /// The max levels of quote indentation allowed
230+ /// Default is 9
231+ public var maximumBlockquoteIndentationLevels = 9
226232
227233 // MARK: - Properties: UI Defaults
228234
@@ -295,17 +301,18 @@ open class TextView: UITextView {
295301
296302 // MARK: - Apparance Properties
297303
298- /// Blockquote Blocks Border Color.
304+
305+ /// Blockquote Blocks Border and Text Colors
299306 ///
300- @objc dynamic public var blockquoteBorderColor : UIColor ? {
307+ @objc dynamic public var blockquoteBorderColors : [ UIColor ] {
301308 get {
302- return layout. blockquoteBorderColor
309+ return layout. blockquoteBorderColors
303310 }
304311 set {
305- layout. blockquoteBorderColor = newValue
312+ layout. blockquoteBorderColors = newValue
306313 }
307314 }
308-
315+
309316 /// Blockquote Blocks Background Color.
310317 ///
311318 @objc dynamic public var blockquoteBackgroundColor : UIColor ? {
@@ -547,41 +554,110 @@ open class TextView: UITextView {
547554 }
548555
549556 @objc func handleShiftTab( command: UIKeyCommand ) {
550- guard let list = TextListFormatter . lists ( in: typingAttributes) . last else {
557+
558+ let lists = TextListFormatter . lists ( in: typingAttributes)
559+ let quotes = BlockquoteFormatter . blockquotes ( in: typingAttributes)
560+
561+ if let list = lists. last {
562+ indent ( list: list, increase: false )
563+
564+ } else if let quote = quotes. last {
565+ indent ( blockquote: quote, increase: false )
566+
567+ } else {
551568 return
552569 }
570+ }
571+
572+ @objc func handleTab( command: UIKeyCommand ) {
573+
574+ let lists = TextListFormatter . lists ( in: typingAttributes)
575+ let quotes = BlockquoteFormatter . blockquotes ( in: typingAttributes)
576+
577+ if let list = lists. last, lists. count < maximumListIndentationLevels {
578+ indent ( list: list)
579+
580+ } else if let quote = quotes. last, quotes. count < maximumBlockquoteIndentationLevels {
581+ indent ( blockquote: quote)
582+
583+ } else {
584+ insertText ( String ( . tab) )
585+ }
586+
587+ }
588+
589+
590+ // MARK: - Text List indent methods
591+
592+ private func indent( list: TextList , increase: Bool = true ) {
553593
554594 let formatter = TextListFormatter ( style: list. style, placeholderAttributes: nil , increaseDepth: true )
555- let liFormatter = LiFormatter ( placeholderAttributes: nil )
595+ let li = LiFormatter ( placeholderAttributes: nil )
596+
556597 let targetRange = formatter. applicationRange ( for: selectedRange, in: storage)
557598
558599 performUndoable ( at: targetRange) {
559- let finalRange = formatter. removeAttributes ( from: storage, at: targetRange)
560- liFormatter. removeAttributes ( from: storage, at: targetRange)
600+ let finalRange : NSRange
601+ if increase {
602+ finalRange = increaseIndent ( listFormatter: formatter, liFormatter: li, targetRange: targetRange)
603+ } else {
604+ finalRange = decreaseIndent ( listFormatter: formatter, liFormatter: li, targetRange: targetRange)
605+ }
561606 typingAttributes = textStorage. attributes ( at: targetRange. location, effectiveRange: nil )
562607 return finalRange
563608 }
564- }
565-
566- @objc func handleTab( command: UIKeyCommand ) {
567- let lists = TextListFormatter . lists ( in: typingAttributes)
568- guard let list = lists. last, lists. count < maximumListIndentationLevels else {
569- insertText ( String ( . tab) )
570- return
571- }
572609
573- let formatter = TextListFormatter ( style: list. style, placeholderAttributes: nil , increaseDepth: true )
574- let liFormatter = LiFormatter ( placeholderAttributes: nil )
610+ }
611+
612+ // MARK: Text List increase or decrease indentation
613+ private func increaseIndent( listFormatter: TextListFormatter , liFormatter: LiFormatter , targetRange: NSRange ) -> NSRange {
614+ let finalRange = listFormatter. applyAttributes ( to: storage, at: targetRange)
615+ liFormatter. applyAttributes ( to: storage, at: targetRange)
616+
617+ return finalRange
618+ }
619+
620+ private func decreaseIndent( listFormatter: TextListFormatter , liFormatter: LiFormatter , targetRange: NSRange ) -> NSRange {
621+ let finalRange = listFormatter. removeAttributes ( from: storage, at: targetRange)
622+ liFormatter. removeAttributes ( from: storage, at: targetRange)
623+
624+ return finalRange
625+ }
626+
627+
628+ // MARK: - Blockquote indent methods
629+
630+ private func indent( blockquote: Blockquote , increase: Bool = true ) {
631+
632+
633+
634+ let formatter = BlockquoteFormatter ( placeholderAttributes: typingAttributes, increaseDepth: true )
575635 let targetRange = formatter. applicationRange ( for: selectedRange, in: storage)
576636
577- performUndoable ( at: targetRange) {
578- let finalRange = formatter. applyAttributes ( to: storage, at: targetRange)
579- liFormatter. applyAttributes ( to: storage, at: targetRange)
637+ performUndoable ( at: targetRange) {
638+ let finalRange : NSRange
639+ if increase {
640+ finalRange = increaseIndent ( quoteFormatter: formatter, targetRange: targetRange)
641+ } else {
642+ finalRange = decreaseIndent ( quoteFormatter: formatter, targetRange: targetRange)
643+ }
580644 typingAttributes = textStorage. attributes ( at: targetRange. location, effectiveRange: nil )
581645 return finalRange
582646 }
647+
583648 }
584649
650+ // MARK: Blockquote increase or decrease indentation
651+ private func increaseIndent( quoteFormatter: BlockquoteFormatter , targetRange: NSRange ) -> NSRange {
652+ let finalRange = quoteFormatter. applyAttributes ( to: storage, at: targetRange)
653+ return finalRange
654+ }
655+
656+ private func decreaseIndent( quoteFormatter: BlockquoteFormatter , targetRange: NSRange ) -> NSRange {
657+ let finalRange = quoteFormatter. removeAttributes ( from: storage, at: targetRange)
658+ return finalRange
659+ }
660+
585661
586662 // MARK: - Pasteboard Helpers
587663
@@ -1004,6 +1080,7 @@ open class TextView: UITextView {
10041080 ensureInsertionOfEndOfLineForEmptyParagraphAtEndOfFile ( forApplicationRange: range)
10051081
10061082 let formatter = BlockquoteFormatter ( placeholderAttributes: typingAttributes)
1083+
10071084 toggle ( formatter: formatter, atRange: range)
10081085
10091086 let citeFormatter = CiteFormatter ( )
0 commit comments