Revert "WIP: Title tags"
This commit is contained in:
parent
8b584d0000
commit
86fb98c17b
@ -86,38 +86,3 @@ public extension Array where Element == Article {
|
|||||||
return map { $0.articleID }
|
return map { $0.articleID }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public extension Article {
|
|
||||||
static let allowedTags: Set = ["b", "bdi", "bdo", "cite", "code", "del", "dfn", "em", "i", "ins", "kbd", "mark", "q", /* "rb", "rp", "rt", "rtc", "ruby", */ "s", "samp", "small", "strong", "sub", "sup", "time", "u", "var"]
|
|
||||||
|
|
||||||
func sanitizedTitle(forHTML: Bool = true) -> String? {
|
|
||||||
guard let title = title else { return nil }
|
|
||||||
|
|
||||||
let scanner = Scanner(string: title)
|
|
||||||
scanner.charactersToBeSkipped = nil
|
|
||||||
var result = ""
|
|
||||||
result.reserveCapacity(title.count)
|
|
||||||
|
|
||||||
while !scanner.isAtEnd {
|
|
||||||
if let text = scanner.scanUpToString("<") {
|
|
||||||
result.append(text)
|
|
||||||
}
|
|
||||||
|
|
||||||
if let _ = scanner.scanString("<") {
|
|
||||||
// All the allowed tags currently don't allow attributes
|
|
||||||
if let tag = scanner.scanUpToString(">") {
|
|
||||||
if Self.allowedTags.contains(tag.replacingOccurrences(of: "/", with: "")) {
|
|
||||||
forHTML ? result.append("<\(tag)>") : result.append("")
|
|
||||||
} else {
|
|
||||||
forHTML ? result.append("<\(tag)>") : result.append("<\(tag)>")
|
|
||||||
}
|
|
||||||
|
|
||||||
let _ = scanner.scanString(">")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
@ -9,7 +9,7 @@ PROVISIONING_PROFILE_SPECIFIER =
|
|||||||
#include? "../../../SharedXcodeSettings/DeveloperSettings.xcconfig"
|
#include? "../../../SharedXcodeSettings/DeveloperSettings.xcconfig"
|
||||||
|
|
||||||
SDKROOT = macosx
|
SDKROOT = macosx
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.15
|
MACOSX_DEPLOYMENT_TARGET = 10.14
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0
|
IPHONEOS_DEPLOYMENT_TARGET = 13.0
|
||||||
SUPPORTED_PLATFORMS = macosx iphoneos iphonesimulator
|
SUPPORTED_PLATFORMS = macosx iphoneos iphonesimulator
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ PROVISIONING_PROFILE_SPECIFIER =
|
|||||||
#include? "../../../SharedXcodeSettings/DeveloperSettings.xcconfig"
|
#include? "../../../SharedXcodeSettings/DeveloperSettings.xcconfig"
|
||||||
|
|
||||||
SDKROOT = macosx
|
SDKROOT = macosx
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.15
|
MACOSX_DEPLOYMENT_TARGET = 10.14
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0
|
IPHONEOS_DEPLOYMENT_TARGET = 13.0
|
||||||
SUPPORTED_PLATFORMS = macosx iphoneos iphonesimulator
|
SUPPORTED_PLATFORMS = macosx iphoneos iphonesimulator
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ PROVISIONING_PROFILE_SPECIFIER =
|
|||||||
#include? "../../../SharedXcodeSettings/DeveloperSettings.xcconfig"
|
#include? "../../../SharedXcodeSettings/DeveloperSettings.xcconfig"
|
||||||
|
|
||||||
SDKROOT = macosx
|
SDKROOT = macosx
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.15
|
MACOSX_DEPLOYMENT_TARGET = 10.14
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0
|
IPHONEOS_DEPLOYMENT_TARGET = 13.0
|
||||||
SUPPORTED_PLATFORMS = macosx iphoneos iphonesimulator
|
SUPPORTED_PLATFORMS = macosx iphoneos iphonesimulator
|
||||||
|
|
||||||
@ -18,6 +18,7 @@ SWIFT_VERSION = 5.1
|
|||||||
COMBINE_HIDPI_IMAGES = YES
|
COMBINE_HIDPI_IMAGES = YES
|
||||||
|
|
||||||
COPY_PHASE_STRIP = NO
|
COPY_PHASE_STRIP = NO
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 10.14
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO
|
ALWAYS_SEARCH_USER_PATHS = NO
|
||||||
CURRENT_PROJECT_VERSION = 1
|
CURRENT_PROJECT_VERSION = 1
|
||||||
VERSION_INFO_PREFIX =
|
VERSION_INFO_PREFIX =
|
||||||
|
@ -34,7 +34,6 @@ final class MultilineTextFieldSizer {
|
|||||||
private let singleLineHeightEstimate: Int
|
private let singleLineHeightEstimate: Int
|
||||||
private let doubleLineHeightEstimate: Int
|
private let doubleLineHeightEstimate: Int
|
||||||
private var cache = [String: WidthHeightCache]() // Each string has a cache.
|
private var cache = [String: WidthHeightCache]() // Each string has a cache.
|
||||||
private var attributedCache = [NSAttributedString: WidthHeightCache]()
|
|
||||||
private static var sizers = [TextFieldSizerSpecifier: MultilineTextFieldSizer]()
|
private static var sizers = [TextFieldSizerSpecifier: MultilineTextFieldSizer]()
|
||||||
|
|
||||||
private init(numberOfLines: Int, font: NSFont) {
|
private init(numberOfLines: Int, font: NSFont) {
|
||||||
@ -52,14 +51,6 @@ final class MultilineTextFieldSizer {
|
|||||||
return sizer(numberOfLines: numberOfLines, font: font).sizeInfo(for: string, width: width)
|
return sizer(numberOfLines: numberOfLines, font: font).sizeInfo(for: string, width: width)
|
||||||
}
|
}
|
||||||
|
|
||||||
static func size(for attributedString: NSAttributedString, numberOfLines: Int, width: Int) -> TextFieldSizeInfo {
|
|
||||||
|
|
||||||
// Assumes the same font family/size for the whole string
|
|
||||||
let font = attributedString.attribute(.font, at: 0, effectiveRange: nil) as! NSFont
|
|
||||||
|
|
||||||
return sizer(numberOfLines: numberOfLines, font: font).sizeInfo(for: attributedString, width: width)
|
|
||||||
}
|
|
||||||
|
|
||||||
static func emptyCache() {
|
static func emptyCache() {
|
||||||
|
|
||||||
sizers = [TextFieldSizerSpecifier: MultilineTextFieldSizer]()
|
sizers = [TextFieldSizerSpecifier: MultilineTextFieldSizer]()
|
||||||
@ -92,16 +83,6 @@ private extension MultilineTextFieldSizer {
|
|||||||
return sizeInfo
|
return sizeInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
func sizeInfo(for attributedString: NSAttributedString, width: Int) -> TextFieldSizeInfo {
|
|
||||||
|
|
||||||
let textFieldHeight = height(for: attributedString, width: width)
|
|
||||||
let numberOfLinesUsed = numberOfLines(for: textFieldHeight)
|
|
||||||
|
|
||||||
let size = NSSize(width: width, height: textFieldHeight)
|
|
||||||
let sizeInfo = TextFieldSizeInfo(size: size, numberOfLinesUsed: numberOfLinesUsed)
|
|
||||||
return sizeInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
func height(for string: String, width: Int) -> Int {
|
func height(for string: String, width: Int) -> Int {
|
||||||
|
|
||||||
if cache[string] == nil {
|
if cache[string] == nil {
|
||||||
@ -122,26 +103,6 @@ private extension MultilineTextFieldSizer {
|
|||||||
return height
|
return height
|
||||||
}
|
}
|
||||||
|
|
||||||
func height(for attribtuedString: NSAttributedString, width: Int) -> Int {
|
|
||||||
|
|
||||||
if attributedCache[attribtuedString] == nil {
|
|
||||||
attributedCache[attribtuedString] = WidthHeightCache()
|
|
||||||
}
|
|
||||||
|
|
||||||
if let height = attributedCache[attribtuedString]![width] {
|
|
||||||
return height
|
|
||||||
}
|
|
||||||
|
|
||||||
if let height = heightConsideringNeighbors(attributedCache[attribtuedString]!, width) {
|
|
||||||
return height
|
|
||||||
}
|
|
||||||
|
|
||||||
let height = calculateHeight(attribtuedString, width)
|
|
||||||
attributedCache[attribtuedString]![width] = height
|
|
||||||
|
|
||||||
return height
|
|
||||||
}
|
|
||||||
|
|
||||||
static func createTextField(_ numberOfLines: Int, _ font: NSFont) -> NSTextField {
|
static func createTextField(_ numberOfLines: Int, _ font: NSFont) -> NSTextField {
|
||||||
|
|
||||||
let textField = NSTextField(wrappingLabelWithString: "")
|
let textField = NSTextField(wrappingLabelWithString: "")
|
||||||
@ -159,14 +120,6 @@ private extension MultilineTextFieldSizer {
|
|||||||
return MultilineTextFieldSizer.calculateHeight(string, width, textField)
|
return MultilineTextFieldSizer.calculateHeight(string, width, textField)
|
||||||
}
|
}
|
||||||
|
|
||||||
func calculateHeight(_ attributedString: NSAttributedString, _ width: Int) -> Int {
|
|
||||||
|
|
||||||
textField.attributedStringValue = attributedString
|
|
||||||
textField.preferredMaxLayoutWidth = CGFloat(width)
|
|
||||||
let size = textField.fittingSize
|
|
||||||
return Int(ceil(size.height))
|
|
||||||
}
|
|
||||||
|
|
||||||
static func calculateHeight(_ string: String, _ width: Int, _ textField: NSTextField) -> Int {
|
static func calculateHeight(_ string: String, _ width: Int, _ textField: NSTextField) -> Int {
|
||||||
|
|
||||||
textField.stringValue = string
|
textField.stringValue = string
|
||||||
|
@ -12,7 +12,6 @@ import Articles
|
|||||||
struct TimelineCellData {
|
struct TimelineCellData {
|
||||||
|
|
||||||
let title: String
|
let title: String
|
||||||
let attributedTitle: NSAttributedString
|
|
||||||
let text: String
|
let text: String
|
||||||
let dateString: String
|
let dateString: String
|
||||||
let feedName: String
|
let feedName: String
|
||||||
@ -27,7 +26,6 @@ struct TimelineCellData {
|
|||||||
init(article: Article, showFeedName: TimelineShowFeedName, feedName: String?, byline: String?, iconImage: IconImage?, showIcon: Bool, featuredImage: NSImage?) {
|
init(article: Article, showFeedName: TimelineShowFeedName, feedName: String?, byline: String?, iconImage: IconImage?, showIcon: Bool, featuredImage: NSImage?) {
|
||||||
|
|
||||||
self.title = ArticleStringFormatter.truncatedTitle(article)
|
self.title = ArticleStringFormatter.truncatedTitle(article)
|
||||||
self.attributedTitle = ArticleStringFormatter.attributedTruncatedTitle(article)
|
|
||||||
self.text = ArticleStringFormatter.truncatedSummary(article)
|
self.text = ArticleStringFormatter.truncatedSummary(article)
|
||||||
|
|
||||||
self.dateString = ArticleStringFormatter.dateString(article.logicalDatePublished)
|
self.dateString = ArticleStringFormatter.dateString(article.logicalDatePublished)
|
||||||
@ -66,6 +64,5 @@ struct TimelineCellData {
|
|||||||
self.featuredImage = nil
|
self.featuredImage = nil
|
||||||
self.read = true
|
self.read = true
|
||||||
self.starred = false
|
self.starred = false
|
||||||
self.attributedTitle = NSAttributedString()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,8 +115,7 @@ private extension TimelineCellLayout {
|
|||||||
return (r, 0)
|
return (r, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
let attributedTitle = cellData.attributedTitle.adding(font: appearance.titleFont)
|
let sizeInfo = MultilineTextFieldSizer.size(for: cellData.title, font: appearance.titleFont, numberOfLines: appearance.titleNumberOfLines, width: Int(textBoxRect.width))
|
||||||
let sizeInfo = MultilineTextFieldSizer.size(for: attributedTitle, numberOfLines: appearance.titleNumberOfLines, width: Int(textBoxRect.width))
|
|
||||||
r.size.height = sizeInfo.size.height
|
r.size.height = sizeInfo.size.height
|
||||||
if sizeInfo.numberOfLinesUsed < 1 {
|
if sizeInfo.numberOfLinesUsed < 1 {
|
||||||
r.size.height = 0
|
r.size.height = 0
|
||||||
|
@ -221,7 +221,7 @@ private extension TimelineTableCellView {
|
|||||||
|
|
||||||
func updateTitleView() {
|
func updateTitleView() {
|
||||||
|
|
||||||
updateTextFieldAttributedText(titleView, cellData?.attributedTitle)
|
updateTextFieldText(titleView, cellData?.title)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateSummaryView() {
|
func updateSummaryView() {
|
||||||
@ -247,19 +247,6 @@ private extension TimelineTableCellView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateTextFieldAttributedText(_ textField: NSTextField, _ text: NSAttributedString?) {
|
|
||||||
var s = text ?? NSAttributedString(string: "")
|
|
||||||
|
|
||||||
if let fieldFont = textField.font, let color = textField.textColor {
|
|
||||||
s = s.adding(font: fieldFont, color: color)
|
|
||||||
}
|
|
||||||
|
|
||||||
if textField.attributedStringValue != s {
|
|
||||||
textField.attributedStringValue = s
|
|
||||||
needsLayout = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func updateFeedNameView() {
|
func updateFeedNameView() {
|
||||||
switch cellData.showFeedName {
|
switch cellData.showFeedName {
|
||||||
case .byline:
|
case .byline:
|
||||||
|
@ -723,15 +723,12 @@
|
|||||||
84F9EAF4213660A100CF2DE4 /* testGenericScript.applescript in Sources */ = {isa = PBXBuildFile; fileRef = 84F9EAE1213660A100CF2DE4 /* testGenericScript.applescript */; };
|
84F9EAF4213660A100CF2DE4 /* testGenericScript.applescript in Sources */ = {isa = PBXBuildFile; fileRef = 84F9EAE1213660A100CF2DE4 /* testGenericScript.applescript */; };
|
||||||
84F9EAF5213660A100CF2DE4 /* establishMainWindowStartingState.applescript in Sources */ = {isa = PBXBuildFile; fileRef = 84F9EAE2213660A100CF2DE4 /* establishMainWindowStartingState.applescript */; };
|
84F9EAF5213660A100CF2DE4 /* establishMainWindowStartingState.applescript in Sources */ = {isa = PBXBuildFile; fileRef = 84F9EAE2213660A100CF2DE4 /* establishMainWindowStartingState.applescript */; };
|
||||||
84FF69B11FC3793300DC198E /* FaviconURLFinder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84FF69B01FC3793300DC198E /* FaviconURLFinder.swift */; };
|
84FF69B11FC3793300DC198E /* FaviconURLFinder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84FF69B01FC3793300DC198E /* FaviconURLFinder.swift */; };
|
||||||
B26B9572243D176B0053EEF5 /* NSAttributedString+NetNewsWire.swift in Sources */ = {isa = PBXBuildFile; fileRef = B26B9571243D176B0053EEF5 /* NSAttributedString+NetNewsWire.swift */; };
|
|
||||||
B26B9573243D176B0053EEF5 /* NSAttributedString+NetNewsWire.swift in Sources */ = {isa = PBXBuildFile; fileRef = B26B9571243D176B0053EEF5 /* NSAttributedString+NetNewsWire.swift */; };
|
|
||||||
B27EEBF9244D15F3000932E6 /* shared.css in Resources */ = {isa = PBXBuildFile; fileRef = B27EEBDF244D15F2000932E6 /* shared.css */; };
|
B27EEBF9244D15F3000932E6 /* shared.css in Resources */ = {isa = PBXBuildFile; fileRef = B27EEBDF244D15F2000932E6 /* shared.css */; };
|
||||||
B27EEBFA244D15F3000932E6 /* shared.css in Resources */ = {isa = PBXBuildFile; fileRef = B27EEBDF244D15F2000932E6 /* shared.css */; };
|
B27EEBFA244D15F3000932E6 /* shared.css in Resources */ = {isa = PBXBuildFile; fileRef = B27EEBDF244D15F2000932E6 /* shared.css */; };
|
||||||
B27EEBFB244D15F3000932E6 /* shared.css in Resources */ = {isa = PBXBuildFile; fileRef = B27EEBDF244D15F2000932E6 /* shared.css */; };
|
B27EEBFB244D15F3000932E6 /* shared.css in Resources */ = {isa = PBXBuildFile; fileRef = B27EEBDF244D15F2000932E6 /* shared.css */; };
|
||||||
B2B8075E239C49D300F191E0 /* RSImage-AppIcons.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2B8075D239C49D300F191E0 /* RSImage-AppIcons.swift */; };
|
B2B8075E239C49D300F191E0 /* RSImage-AppIcons.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2B8075D239C49D300F191E0 /* RSImage-AppIcons.swift */; };
|
||||||
B2B80778239C4C7000F191E0 /* RSImage-AppIcons.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2B8075D239C49D300F191E0 /* RSImage-AppIcons.swift */; };
|
B2B80778239C4C7000F191E0 /* RSImage-AppIcons.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2B8075D239C49D300F191E0 /* RSImage-AppIcons.swift */; };
|
||||||
B2B80779239C4C7300F191E0 /* RSImage-AppIcons.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2B8075D239C49D300F191E0 /* RSImage-AppIcons.swift */; };
|
B2B80779239C4C7300F191E0 /* RSImage-AppIcons.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2B8075D239C49D300F191E0 /* RSImage-AppIcons.swift */; };
|
||||||
B2C0FDEA2447A69100ADC150 /* NSAttributedString+NetNewsWire.swift in Sources */ = {isa = PBXBuildFile; fileRef = B26B9571243D176B0053EEF5 /* NSAttributedString+NetNewsWire.swift */; };
|
|
||||||
B528F81E23333C7E00E735DD /* page.html in Resources */ = {isa = PBXBuildFile; fileRef = B528F81D23333C7E00E735DD /* page.html */; };
|
B528F81E23333C7E00E735DD /* page.html in Resources */ = {isa = PBXBuildFile; fileRef = B528F81D23333C7E00E735DD /* page.html */; };
|
||||||
BDCB516724282C8A00102A80 /* AccountsNewsBlur.xib in Resources */ = {isa = PBXBuildFile; fileRef = BDCB514D24282C8A00102A80 /* AccountsNewsBlur.xib */; };
|
BDCB516724282C8A00102A80 /* AccountsNewsBlur.xib in Resources */ = {isa = PBXBuildFile; fileRef = BDCB514D24282C8A00102A80 /* AccountsNewsBlur.xib */; };
|
||||||
BDCB516824282C8A00102A80 /* AccountsNewsBlur.xib in Resources */ = {isa = PBXBuildFile; fileRef = BDCB514D24282C8A00102A80 /* AccountsNewsBlur.xib */; };
|
BDCB516824282C8A00102A80 /* AccountsNewsBlur.xib in Resources */ = {isa = PBXBuildFile; fileRef = BDCB514D24282C8A00102A80 /* AccountsNewsBlur.xib */; };
|
||||||
@ -1260,13 +1257,6 @@
|
|||||||
remoteGlobalIDString = 84F22C541B52E0D9000060CE;
|
remoteGlobalIDString = 84F22C541B52E0D9000060CE;
|
||||||
remoteInfo = RSDatabase;
|
remoteInfo = RSDatabase;
|
||||||
};
|
};
|
||||||
B234554A2453AB0F000F1D7F /* PBXContainerItemProxy */ = {
|
|
||||||
isa = PBXContainerItemProxy;
|
|
||||||
containerPortal = 517A754424451BD500B553B9 /* OAuthSwift.xcodeproj */;
|
|
||||||
proxyType = 1;
|
|
||||||
remoteGlobalIDString = C48B28011AFA598D00C7DEF6;
|
|
||||||
remoteInfo = OAuthSwiftMacOS;
|
|
||||||
};
|
|
||||||
/* End PBXContainerItemProxy section */
|
/* End PBXContainerItemProxy section */
|
||||||
|
|
||||||
/* Begin PBXCopyFilesBuildPhase section */
|
/* Begin PBXCopyFilesBuildPhase section */
|
||||||
@ -1792,7 +1782,6 @@
|
|||||||
84FF69B01FC3793300DC198E /* FaviconURLFinder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FaviconURLFinder.swift; sourceTree = "<group>"; };
|
84FF69B01FC3793300DC198E /* FaviconURLFinder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FaviconURLFinder.swift; sourceTree = "<group>"; };
|
||||||
B24EFD482330FF99006C6242 /* NetNewsWire-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NetNewsWire-Bridging-Header.h"; sourceTree = "<group>"; };
|
B24EFD482330FF99006C6242 /* NetNewsWire-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NetNewsWire-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||||
B24EFD5923310109006C6242 /* WKPreferencesPrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WKPreferencesPrivate.h; sourceTree = "<group>"; };
|
B24EFD5923310109006C6242 /* WKPreferencesPrivate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WKPreferencesPrivate.h; sourceTree = "<group>"; };
|
||||||
B26B9571243D176B0053EEF5 /* NSAttributedString+NetNewsWire.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSAttributedString+NetNewsWire.swift"; sourceTree = "<group>"; };
|
|
||||||
B27EEBDF244D15F2000932E6 /* shared.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; path = shared.css; sourceTree = "<group>"; };
|
B27EEBDF244D15F2000932E6 /* shared.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; path = shared.css; sourceTree = "<group>"; };
|
||||||
B2B8075D239C49D300F191E0 /* RSImage-AppIcons.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RSImage-AppIcons.swift"; sourceTree = "<group>"; };
|
B2B8075D239C49D300F191E0 /* RSImage-AppIcons.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RSImage-AppIcons.swift"; sourceTree = "<group>"; };
|
||||||
B528F81D23333C7E00E735DD /* page.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = page.html; sourceTree = "<group>"; };
|
B528F81D23333C7E00E735DD /* page.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = page.html; sourceTree = "<group>"; };
|
||||||
@ -2587,7 +2576,6 @@
|
|||||||
B2B8075D239C49D300F191E0 /* RSImage-AppIcons.swift */,
|
B2B8075D239C49D300F191E0 /* RSImage-AppIcons.swift */,
|
||||||
51126DA3225FDE2F00722696 /* RSImage-Extensions.swift */,
|
51126DA3225FDE2F00722696 /* RSImage-Extensions.swift */,
|
||||||
84411E701FE5FBFA004B527F /* SmallIconProvider.swift */,
|
84411E701FE5FBFA004B527F /* SmallIconProvider.swift */,
|
||||||
B26B9571243D176B0053EEF5 /* NSAttributedString+NetNewsWire.swift */,
|
|
||||||
);
|
);
|
||||||
path = Extensions;
|
path = Extensions;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -3257,7 +3245,6 @@
|
|||||||
84C37FB020DD8D9900CA8CF5 /* PBXTargetDependency */,
|
84C37FB020DD8D9900CA8CF5 /* PBXTargetDependency */,
|
||||||
84C37FB820DD8DBB00CA8CF5 /* PBXTargetDependency */,
|
84C37FB820DD8DBB00CA8CF5 /* PBXTargetDependency */,
|
||||||
84C37FC820DD8E1D00CA8CF5 /* PBXTargetDependency */,
|
84C37FC820DD8E1D00CA8CF5 /* PBXTargetDependency */,
|
||||||
B234554B2453AB0F000F1D7F /* PBXTargetDependency */,
|
|
||||||
51C451AC226377C300C03939 /* PBXTargetDependency */,
|
51C451AC226377C300C03939 /* PBXTargetDependency */,
|
||||||
51C451BC226377C900C03939 /* PBXTargetDependency */,
|
51C451BC226377C900C03939 /* PBXTargetDependency */,
|
||||||
51C451C0226377D000C03939 /* PBXTargetDependency */,
|
51C451C0226377D000C03939 /* PBXTargetDependency */,
|
||||||
@ -3304,36 +3291,36 @@
|
|||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
51314636235A7BBE00387FDC = {
|
51314636235A7BBE00387FDC = {
|
||||||
CreatedOnToolsVersion = 11.2;
|
CreatedOnToolsVersion = 11.2;
|
||||||
DevelopmentTeam = M72QZ9W58G;
|
DevelopmentTeam = SHJK2V3AJG;
|
||||||
LastSwiftMigration = 1120;
|
LastSwiftMigration = 1120;
|
||||||
ProvisioningStyle = Automatic;
|
ProvisioningStyle = Automatic;
|
||||||
};
|
};
|
||||||
513C5CE5232571C2003D4054 = {
|
513C5CE5232571C2003D4054 = {
|
||||||
CreatedOnToolsVersion = 11.0;
|
CreatedOnToolsVersion = 11.0;
|
||||||
DevelopmentTeam = M72QZ9W58G;
|
DevelopmentTeam = SHJK2V3AJG;
|
||||||
ProvisioningStyle = Automatic;
|
ProvisioningStyle = Automatic;
|
||||||
};
|
};
|
||||||
518B2ED12351B3DD00400001 = {
|
518B2ED12351B3DD00400001 = {
|
||||||
CreatedOnToolsVersion = 11.2;
|
CreatedOnToolsVersion = 11.2;
|
||||||
DevelopmentTeam = M72QZ9W58G;
|
DevelopmentTeam = SHJK2V3AJG;
|
||||||
ProvisioningStyle = Automatic;
|
ProvisioningStyle = Automatic;
|
||||||
TestTargetID = 840D617B2029031C009BC708;
|
TestTargetID = 840D617B2029031C009BC708;
|
||||||
};
|
};
|
||||||
6581C73220CED60000F4AD34 = {
|
6581C73220CED60000F4AD34 = {
|
||||||
DevelopmentTeam = M72QZ9W58G;
|
DevelopmentTeam = SHJK2V3AJG;
|
||||||
ProvisioningStyle = Automatic;
|
ProvisioningStyle = Automatic;
|
||||||
};
|
};
|
||||||
65ED3FA2235DEF6C0081F399 = {
|
65ED3FA2235DEF6C0081F399 = {
|
||||||
DevelopmentTeam = M72QZ9W58G;
|
DevelopmentTeam = SHJK2V3AJG;
|
||||||
ProvisioningStyle = Automatic;
|
ProvisioningStyle = Automatic;
|
||||||
};
|
};
|
||||||
65ED4090235DEF770081F399 = {
|
65ED4090235DEF770081F399 = {
|
||||||
DevelopmentTeam = M72QZ9W58G;
|
DevelopmentTeam = SHJK2V3AJG;
|
||||||
ProvisioningStyle = Automatic;
|
ProvisioningStyle = Automatic;
|
||||||
};
|
};
|
||||||
840D617B2029031C009BC708 = {
|
840D617B2029031C009BC708 = {
|
||||||
CreatedOnToolsVersion = 9.3;
|
CreatedOnToolsVersion = 9.3;
|
||||||
DevelopmentTeam = M72QZ9W58G;
|
DevelopmentTeam = SHJK2V3AJG;
|
||||||
ProvisioningStyle = Automatic;
|
ProvisioningStyle = Automatic;
|
||||||
SystemCapabilities = {
|
SystemCapabilities = {
|
||||||
com.apple.BackgroundModes = {
|
com.apple.BackgroundModes = {
|
||||||
@ -3343,7 +3330,7 @@
|
|||||||
};
|
};
|
||||||
849C645F1ED37A5D003D8FC0 = {
|
849C645F1ED37A5D003D8FC0 = {
|
||||||
CreatedOnToolsVersion = 8.2.1;
|
CreatedOnToolsVersion = 8.2.1;
|
||||||
DevelopmentTeam = M72QZ9W58G;
|
DevelopmentTeam = SHJK2V3AJG;
|
||||||
ProvisioningStyle = Automatic;
|
ProvisioningStyle = Automatic;
|
||||||
SystemCapabilities = {
|
SystemCapabilities = {
|
||||||
com.apple.HardenedRuntime = {
|
com.apple.HardenedRuntime = {
|
||||||
@ -3353,7 +3340,7 @@
|
|||||||
};
|
};
|
||||||
849C64701ED37A5D003D8FC0 = {
|
849C64701ED37A5D003D8FC0 = {
|
||||||
CreatedOnToolsVersion = 8.2.1;
|
CreatedOnToolsVersion = 8.2.1;
|
||||||
DevelopmentTeam = M72QZ9W58G;
|
DevelopmentTeam = SHJK2V3AJG;
|
||||||
ProvisioningStyle = Automatic;
|
ProvisioningStyle = Automatic;
|
||||||
TestTargetID = 849C645F1ED37A5D003D8FC0;
|
TestTargetID = 849C645F1ED37A5D003D8FC0;
|
||||||
};
|
};
|
||||||
@ -4217,7 +4204,6 @@
|
|||||||
65ED4023235DEF6C0081F399 /* Folder+Scriptability.swift in Sources */,
|
65ED4023235DEF6C0081F399 /* Folder+Scriptability.swift in Sources */,
|
||||||
65ED4024235DEF6C0081F399 /* TimelineCellLayout.swift in Sources */,
|
65ED4024235DEF6C0081F399 /* TimelineCellLayout.swift in Sources */,
|
||||||
65ED4025235DEF6C0081F399 /* DetailWebView.swift in Sources */,
|
65ED4025235DEF6C0081F399 /* DetailWebView.swift in Sources */,
|
||||||
B26B9573243D176B0053EEF5 /* NSAttributedString+NetNewsWire.swift in Sources */,
|
|
||||||
B2B80779239C4C7300F191E0 /* RSImage-AppIcons.swift in Sources */,
|
B2B80779239C4C7300F191E0 /* RSImage-AppIcons.swift in Sources */,
|
||||||
65ED4026235DEF6C0081F399 /* TimelineTableRowView.swift in Sources */,
|
65ED4026235DEF6C0081F399 /* TimelineTableRowView.swift in Sources */,
|
||||||
65ED4027235DEF6C0081F399 /* UnreadIndicatorView.swift in Sources */,
|
65ED4027235DEF6C0081F399 /* UnreadIndicatorView.swift in Sources */,
|
||||||
@ -4314,7 +4300,6 @@
|
|||||||
51F9F3F923DFB16300A314FD /* UITableView-Extensions.swift in Sources */,
|
51F9F3F923DFB16300A314FD /* UITableView-Extensions.swift in Sources */,
|
||||||
51C452792265091600C03939 /* MasterTimelineTableViewCell.swift in Sources */,
|
51C452792265091600C03939 /* MasterTimelineTableViewCell.swift in Sources */,
|
||||||
51C4526B226508F600C03939 /* MasterFeedViewController.swift in Sources */,
|
51C4526B226508F600C03939 /* MasterFeedViewController.swift in Sources */,
|
||||||
B2C0FDEA2447A69100ADC150 /* NSAttributedString+NetNewsWire.swift in Sources */,
|
|
||||||
5126EE97226CB48A00C22AFC /* SceneCoordinator.swift in Sources */,
|
5126EE97226CB48A00C22AFC /* SceneCoordinator.swift in Sources */,
|
||||||
84CAFCB022BC8C35007694F0 /* FetchRequestOperation.swift in Sources */,
|
84CAFCB022BC8C35007694F0 /* FetchRequestOperation.swift in Sources */,
|
||||||
51EF0F77227716200050506E /* FaviconGenerator.swift in Sources */,
|
51EF0F77227716200050506E /* FaviconGenerator.swift in Sources */,
|
||||||
@ -4554,7 +4539,6 @@
|
|||||||
8426119E1FCB6ED40086A189 /* HTMLMetadataDownloader.swift in Sources */,
|
8426119E1FCB6ED40086A189 /* HTMLMetadataDownloader.swift in Sources */,
|
||||||
849A976E1ED9EBC8007D329B /* TimelineViewController.swift in Sources */,
|
849A976E1ED9EBC8007D329B /* TimelineViewController.swift in Sources */,
|
||||||
3B826DCC2385C84800FC1ADB /* AccountsFeedWranglerWindowController.swift in Sources */,
|
3B826DCC2385C84800FC1ADB /* AccountsFeedWranglerWindowController.swift in Sources */,
|
||||||
B26B9572243D176B0053EEF5 /* NSAttributedString+NetNewsWire.swift in Sources */,
|
|
||||||
5154368B229404D1005E1CDF /* FaviconGenerator.swift in Sources */,
|
5154368B229404D1005E1CDF /* FaviconGenerator.swift in Sources */,
|
||||||
5183CCE6226F4E110010922C /* RefreshInterval.swift in Sources */,
|
5183CCE6226F4E110010922C /* RefreshInterval.swift in Sources */,
|
||||||
849A97771ED9EC04007D329B /* TimelineCellData.swift in Sources */,
|
849A97771ED9EC04007D329B /* TimelineCellData.swift in Sources */,
|
||||||
@ -4769,11 +4753,6 @@
|
|||||||
name = RSDatabase;
|
name = RSDatabase;
|
||||||
targetProxy = 84C37FC720DD8E1D00CA8CF5 /* PBXContainerItemProxy */;
|
targetProxy = 84C37FC720DD8E1D00CA8CF5 /* PBXContainerItemProxy */;
|
||||||
};
|
};
|
||||||
B234554B2453AB0F000F1D7F /* PBXTargetDependency */ = {
|
|
||||||
isa = PBXTargetDependency;
|
|
||||||
name = OAuthSwiftMacOS;
|
|
||||||
targetProxy = B234554A2453AB0F000F1D7F /* PBXContainerItemProxy */;
|
|
||||||
};
|
|
||||||
/* End PBXTargetDependency section */
|
/* End PBXTargetDependency section */
|
||||||
|
|
||||||
/* Begin PBXVariantGroup section */
|
/* Begin PBXVariantGroup section */
|
||||||
|
@ -46,7 +46,7 @@ struct ArticleRenderer {
|
|||||||
self.article = article
|
self.article = article
|
||||||
self.extractedArticle = extractedArticle
|
self.extractedArticle = extractedArticle
|
||||||
self.articleStyle = style
|
self.articleStyle = style
|
||||||
self.title = article?.sanitizedTitle() ?? ""
|
self.title = article?.title ?? ""
|
||||||
if let content = extractedArticle?.content {
|
if let content = extractedArticle?.content {
|
||||||
self.body = content
|
self.body = content
|
||||||
self.baseURL = extractedArticle?.url
|
self.baseURL = extractedArticle?.url
|
||||||
|
@ -52,8 +52,8 @@ struct ArticleStringFormatter {
|
|||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
static func truncatedTitle(_ article: Article, forHTML: Bool = false) -> String {
|
static func truncatedTitle(_ article: Article) -> String {
|
||||||
guard let title = article.sanitizedTitle(forHTML: forHTML) else {
|
guard let title = article.title else {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,11 +64,7 @@ struct ArticleStringFormatter {
|
|||||||
var s = title.replacingOccurrences(of: "\n", with: "")
|
var s = title.replacingOccurrences(of: "\n", with: "")
|
||||||
s = s.replacingOccurrences(of: "\r", with: "")
|
s = s.replacingOccurrences(of: "\r", with: "")
|
||||||
s = s.replacingOccurrences(of: "\t", with: "")
|
s = s.replacingOccurrences(of: "\t", with: "")
|
||||||
|
s = s.rsparser_stringByDecodingHTMLEntities()
|
||||||
if !forHTML {
|
|
||||||
s = s.rsparser_stringByDecodingHTMLEntities()
|
|
||||||
}
|
|
||||||
|
|
||||||
s = s.trimmingWhitespace
|
s = s.trimmingWhitespace
|
||||||
s = s.collapsingWhitespace
|
s = s.collapsingWhitespace
|
||||||
|
|
||||||
@ -83,12 +79,6 @@ struct ArticleStringFormatter {
|
|||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
static func attributedTruncatedTitle(_ article: Article) -> NSAttributedString {
|
|
||||||
let title = truncatedTitle(article, forHTML: true)
|
|
||||||
let attributed = NSAttributedString(html: title)
|
|
||||||
return attributed
|
|
||||||
}
|
|
||||||
|
|
||||||
static func truncatedSummary(_ article: Article) -> String {
|
static func truncatedSummary(_ article: Article) -> String {
|
||||||
guard let body = article.body else {
|
guard let body = article.body else {
|
||||||
return ""
|
return ""
|
||||||
|
@ -1,134 +0,0 @@
|
|||||||
//
|
|
||||||
// NSAttributedString+NetNewsWire.swift
|
|
||||||
// NetNewsWire
|
|
||||||
//
|
|
||||||
// Created by Nate Weaver on 2020-04-07.
|
|
||||||
// Copyright © 2020 Ranchero Software. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
#if canImport(AppKit)
|
|
||||||
import AppKit
|
|
||||||
typealias Font = NSFont
|
|
||||||
typealias FontDescriptor = NSFontDescriptor
|
|
||||||
typealias Color = NSColor
|
|
||||||
|
|
||||||
private let boldTrait = NSFontDescriptor.SymbolicTraits.bold
|
|
||||||
private let italicTrait = NSFontDescriptor.SymbolicTraits.italic
|
|
||||||
private let monoSpaceTrait = NSFontDescriptor.SymbolicTraits.monoSpace
|
|
||||||
#else
|
|
||||||
import UIKit
|
|
||||||
typealias Font = UIFont
|
|
||||||
typealias FontDescriptor = UIFontDescriptor
|
|
||||||
typealias Color = UIColor
|
|
||||||
|
|
||||||
private let boldTrait = UIFontDescriptor.SymbolicTraits.traitBold
|
|
||||||
private let italicTrait = UIFontDescriptor.SymbolicTraits.traitItalic
|
|
||||||
private let monoSpaceTrait = UIFontDescriptor.SymbolicTraits.traitMonoSpace
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extension NSAttributedString {
|
|
||||||
|
|
||||||
/// Adds a font and color to an attributed string.
|
|
||||||
///
|
|
||||||
/// Additionally converts super-/subscript runs to super-/subscripted font variants
|
|
||||||
/// and converts bold text to heavy if the base font is semibold.
|
|
||||||
///
|
|
||||||
/// - Parameters:
|
|
||||||
/// - baseFont: The font to add.
|
|
||||||
/// - color: The color to add.
|
|
||||||
func adding(font baseFont: Font, color: Color? = nil) -> NSAttributedString {
|
|
||||||
let mutable = self.mutableCopy() as! NSMutableAttributedString
|
|
||||||
let fullRange = NSRange(location: 0, length: mutable.length)
|
|
||||||
|
|
||||||
if let color = color {
|
|
||||||
mutable.addAttribute(.foregroundColor, value: color as Any, range: fullRange)
|
|
||||||
}
|
|
||||||
|
|
||||||
let size = baseFont.pointSize
|
|
||||||
let baseDescriptor = baseFont.fontDescriptor
|
|
||||||
let baseSymbolicTraits = baseDescriptor.symbolicTraits
|
|
||||||
|
|
||||||
let baseTraits = baseDescriptor.object(forKey: .traits) as! [FontDescriptor.TraitKey: Any]
|
|
||||||
let baseWeight = baseTraits[.weight] as! Font.Weight
|
|
||||||
|
|
||||||
mutable.enumerateAttribute(.font, in: fullRange, options: []) { (font: Any?, range: NSRange, stop: UnsafeMutablePointer<ObjCBool>) in
|
|
||||||
guard let font = font as? Font else { return }
|
|
||||||
|
|
||||||
var newSymbolicTraits = baseSymbolicTraits
|
|
||||||
|
|
||||||
let symbolicTraits = font.fontDescriptor.symbolicTraits
|
|
||||||
|
|
||||||
if symbolicTraits.contains(italicTrait) {
|
|
||||||
newSymbolicTraits.insert(italicTrait)
|
|
||||||
}
|
|
||||||
|
|
||||||
if symbolicTraits.contains(monoSpaceTrait) {
|
|
||||||
newSymbolicTraits.insert(monoSpaceTrait)
|
|
||||||
}
|
|
||||||
|
|
||||||
#if canImport(AppKit)
|
|
||||||
var descriptor = baseDescriptor.withSymbolicTraits(newSymbolicTraits)
|
|
||||||
#else
|
|
||||||
var descriptor = baseDescriptor.withSymbolicTraits(newSymbolicTraits)!
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if symbolicTraits.contains(boldTrait) {
|
|
||||||
// If the base font is semibold (as timeline titles are), make the "bold"
|
|
||||||
// text heavy for better contrast.
|
|
||||||
|
|
||||||
if baseWeight == .semibold {
|
|
||||||
let traits: [FontDescriptor.TraitKey: Any] = [.weight: Font.Weight.heavy]
|
|
||||||
let attributes: [FontDescriptor.AttributeName: Any] = [.traits: traits]
|
|
||||||
descriptor = descriptor.addingAttributes(attributes)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let newFont = Font(descriptor: descriptor, size: size)
|
|
||||||
|
|
||||||
mutable.addAttribute(.font, value: newFont as Any, range: range)
|
|
||||||
}
|
|
||||||
|
|
||||||
// make sup/sub smaller. `Key("NSSupeScript")` is used here because `.superscript`
|
|
||||||
// isn't defined in UIKit.
|
|
||||||
let superscriptAttribute = Key("NSSuperScript")
|
|
||||||
|
|
||||||
mutable.enumerateAttributes(in: fullRange, options: []) { (attributes: [Key : Any], range: NSRange, stop: UnsafeMutablePointer<ObjCBool>) in
|
|
||||||
guard let superscript = attributes[superscriptAttribute] as? Int else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if superscript != 0 {
|
|
||||||
let font = mutable.attribute(.font, at: range.location, effectiveRange: nil) as! Font
|
|
||||||
|
|
||||||
// There's some discrepancy here: The raw value of AppKit's .typeIdentifier is UIKit's .featureIdentifier,
|
|
||||||
// and AppKit's .selectorIdentifier is UIKit's .typeIdentifier
|
|
||||||
#if canImport(AppKit)
|
|
||||||
let features: [FontDescriptor.FeatureKey: Any] = [.typeIdentifier: kVerticalPositionType, .selectorIdentifier: superscript > 0 ? kSuperiorsSelector : kInferiorsSelector]
|
|
||||||
#else
|
|
||||||
let features: [FontDescriptor.FeatureKey: Any] = [.featureIdentifier: kVerticalPositionType, .typeIdentifier: superscript > 0 ? kSuperiorsSelector : kInferiorsSelector]
|
|
||||||
#endif
|
|
||||||
let attributes: [FontDescriptor.AttributeName: Any] = [.featureSettings: [features]]
|
|
||||||
let descriptor = font.fontDescriptor.addingAttributes(attributes)
|
|
||||||
|
|
||||||
let newFont = Font(descriptor: descriptor, size: font.pointSize)
|
|
||||||
|
|
||||||
let newAttributes: [NSAttributedString.Key: Any] = [
|
|
||||||
.font: newFont as Any,
|
|
||||||
superscriptAttribute: 0,
|
|
||||||
]
|
|
||||||
|
|
||||||
mutable.addAttributes(newAttributes, range: range)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return mutable.copy() as! NSAttributedString
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates an attributed string from HTML.
|
|
||||||
convenience init(html: String) {
|
|
||||||
let data = html.data(using: .utf8)!
|
|
||||||
let options: [NSAttributedString.DocumentReadingOptionKey: Any] = [.characterEncoding: String.Encoding.utf8.rawValue, .documentType: NSAttributedString.DocumentType.html]
|
|
||||||
try! self.init(data: data, options: options, documentAttributes: nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -12,7 +12,6 @@ import Articles
|
|||||||
struct MasterTimelineCellData {
|
struct MasterTimelineCellData {
|
||||||
|
|
||||||
let title: String
|
let title: String
|
||||||
let attributedTitle: NSAttributedString
|
|
||||||
let summary: String
|
let summary: String
|
||||||
let dateString: String
|
let dateString: String
|
||||||
let feedName: String
|
let feedName: String
|
||||||
@ -29,7 +28,6 @@ struct MasterTimelineCellData {
|
|||||||
init(article: Article, showFeedName: ShowFeedName, feedName: String?, byline: String?, iconImage: IconImage?, showIcon: Bool, featuredImage: UIImage?, numberOfLines: Int, iconSize: IconSize) {
|
init(article: Article, showFeedName: ShowFeedName, feedName: String?, byline: String?, iconImage: IconImage?, showIcon: Bool, featuredImage: UIImage?, numberOfLines: Int, iconSize: IconSize) {
|
||||||
|
|
||||||
self.title = ArticleStringFormatter.truncatedTitle(article)
|
self.title = ArticleStringFormatter.truncatedTitle(article)
|
||||||
self.attributedTitle = ArticleStringFormatter.attributedTruncatedTitle(article)
|
|
||||||
self.summary = ArticleStringFormatter.truncatedSummary(article)
|
self.summary = ArticleStringFormatter.truncatedSummary(article)
|
||||||
|
|
||||||
self.dateString = ArticleStringFormatter.dateString(article.logicalDatePublished)
|
self.dateString = ArticleStringFormatter.dateString(article.logicalDatePublished)
|
||||||
@ -62,7 +60,6 @@ struct MasterTimelineCellData {
|
|||||||
|
|
||||||
init() { //Empty
|
init() { //Empty
|
||||||
self.title = ""
|
self.title = ""
|
||||||
self.attributedTitle = NSAttributedString()
|
|
||||||
self.summary = ""
|
self.summary = ""
|
||||||
self.dateString = ""
|
self.dateString = ""
|
||||||
self.feedName = ""
|
self.feedName = ""
|
||||||
|
@ -148,7 +148,7 @@ private extension MasterTimelineTableViewCell {
|
|||||||
func updateTitleView() {
|
func updateTitleView() {
|
||||||
titleView.font = MasterTimelineDefaultCellLayout.titleFont
|
titleView.font = MasterTimelineDefaultCellLayout.titleFont
|
||||||
titleView.textColor = labelColor
|
titleView.textColor = labelColor
|
||||||
updateTextFieldAttributedText(titleView, cellData?.attributedTitle)
|
updateTextFieldText(titleView, cellData?.title)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateSummaryView() {
|
func updateSummaryView() {
|
||||||
@ -170,19 +170,6 @@ private extension MasterTimelineTableViewCell {
|
|||||||
setNeedsLayout()
|
setNeedsLayout()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateTextFieldAttributedText(_ label: UILabel, _ text: NSAttributedString?) {
|
|
||||||
var s = text ?? NSAttributedString(string: "")
|
|
||||||
|
|
||||||
if let fieldFont = label.font, let color = label.textColor {
|
|
||||||
s = s.adding(font: fieldFont, color: color)
|
|
||||||
}
|
|
||||||
|
|
||||||
if label.attributedText != s {
|
|
||||||
label.attributedText = s
|
|
||||||
setNeedsLayout()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func updateFeedNameView() {
|
func updateFeedNameView() {
|
||||||
switch cellData.showFeedName {
|
switch cellData.showFeedName {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user