Skip to content

Commit 413809e

Browse files
committed
【修改信息】 readme 和 preview vc link跳转优化
1 parent 8797634 commit 413809e

File tree

5 files changed

+198
-60
lines changed

5 files changed

+198
-60
lines changed

ZLGitHubClient/ZLGitHubClient.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
7407C8BB2DDBA21E0052A413 /* ZLCompareCommitFilesController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7407C8BA2DDBA20F0052A413 /* ZLCompareCommitFilesController.swift */; };
4747
7407CFCD2DE60AD10052A413 /* ZLUIRouter+Github.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7407CFCC2DE60AC60052A413 /* ZLUIRouter+Github.swift */; };
4848
7407CFD02DE62ABA0052A413 /* String+URL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7407CFCF2DE62AB40052A413 /* String+URL.swift */; };
49+
7407CFD22DEE14710052A413 /* ZLGithubMarkDownLinkRouter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7407CFD12DEE14610052A413 /* ZLGithubMarkDownLinkRouter.swift */; };
4950
740C2F2B2830F9E300DAFF0E /* ZLExploreChildListController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 740C2F2A2830F9E300DAFF0E /* ZLExploreChildListController.swift */; };
5051
740C2F362832A1E100DAFF0E /* ZLBaseCardTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 740C2F352832A1E100DAFF0E /* ZLBaseCardTableViewCell.swift */; };
5152
740C2FBC2838D46400DAFF0E /* ZLStarRepoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 740C2FBB2838D46400DAFF0E /* ZLStarRepoViewController.swift */; };
@@ -361,6 +362,7 @@
361362
7407C8BA2DDBA20F0052A413 /* ZLCompareCommitFilesController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZLCompareCommitFilesController.swift; sourceTree = "<group>"; };
362363
7407CFCC2DE60AC60052A413 /* ZLUIRouter+Github.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ZLUIRouter+Github.swift"; sourceTree = "<group>"; };
363364
7407CFCF2DE62AB40052A413 /* String+URL.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+URL.swift"; sourceTree = "<group>"; };
365+
7407CFD12DEE14610052A413 /* ZLGithubMarkDownLinkRouter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZLGithubMarkDownLinkRouter.swift; sourceTree = "<group>"; };
364366
7408EC222533BD72001DA1EC /* ZLGithubAppKey.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ZLGithubAppKey.h; sourceTree = "<group>"; };
365367
740C2F2A2830F9E300DAFF0E /* ZLExploreChildListController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZLExploreChildListController.swift; sourceTree = "<group>"; };
366368
740C2F352832A1E100DAFF0E /* ZLBaseCardTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZLBaseCardTableViewCell.swift; sourceTree = "<group>"; };
@@ -2097,6 +2099,7 @@
20972099
74D3F05B259BCDC10002A2D3 /* Router */ = {
20982100
isa = PBXGroup;
20992101
children = (
2102+
7407CFD12DEE14610052A413 /* ZLGithubMarkDownLinkRouter.swift */,
21002103
7407CFCC2DE60AC60052A413 /* ZLUIRouter+Github.swift */,
21012104
7486DFBA25A2608F00EE38CB /* ZLUIRouter.swift */,
21022105
);
@@ -2841,6 +2844,7 @@
28412844
7403A3452DCF9D89009141E1 /* ZLReleaseTableViewCell.swift in Sources */,
28422845
74634D4F2766408500A042F4 /* ZLOrgInfoHeaderCellData.swift in Sources */,
28432846
7407C8AA2DDA59570052A413 /* ZLPatchView.swift in Sources */,
2847+
7407CFD22DEE14710052A413 /* ZLGithubMarkDownLinkRouter.swift in Sources */,
28442848
743425C7230AC6AD0031AD7D /* ZLRepoInfoController.swift in Sources */,
28452849
74209D5424B66D820068891E /* ZLRepoLanguagesPercentView.swift in Sources */,
28462850
747FCA1525FFAA2B00D2C39B /* Fixed_Repo.intentdefinition in Sources */,
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
//
2+
// ZLGithubMarkDownLinkRouter.swift
3+
// ZLGitHubClient
4+
//
5+
// Created by 朱猛 on 2025/6/3.
6+
// Copyright © 2025 ZM. All rights reserved.
7+
//
8+
9+
10+
class ZLGithubMarkDownLinkRouter {
11+
12+
let needDealWithRelativePath: Bool /// 是否处理相对路径
13+
14+
let needDealWithAboutBlank: Bool /// 是否处理AboutBlank
15+
16+
let needDealWithCommonURL: Bool /// 是否处理 邮箱,手机号等链接
17+
18+
let forbidSamePathNavigation: Bool /// 禁止相同路径跳转
19+
20+
let forbidInvalidNavigation: Bool /// 禁止无效的跳转
21+
22+
var rootRepoHTMLPath: String = "" /// 仓库根链接
23+
24+
var markdownHTMLPath: String = "" /// markdown页面 page
25+
26+
27+
init(needDealWithRelativePath: Bool = false ,
28+
needDealWithAboutBlank: Bool = false,
29+
needDealWithCommonURL: Bool = false,
30+
forbidSamePathNavigation: Bool = false,
31+
forbidInvalidNavigation: Bool = true,
32+
rootRepoHTMLPath: String = "",
33+
markdownHTMLPath: String = "") {
34+
self.needDealWithCommonURL = needDealWithCommonURL
35+
self.needDealWithRelativePath = needDealWithRelativePath
36+
self.needDealWithAboutBlank = needDealWithAboutBlank
37+
self.forbidSamePathNavigation = forbidSamePathNavigation
38+
self.forbidInvalidNavigation = forbidInvalidNavigation
39+
self.rootRepoHTMLPath = rootRepoHTMLPath
40+
self.markdownHTMLPath = markdownHTMLPath
41+
}
42+
43+
44+
/// 处理链接
45+
func dealWithLink(urlStr: String) -> Bool {
46+
47+
print("dealWithLink \(urlStr)")
48+
49+
50+
51+
/**
52+
* 1. 处理AboutBlank
53+
*/
54+
if isAboutBlackURLStr(urlStr: urlStr) {
55+
/// 是AboutBlank
56+
if needDealWithAboutBlank {
57+
return dealWithAboutBlank(urlStr: urlStr)
58+
} else {
59+
return false
60+
}
61+
}
62+
63+
/**
64+
* 2. 处理相同html路径跳转
65+
*/
66+
if let url = URL(string: urlStr),
67+
let htmlURL = URL(string: markdownHTMLPath) {
68+
if forbidSamePathNavigation, url.path == htmlURL.path {
69+
return true
70+
}
71+
}
72+
73+
/**
74+
* 3. 处理处理 邮箱,手机号等链接
75+
*/
76+
if needDealWithCommonURL, ZLCommonURLManager.openURL(urlStr: urlStr) {
77+
return true
78+
}
79+
80+
/**
81+
* 4. 处理处理 邮箱,手机号等链接
82+
*/
83+
var url = URL(string: urlStr)
84+
if needDealWithRelativePath, url?.host == nil { // 如果是相对路径,组装baseurl; baseurl为仓库根路径
85+
url = URL(string: "\(rootRepoHTMLPath)/\(urlStr)")
86+
}
87+
88+
89+
if let realurl = url {
90+
/// 处理github 链接 或者 webview
91+
ZLUIRouter.openURL(url: realurl)
92+
return true
93+
}
94+
95+
if forbidInvalidNavigation {
96+
return true
97+
} else {
98+
return false
99+
}
100+
101+
}
102+
103+
104+
func dealWithAboutBlank(urlStr: String) -> Bool {
105+
var url = urlStr
106+
if(url.hasPrefix("about:blank%23")) {
107+
if let range = url.range(of: "about:blank%23") {
108+
url.removeSubrange(range)
109+
}
110+
if let url = URL(string: "\(self.markdownHTMLPath)#\(url)") {
111+
ZLUIRouter.openURL(url: url)
112+
return true
113+
} else {
114+
return false
115+
}
116+
}
117+
return false
118+
}
119+
120+
func isAboutBlackURLStr(urlStr: String) -> Bool {
121+
return urlStr.hasPrefix("about:blank%23")
122+
}
123+
}

ZLGitHubClient/ZLGitHubClient/Class/Router/ZLUIRouter+Github.swift

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ enum ZLGithubPathType {
1818
case commit(login: String, repoName: String, ref: String)
1919
case compare(login: String, repoName: String, baseRef: String, headRef: String)
2020
case tree(login: String, repoName: String, ref: String, path: String)
21-
case blob(login: String, repoName: String, ref: String, path: String)
21+
case blob(login: String, repoName: String, ref: String, path: String, fragment: String)
2222

2323
func routerParams() -> (SYDCentralRouterModelType, ZLRouterKey, [String:Any]) {
2424
switch self {
@@ -83,12 +83,13 @@ enum ZLGithubPathType {
8383
"branch": ref,
8484
"path": path])
8585

86-
case .blob(let login, let repoName, let ref, let path):
86+
case .blob(let login, let repoName, let ref, let path, let fragment):
8787
return (.uiViewController,
8888
.RepoCodePreview3Controller,
8989
["repoFullName": "\(login)/\(repoName)",
9090
"branch": ref,
91-
"path": path])
91+
"path": path,
92+
"fragment": fragment])
9293
}
9394
}
9495

