Skip to content

Commit cc01cfc

Browse files
Merge pull request #395 from woocommerce/issue/19-block-formatter
StringDescriptor Formatter
2 parents 08281d0 + e6943d2 commit cc01cfc

File tree

14 files changed

+780
-33
lines changed

14 files changed

+780
-33
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import Foundation
2+
3+
4+
/// NSMutableAttributedString: Helper Methods
5+
///
6+
extension NSMutableAttributedString {
7+
8+
/// Applies the specified attributes to the receiver's quoted text.
9+
///
10+
func applyAttributesToQuotedText( attributes: [NSAttributedString.Key: Any]) {
11+
let scanner = Scanner(string: string)
12+
for range in scanner.scanQuotedRanges() {
13+
addAttributes(attributes, range: range)
14+
}
15+
}
16+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import Foundation
2+
import UIKit
3+
4+
5+
/// NSMutableParagraphStyle: Helper Methods
6+
///
7+
extension NSMutableParagraphStyle {
8+
9+
/// No Maximum Line Height constant
10+
///
11+
static let NoMaximum = CGFloat(0)
12+
13+
/// Convenience Initializer
14+
///
15+
convenience init(minLineHeight: CGFloat,
16+
maxLineHeight: CGFloat = NoMaximum,
17+
lineBreakMode: NSLineBreakMode = .byWordWrapping,
18+
alignment: NSTextAlignment = .natural) {
19+
20+
self.init()
21+
self.minimumLineHeight = minLineHeight
22+
self.maximumLineHeight = maxLineHeight
23+
self.lineBreakMode = lineBreakMode
24+
self.alignment = alignment
25+
}
26+
27+
/// Convenience Initializer: Returns a Paragraph Style with a standard "minimum line height" set to accommodate a
28+
/// given UIFont instance.
29+
///
30+
convenience init(standardLineHeightUsingFont font: UIFont, alignment: NSTextAlignment = .natural) {
31+
self.init(minLineHeight: font.lineHeight.rounded(.up), alignment: alignment)
32+
}
33+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import Foundation
2+
import UIKit
3+
4+
5+
/// NSParagraphStyle: Helper Methods
6+
///
7+
extension NSParagraphStyle {
8+
9+
/// Returns a ParagraphStyle with it's minimum Line Height set to accomodate `UIFont.subheadline`
10+
///
11+
static var subheadline: NSParagraphStyle {
12+
return NSMutableParagraphStyle(standardLineHeightUsingFont: UIFont.subheadline)
13+
}
14+
15+
/// Returns a ParagraphStyle with it's minimum Line Height set to accomodate `UIFont.body`
16+
///
17+
static var body: NSParagraphStyle {
18+
return NSMutableParagraphStyle(standardLineHeightUsingFont: UIFont.body)
19+
}
20+
21+
/// Returns a ParagraphStyle with it's minimum Line Height set to accomodate `UIFont.body` / Centered
22+
///
23+
static var badge: NSParagraphStyle {
24+
return NSMutableParagraphStyle(standardLineHeightUsingFont: UIFont.body, alignment: .center)
25+
}
26+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import Foundation
2+
3+
4+
/// Scanner: Helper Methods
5+
///
6+
extension Scanner {
7+
8+
/// Returns the NSRange(s) for all of the quotes contained within the scanned string.
9+
///
10+
func scanQuotedRanges() -> [NSRange] {
11+
var output = [NSRange]()
12+
let marker = "\""
13+
14+
while isAtEnd == false {
15+
// Find + Drop the first quotation mark
16+
scanUpTo(marker, into: nil)
17+
scanString(marker, into: nil)
18+
19+
// Scan the actual quoted text
20+
let start = scanLocation
21+
scanUpTo(marker, into: nil)
22+
let end = scanLocation
23+
24+
// Drop the closing mark
25+
scanString(marker, into: nil)
26+
27+
// Build the Range
28+
guard start >= 0 && end < string.count && start < end else {
29+
continue
30+
}
31+
32+
let foundationRange = NSRange(location: start, length: end - start)
33+
output.append(foundationRange)
34+
}
35+
36+
return output
37+
}
38+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import Foundation
2+
3+
4+
/// String: Constant Helpers
5+
///
6+
extension String {
7+
8+
/// Returns a string containing the Hair Space.
9+
///
10+
static var hairSpace: String {
11+
return "\u{200A}"
12+
}
13+
14+
/// Returns a string containing a Space.
15+
///
16+
static var space: String {
17+
return " "
18+
}
19+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import Foundation
2+
import UIKit
3+
4+
5+
/// WooCommerce UIFont Helpers
6+
///
7+
extension UIFont {
8+
9+
/// Returns the receiver *Bold* version.
10+
///
11+
var bold: UIFont {
12+
guard let descriptor = fontDescriptor.withSymbolicTraits(.traitBold) else {
13+
DDLogError("# Error: Cannot toggle font to Bold: [\(self)]")
14+
return self
15+
}
16+
17+
return UIFont(descriptor: descriptor, size: pointSize)
18+
}
19+
20+
/// Returns the receiver *Italics* version.
21+
///
22+
var italics: UIFont {
23+
guard let descriptor = fontDescriptor.withSymbolicTraits(.traitItalic) else {
24+
DDLogError("# Error: Cannot toggle font to Italics: [\(self)]")
25+
return self
26+
}
27+
28+
return UIFont(descriptor: descriptor, size: pointSize)
29+
}
30+
}

WooCommerce/Classes/Styles/Style.swift

Lines changed: 58 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,16 @@ import UIKit
44
// MARK: - Style defines the basic API of a Woo Skin.
55
//
66
protocol Style {
7+
8+
/// Fonts
9+
///
710
var actionButtonTitleFont: UIFont { get }
811
var alternativeLoginsTitleFont: UIFont { get }
12+
var chartLabelFont: UIFont { get }
13+
var subheadlineFont: UIFont { get }
14+
15+
/// Colors
16+
///
917
var buttonPrimaryColor: UIColor { get }
1018
var buttonPrimaryHighlightedColor: UIColor { get }
1119
var buttonPrimaryTitleColor: UIColor { get }
@@ -16,14 +24,10 @@ protocol Style {
1624
var buttonDisabledHighlightedColor: UIColor { get }
1725
var buttonDisabledTitleColor: UIColor { get }
1826
var cellSeparatorColor: UIColor { get }
19-
var chartLabelFont: UIFont { get }
2027
var defaultTextColor: UIColor { get }
2128
var destructiveActionColor: UIColor { get }
22-
var navBarImage: UIImage { get }
2329
var sectionBackgroundColor: UIColor { get }
2430
var sectionTitleColor: UIColor { get }
25-
var statusBarDark: UIStatusBarStyle { get }
26-
var statusBarLight: UIStatusBarStyle { get }
2731
var statusDangerColor: UIColor { get }
2832
var statusDangerBoldColor: UIColor { get }
2933
var statusNotIdentifiedColor: UIColor { get }
@@ -32,7 +36,6 @@ protocol Style {
3236
var statusPrimaryBoldColor: UIColor { get }
3337
var statusSuccessColor: UIColor { get }
3438
var statusSuccessBoldColor: UIColor { get }
35-
var subheadlineFont: UIFont { get }
3639
var tableViewBackgroundColor: UIColor { get }
3740
var wooCommerceBrandColor: UIColor { get }
3841
var wooAccent: UIColor { get }
@@ -42,22 +45,31 @@ protocol Style {
4245
var wooGreyBorder: UIColor { get }
4346
var wooSecondary: UIColor { get }
4447
var wooWhite: UIColor { get }
48+
49+
/// NavBar
50+
///
51+
var navBarImage: UIImage { get }
52+
53+
/// StatusBar
54+
///
55+
var statusBarDark: UIStatusBarStyle { get }
56+
var statusBarLight: UIStatusBarStyle { get }
4557
}
4658

4759

4860
// MARK: - WooCommerce's Default Style
4961
//
5062
class DefaultStyle: Style {
5163

52-
// Fonts!
53-
//
64+
/// Fonts!
65+
///
5466
let actionButtonTitleFont = UIFont.font(forStyle: .headline, weight: .semibold)
5567
let alternativeLoginsTitleFont = UIFont.font(forStyle: .subheadline, weight: .semibold)
5668
let subheadlineFont = UIFont.font(forStyle: .subheadline, weight: .regular)
5769
let chartLabelFont = UIFont.font(forStyle: .caption2, weight: .ultraLight)
5870

59-
// Colors!
60-
//
71+
/// Colors!
72+
///
6173
let buttonPrimaryColor = UIColor(red: 0x96/255.0, green: 0x58/255.0, blue: 0x8A/255.0, alpha: 0xFF/255.0)
6274
let buttonPrimaryHighlightedColor = UIColor(red: 0x6E/255.0, green: 0x29/255.0, blue: 0x67/255.0, alpha: 0xFF/255.0)
6375
let buttonPrimaryTitleColor = HandbookColors.wooWhite
@@ -70,14 +82,10 @@ class DefaultStyle: Style {
7082
let cellSeparatorColor = HandbookColors.wooGreyBorder
7183
let defaultTextColor = HandbookColors.wooSecondary
7284
let destructiveActionColor = UIColor(red: 197.0/255.0, green: 60.0/255.0, blue: 53.0/255.0, alpha: 1.0)
73-
let navBarImage = UIImage(named: "woo-logo")!
7485
let sectionBackgroundColor = HandbookColors.wooGreyLight
7586
let sectionTitleColor = HandbookColors.wooSecondary
7687
let tableViewBackgroundColor = HandbookColors.wooGreyLight
7788

78-
let statusBarDark = UIStatusBarStyle.default
79-
let statusBarLight = UIStatusBarStyle.lightContent
80-
8189
let statusDangerColor = HandbookColors.statusRedDimmed
8290
let statusDangerBoldColor = HandbookColors.statusRed
8391
let statusNotIdentifiedColor = HandbookColors.wooGreyLight
@@ -95,6 +103,15 @@ class DefaultStyle: Style {
95103
let wooGreyMid = HandbookColors.wooGreyMid
96104
let wooGreyTextMin = HandbookColors.wooGreyTextMin
97105
let wooWhite = HandbookColors.wooWhite
106+
107+
/// NavBar
108+
///
109+
let navBarImage = UIImage(named: "woo-logo")!
110+
111+
/// StatusBar
112+
///
113+
let statusBarDark = UIStatusBarStyle.default
114+
let statusBarLight = UIStatusBarStyle.lightContent
98115
}
99116

100117

@@ -141,6 +158,8 @@ class StyleManager {
141158
}
142159
}
143160

161+
// MARK: - Fonts
162+
144163
static var actionButtonTitleFont: UIFont {
145164
return active.actionButtonTitleFont
146165
}
@@ -149,6 +168,16 @@ class StyleManager {
149168
return active.alternativeLoginsTitleFont
150169
}
151170

171+
static var chartLabelFont: UIFont {
172+
return active.chartLabelFont
173+
}
174+
175+
static var subheadlineFont: UIFont {
176+
return active.subheadlineFont
177+
}
178+
179+
// MARK: - Colors
180+
152181
static var buttonPrimaryColor: UIColor {
153182
return active.buttonPrimaryColor
154183
}
@@ -189,10 +218,6 @@ class StyleManager {
189218
return active.cellSeparatorColor
190219
}
191220

192-
static var chartLabelFont: UIFont {
193-
return active.chartLabelFont
194-
}
195-
196221
static var defaultTextColor: UIColor {
197222
return active.defaultTextColor
198223
}
@@ -201,18 +226,6 @@ class StyleManager {
201226
return active.destructiveActionColor
202227
}
203228

204-
static var navBarImage: UIImage {
205-
return active.navBarImage
206-
}
207-
208-
static var statusBarDark: UIStatusBarStyle {
209-
return active.statusBarDark
210-
}
211-
212-
static var statusBarLight: UIStatusBarStyle {
213-
return active.statusBarLight
214-
}
215-
216229
static var sectionBackgroundColor: UIColor {
217230
return active.sectionBackgroundColor
218231
}
@@ -253,10 +266,6 @@ class StyleManager {
253266
return active.statusSuccessBoldColor
254267
}
255268

256-
static var subheadlineFont: UIFont {
257-
return active.subheadlineFont
258-
}
259-
260269
static var tableViewBackgroundColor: UIColor {
261270
return active.tableViewBackgroundColor
262271
}
@@ -292,4 +301,20 @@ class StyleManager {
292301
static var wooWhite: UIColor {
293302
return active.wooWhite
294303
}
304+
305+
// MARK: - NavBar
306+
307+
static var navBarImage: UIImage {
308+
return active.navBarImage
309+
}
310+
311+
// MARK: - StatusBar
312+
313+
static var statusBarDark: UIStatusBarStyle {
314+
return active.statusBarDark
315+
}
316+
317+
static var statusBarLight: UIStatusBarStyle {
318+
return active.statusBarLight
319+
}
295320
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import Foundation
2+
3+
4+
/// Describes the kind of data contained within a specific Text Range.
5+
///
6+
protocol StringDescriptor {
7+
8+
/// Text Range associated.
9+
///
10+
var range: NSRange { get }
11+
12+
/// Associated URL.
13+
///
14+
var url: URL? { get }
15+
16+
/// String Payload associated to the range.
17+
///
18+
var value: String? { get }
19+
20+
/// Returns the `Text Style` that should be applied over the associated range.
21+
///
22+
func attributes(from styles: StringStyles) -> [NSAttributedString.Key: Any]?
23+
}

0 commit comments

Comments
 (0)