mirror of
https://github.com/zhigang1992/GitHawk.git
synced 2026-05-22 23:42:50 +08:00
Add support for shortening GitHub issues links (#531)
* Add support for shortening GitHub issues links Relates to #411 * Added Tests
This commit is contained in:
committed by
Ryan Nystrom
parent
d85cb91f07
commit
ba4a0713ec
@@ -357,6 +357,53 @@ func updateIssueShorthand(
|
||||
return mutableAttributedString
|
||||
}
|
||||
|
||||
private let issueURLRegex = try! NSRegularExpression(pattern: "https?:\\/\\/.*github.com\\/(\\w*)\\/([^/]*?)\\/issues\\/([0-9]+)", options: [])
|
||||
func shortenGitHubLinks(attributedString: NSAttributedString,
|
||||
options: GitHubMarkdownOptions) -> NSAttributedString {
|
||||
|
||||
guard options.flavors.contains(.issueShorthand) else { return attributedString }
|
||||
|
||||
let string = attributedString.string
|
||||
let mutableAttributedString = NSMutableAttributedString(attributedString: attributedString)
|
||||
let matches = issueURLRegex.matches(in: string, options: [], range: string.nsrange)
|
||||
|
||||
for match in matches.reversed() {
|
||||
let ownerRange = match.range(at: 1)
|
||||
let repoRange = match.range(at: 2)
|
||||
let numberRange = match.range(at: 3)
|
||||
|
||||
guard let ownerSubstring = string.substring(with: ownerRange),
|
||||
let repoSubstring = string.substring(with: repoRange),
|
||||
let numberSubstring = string.substring(with: numberRange) else { continue }
|
||||
|
||||
var attributes = attributedString.attributes(at: match.range.location, effectiveRange: nil)
|
||||
|
||||
// manually disable link shortening for some text (namely code)
|
||||
guard attributes[MarkdownAttribute.linkShorteningDisabled] == nil else { continue }
|
||||
|
||||
attributes[.foregroundColor] = Styles.Colors.Blue.medium.color
|
||||
attributes[MarkdownAttribute.issue] = IssueDetailsModel(
|
||||
owner: ownerSubstring,
|
||||
repo: repoSubstring,
|
||||
number: (numberSubstring as NSString).integerValue
|
||||
)
|
||||
attributes[MarkdownAttribute.url] = nil
|
||||
|
||||
var shortenedText: String
|
||||
|
||||
if ownerSubstring == options.owner && repoSubstring == options.repo {
|
||||
shortenedText = "#\(numberSubstring)"
|
||||
} else {
|
||||
shortenedText = "\(ownerSubstring)/\(repoSubstring)#\(numberSubstring)"
|
||||
}
|
||||
|
||||
let linkAttributedString = NSAttributedString(string: shortenedText, attributes: attributes)
|
||||
mutableAttributedString.replaceCharacters(in: match.range, with: linkAttributedString)
|
||||
}
|
||||
|
||||
return mutableAttributedString
|
||||
}
|
||||
|
||||
func createTextModelUpdatingGitHubFeatures(
|
||||
attributedString: NSAttributedString,
|
||||
width: CGFloat,
|
||||
@@ -366,10 +413,11 @@ func createTextModelUpdatingGitHubFeatures(
|
||||
|
||||
let usernames = updateUsernames(attributedString: attributedString, options: options)
|
||||
let issues = updateIssueShorthand(attributedString: usernames, options: options)
|
||||
let shorten = shortenGitHubLinks(attributedString: issues, options: options)
|
||||
|
||||
return NSAttributedStringSizing(
|
||||
containerWidth: width,
|
||||
attributedText: issues,
|
||||
attributedText: shorten,
|
||||
inset: inset
|
||||
)
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ func PushAttributes(
|
||||
NSAttributedStringKey.backgroundColor: Styles.Colors.Gray.lighter.color,
|
||||
.foregroundColor: Styles.Colors.Gray.dark.color,
|
||||
MarkdownAttribute.usernameDisabled: true,
|
||||
MarkdownAttribute.linkShorteningDisabled: true,
|
||||
]
|
||||
case .link: newAttributes = [
|
||||
.foregroundColor: Styles.Colors.Blue.medium.color,
|
||||
|
||||
@@ -13,5 +13,6 @@ enum MarkdownAttribute {
|
||||
static let email = NSAttributedStringKey(rawValue: "com.freetime.Markdown.email-name")
|
||||
static let username = NSAttributedStringKey(rawValue: "com.freetime.Markdown.username-name")
|
||||
static let usernameDisabled = NSAttributedStringKey(rawValue: "com.freetime.Markdown.username-disabled-name")
|
||||
static let linkShorteningDisabled = NSAttributedStringKey(rawValue: "com.freetime.Markdown.link-shortening-disabled-name")
|
||||
static let issue = NSAttributedStringKey(rawValue: "com.freetime.Markdown.issue")
|
||||
}
|
||||
|
||||
@@ -124,5 +124,33 @@ final class MMMarkdownASTTests: XCTestCase {
|
||||
XCTAssertEqual(comboDetails.repo, "bar")
|
||||
XCTAssertEqual(comboDetails.number, 456)
|
||||
}
|
||||
|
||||
func test_shortenLinks() {
|
||||
let options = GitHubMarkdownOptions(owner: "owner", repo: "repo", flavors: [.issueShorthand])
|
||||
|
||||
// Test Same Repository
|
||||
let testOne = "https://github.com/owner/repo/issues/123"
|
||||
let resultOne = CreateCommentModels(markdown: testOne, width: 300, options: options)
|
||||
let textOne = resultOne.first as! NSAttributedStringSizing
|
||||
XCTAssertEqual(textOne.attributedText.string, "#123")
|
||||
XCTAssertNotNil(textOne.attributedText.attributes(at: 1, effectiveRange: nil)[MarkdownAttribute.issue])
|
||||
|
||||
let detailsOne = textOne.attributedText.attributes(at: 1, effectiveRange: nil)[MarkdownAttribute.issue] as! IssueDetailsModel
|
||||
XCTAssertEqual(detailsOne.owner, "owner")
|
||||
XCTAssertEqual(detailsOne.repo, "repo")
|
||||
XCTAssertEqual(detailsOne.number, 123)
|
||||
|
||||
// Test Cross Repository
|
||||
let testTwo = "https://github.com/differentOwner/differentRepo/issues/321"
|
||||
let resultTwo = CreateCommentModels(markdown: testTwo, width: 300, options: options)
|
||||
let textTwo = resultTwo.first as! NSAttributedStringSizing
|
||||
XCTAssertEqual(textTwo.attributedText.string, "differentOwner/differentRepo#321")
|
||||
XCTAssertNotNil(textTwo.attributedText.attributes(at: 1, effectiveRange: nil)[MarkdownAttribute.issue])
|
||||
|
||||
let detailsTwo = textTwo.attributedText.attributes(at: 1, effectiveRange: nil)[MarkdownAttribute.issue] as! IssueDetailsModel
|
||||
XCTAssertEqual(detailsTwo.owner, "differentOwner")
|
||||
XCTAssertEqual(detailsTwo.repo, "differentRepo")
|
||||
XCTAssertEqual(detailsTwo.number, 321)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user