@@ -211,21 +212,30 @@ extension ZLUIRouter {
211212
if pathCount >= 5 {
212213
let ref = pathComponents[4]
213214
let paths = Array(pathComponents[5...])
215+
let path = paths.joined(separator: "/")
214216
pathType = .tree(login: pathComponents[1],
215217
repoName: pathComponents[2],
216-
ref: pathComponents[4],
217-
path: paths.joined(separator: "/"))
218+
ref: ref,
219+
path: path)
218220
}
219221

220222
case .blob:
221-
// https://github.com/ExistOrLive/GithubClient/blob/master/Document/GithubAction/DailyCI%E8%AF%B4%E6%98%8E.md
223+
// https://github.com/ExistOrLive/GithubClient/blob/master/Document/GithubAction/DailyCI%E8%AF%B4%E6%98%8E.md#certicate
222224
if pathCount >= 5 {
223225
let ref = pathComponents[4]
224226
let paths = Array(pathComponents[5...])
227+
let path = paths.joined(separator: "/")
228+
var fragment = ""
229+
if #available(iOS 16.0, *) {
230+
fragment = url.fragment(percentEncoded: false) ?? ""
231+
} else {
232+
fragment = url.fragment ?? ""
233+
}
225234
pathType = .blob(login: pathComponents[1],
226235
repoName: pathComponents[2],
227-
ref: pathComponents[4],
228-
path: paths.joined(separator: "/"))
236+
ref: ref,
237+
path: path,
238+
fragment: fragment)
229239
}
230240

231241
default:

ZLGitHubClient/ZLGitHubClient/Class/UI/ZLReuseView/ZLReadMeView/ZLReadMeView.swift

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,16 @@ class ZLReadMeView: UIView {
3838
private var serialNumber: String?
3939

4040
var hasRequestData: Bool = false
41+
42+
lazy var linkRouter: ZLGithubMarkDownLinkRouter = {
43+
let linkRouter = ZLGithubMarkDownLinkRouter(needDealWithRelativePath: true,
44+
needDealWithAboutBlank: true,
45+
needDealWithCommonURL: true,
46+
forbidSamePathNavigation: false,
47+
rootRepoHTMLPath: root_html_url(),
48+
markdownHTMLPath: "")
49+
return linkRouter
50+
}()
4151

4252

4353
init() {
@@ -115,6 +125,11 @@ class ZLReadMeView: UIView {
115125
let range1 = (newHtmlStr as NSString).range(of: "<style>")
116126
if range1.location != NSNotFound {
117127
newHtmlStr.insert("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no\"/>", at: range1.location)
128+
129+
if let html_url = readMeModel?.html_url, !html_url.isEmpty {
130+
newHtmlStr.insert("<base href=\"\(html_url)\" target=\"_blank\">", at: range1.location)
131+
}
132+
118133
}
119134

120135
if let cssURL = cssURL {
@@ -259,6 +274,7 @@ extension ZLReadMeView {
259274
}
260275

261276
self.readMeModel = data
277+
self.linkRouter.markdownHTMLPath = data.html_url
262278

263279
if self.webView.isLoading == false
264280
&& self.htmlStr != nil {
@@ -308,34 +324,11 @@ extension ZLReadMeView: WKNavigationDelegate, WKUIDelegate {
308324
}
309325

310326
if navigationAction.navigationType == .linkActivated {
311-
312-
decisionHandler(.cancel)
313-
314-
if ZLCommonURLManager.openURL(urlStr: urlStr) {
315-
return
316-
}
317-
318-
if urlStr.starts(with: "about:blank%23") {
319-
if let range = urlStr.range(of: "about:blank%23") {
320-
urlStr.removeSubrange(range)
321-
let url = URL(string: "\(self.readMeModel?.html_url ?? "")#\(urlStr))")
322-
if self.delegate?.responds(to: #selector(ZLReadMeViewDelegate.onLinkClicked(url:))) ?? false {
323-
self.delegate?.onLinkClicked?(url: url)
324-
}
325-
return
326-
}
327-
}
328-
329-
var url = URL(string: urlStr)
330-
if url?.host == nil {
331-
// 如果是相对路径,组装baseurl
332-
url = (URL.init(string: self.readMeModel?.html_url ?? "") as NSURL?)?.deletingLastPathComponent
333-
url = URL(string: "\(url?.absoluteString ?? "")\(urlStr)")
334-
}
335-
if self.delegate?.responds(to: #selector(ZLReadMeViewDelegate.onLinkClicked(url:))) ?? false {
336-
self.delegate?.onLinkClicked?(url: url)
327+
if linkRouter.dealWithLink(urlStr: urlStr) {
328+
decisionHandler(.cancel)
329+
} else {
330+
decisionHandler(.allow)
337331
}
338-
339332
} else {
340333
decisionHandler(.allow)
341334
}
@@ -366,5 +359,9 @@ extension ZLReadMeView: WKNavigationDelegate, WKUIDelegate {
366359
}
367360
}
368361
}
369-
362+
363+
func root_html_url() -> String {
364+
let html_url = "https://github.com/\(fullName?.urlPathEncoding ?? "")/blob/\(branch?.urlPathEncoding ?? "")"
365+
return html_url
366+
}
370367
}

ZLGitHubClient/ZLGitHubClient/Class/UI/repo/ZLRepoContentController/viewcontroller/ZLRepoCodePreview3Controller.swift

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,19 @@ class ZLRepoCodePreview3Controller: ZMViewController {
2424
@objc var repoFullName: String = ""
2525
@objc var branch: String = ""
2626
@objc var path: String = ""
27+
@objc var fragment: String = ""
2728

2829
var htmlStr: String?
30+
31+
lazy var linkRouter: ZLGithubMarkDownLinkRouter = {
32+
let linkRouter = ZLGithubMarkDownLinkRouter(needDealWithRelativePath: true,
33+
needDealWithAboutBlank: false,
34+
needDealWithCommonURL: true,
35+
forbidSamePathNavigation: true,
36+
rootRepoHTMLPath: root_html_url(),
37+
markdownHTMLPath: html_url())
38+
return linkRouter
39+
}()
2940

3041

3142
@objc init() {
@@ -113,6 +124,11 @@ class ZLRepoCodePreview3Controller: ZMViewController {
113124
return html_url
114125
}
115126

127+
func root_html_url() -> String {
128+
let html_url = "https://github.com/\(repoFullName.urlPathEncoding)/blob/\(branch.urlPathEncoding)"
129+
return html_url
130+
}
131+
116132
func download_url() -> String {
117133
let download_url = "https://raw.githubusercontent.com/\(repoFullName.urlPathEncoding)/\(branch.urlPathEncoding)/\(path.urlPathEncoding)"
118134
return download_url
@@ -289,6 +305,8 @@ extension ZLRepoCodePreview3Controller {
289305
let range1 = (newHtmlStr as NSString).range(of: "<style>")
290306
if range1.location != NSNotFound {
291307
newHtmlStr.insert("<meta name=\"viewport\" content=\"width=device-width\"/>", at: range1.location)
308+
309+
newHtmlStr.insert("<base href=\"\(html_url())\" target=\"_blank\">", at: range1.location)
292310
}
293311

294312
if let tmoCSSURL = cssURL {
@@ -341,41 +359,27 @@ extension ZLRepoCodePreview3Controller: WKUIDelegate, WKNavigationDelegate {
341359
decisionHandler(.allow)
342360
return
343361
}
344-
345-
if navigationAction.navigationType == .linkActivated {
346-
decisionHandler(.cancel)
347-
348-
if ZLCommonURLManager.openURL(urlStr: urlStr) {
349-
return
350-
}
351-
352-
var url = URL(string: urlStr)
353-
if url?.host == nil { // 如果是相对路径,组装baseurl
354-
url = (URL.init(string: html_url()) as NSURL?)?.deletingLastPathComponent
355-
url = URL(string: "\(url?.absoluteString ?? "" )\(urlStr)")
356-
}
357362

358-
guard let appdelegate: AppDelegate = UIApplication.shared.delegate as? AppDelegate else {
359-
return
363+
if navigationAction.navigationType == .linkActivated {
364+
if linkRouter.dealWithLink(urlStr: urlStr) {
365+
decisionHandler(.cancel)
366+
} else {
367+
decisionHandler(.allow)
360368
}
361-
appdelegate.allowRotation = false
362-
363-
self.openURL(url: url)
364369
} else {
365370
decisionHandler(.allow)
366371
}
367372
}
368373

369374
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
370375

371-
let baseURLStr = (URL.init(string: download_url()) as NSURL?)?.deletingLastPathComponent?.absoluteString
372-
let addBaseScript = "let a = '\(baseURLStr ?? "")';let array = document.getElementsByTagName('img');for(i=0;i<array.length;i++){let item=array[i];if(item.getAttribute('src').indexOf('http') == -1){item.src = a + item.getAttribute('src');}}"
373-
374-
webView.evaluateJavaScript(addBaseScript) { (_: Any?, _: Error?) in
375-
376+
let baseURLStr = (URL.init(string: download_url()) as NSURL?)?.deletingLastPathComponent?.absoluteString
377+
let addBaseScript = "let a = '\(baseURLStr ?? "")';let array = document.getElementsByTagName('img');for(i=0;i<array.length;i++){let item=array[i];if(item.getAttribute('src').indexOf('http') == -1){item.src = a + item.getAttribute('src');}}"
378+
379+
webView.evaluateJavaScript(addBaseScript) { (_: Any?, _: Error?) in
376380

377381
}
378-
382+
379383
}
380384

381385
}

0 commit comments

Comments
 (0)