Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Delta Between Two Patch Sets: FavIcon/IconExtraction.swift

Issue 29664569: Favicon: Issue 6245 - SwiftLinted project files (Closed)
Left Patch Set: Created Jan. 12, 2018, 11:04 a.m.
Right Patch Set: Removed the sorted_imports rule and reversed the import calls to be sorted alphabetically Created Feb. 19, 2018, 10:38 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « FavIcon/FavIcon.swift ('k') | FavIcon/URLRequestOperation.swift » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 // 1 //
2 // FavIcon 2 // FavIcon
3 // Copyright © 2016 Leon Breedt 3 // Copyright © 2016 Leon Breedt
4 // 4 //
5 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License. 6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at 7 // You may obtain a copy of the License at
8 // 8 //
9 // http://www.apache.org/licenses/LICENSE-2.0 9 // http://www.apache.org/licenses/LICENSE-2.0
10 // 10 //
11 // Unless required by applicable law or agreed to in writing, software 11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS, 12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and 14 // See the License for the specific language governing permissions and
15 // limitations under the License. 15 // limitations under the License.
16 // 16 //
17 17
18 import FavIcon.XMLDocument 18 import FavIcon.XMLDocument
19 import Foundation
20 19
21 /// Represents an icon size. 20 /// Represents an icon size.
22 struct IconSize: Hashable, Equatable { 21 struct IconSize: Hashable, Equatable {
23 var hashValue: Int { 22 var hashValue: Int {
24 return width.hashValue ^ height.hashValue 23 return width.hashValue ^ height.hashValue
25 } 24 }
26 25
27 static func == (lhs: IconSize, rhs: IconSize) -> Bool { 26 static func == (lhs: IconSize, rhs: IconSize) -> Bool {
28 return lhs.width == rhs.width && lhs.height == rhs.height 27 return lhs.width == rhs.width && lhs.height == rhs.height
29 } 28 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 // swiftlint:disable function_body_length 62 // swiftlint:disable function_body_length
64 // swiftlint:disable cyclomatic_complexity 63 // swiftlint:disable cyclomatic_complexity
65 func examineHTMLMeta(_ document: HTMLDocument, baseURL: URL) -> [String: String] { 64 func examineHTMLMeta(_ document: HTMLDocument, baseURL: URL) -> [String: String] {
66 var resp: [String: String] = [:] 65 var resp: [String: String] = [:]
67 for meta in document.query("/html/head/meta") { 66 for meta in document.query("/html/head/meta") {
68 if let property = meta.attributes["property"]?.lowercased(), 67 if let property = meta.attributes["property"]?.lowercased(),
69 let content = meta.attributes["content"] { 68 let content = meta.attributes["content"] {
70 switch property { 69 switch property {
71 case "og:url": 70 case "og:url":
72 resp["og:url"] = content 71 resp["og:url"] = content
73 break
74 case "og:description": 72 case "og:description":
75 resp["description"] = content 73 resp["description"] = content
76 break
77 case "og:image": 74 case "og:image":
78 resp["image"] = content 75 resp["image"] = content
79 break
80 case "og:title": 76 case "og:title":
81 resp["title"] = content 77 resp["title"] = content
82 break
83 case "og:site_name": 78 case "og:site_name":
84 resp["site_name"] = content 79 resp["site_name"] = content
85 break
86 default: 80 default:
87 break 81 break
88 } 82 }
89 } 83 }
90 if let name = meta.attributes["name"]?.lowercased(), 84 if let name = meta.attributes["name"]?.lowercased(),
91 let content = meta.attributes["content"], 85 let content = meta.attributes["content"],
92 name == "description" { 86 name == "description" {
93 resp["description"] = resp["description"] ?? content 87 resp["description"] = resp["description"] ?? content
94 } 88 }
95 } 89 }
96 90
97 for title in document.query("/html/head/title") { 91 for title in document.query("/html/head/title") {
98 if let titleString = title.contents { 92 if let titleString = title.contents {
99 resp["title"] = resp["title"] ?? titleString 93 resp["title"] = resp["title"] ?? titleString
100 } 94 }
101 } 95 }
102 96
103 for link in document.query("/html/head/link") { 97 for link in document.query("/html/head/link") {
104 if let rel = link.attributes["rel"], 98 if let rel = link.attributes["rel"],
105 let href = link.attributes["href"], 99 let href = link.attributes["href"],
106 let url = URL(string: href, relativeTo: baseURL) { 100 let url = URL(string: href, relativeTo: baseURL) {
107 switch rel.lowercased() { 101 switch rel.lowercased() {
108 case "canonical": 102 case "canonical":
109 resp["canonical"] = url.absoluteString 103 resp["canonical"] = url.absoluteString
110 break
111 case "amphtml": 104 case "amphtml":
112 resp["amphtml"] = url.absoluteString 105 resp["amphtml"] = url.absoluteString
113 break
114 case "search": 106 case "search":
115 resp["search"] = url.absoluteString 107 resp["search"] = url.absoluteString
116 break
117 case "fluid-icon": 108 case "fluid-icon":
118 resp["fluid-icon"] = url.absoluteString 109 resp["fluid-icon"] = url.absoluteString
119 break
120 case "alternate": 110 case "alternate":
121 let application = link.attributes["application"] 111 let application = link.attributes["application"]
122 if application == "application/atom+xml" { 112 if application == "application/atom+xml" {
123 resp["atom"] = url.absoluteString 113 resp["atom"] = url.absoluteString
124 } 114 }
125 break
126 default: 115 default:
127 break 116 break
128 } 117 }
129 } 118 }
130 } 119 }
131 return resp 120 return resp
132 } 121 }
133 122
134 func extractHTMLHeadIcons(_ document: HTMLDocument, baseURL: URL) -> [DetectedIc on] { 123 func extractHTMLHeadIcons(_ document: HTMLDocument, baseURL: URL) -> [DetectedIc on] {
135 var icons: [DetectedIcon] = [] 124 var icons: [DetectedIcon] = []
136 125
137 for link in document.query("/html/head/link") { 126 for link in document.query("/html/head/link") {
138 if let rel = link.attributes["rel"], 127 if let rel = link.attributes["rel"],
139 let href = link.attributes["href"], 128 let href = link.attributes["href"],
140 let url = URL(string: href, relativeTo: baseURL) { 129 let url = URL(string: href, relativeTo: baseURL) {
141 switch rel.lowercased() { 130 switch rel.lowercased() {
142 case "shortcut icon": 131 case "shortcut icon":
143 icons.append(DetectedIcon(url: url.absoluteURL, type: .shortcut) ) 132 icons.append(DetectedIcon(url: url.absoluteURL, type: .shortcut) )
144 break
145 case "icon": 133 case "icon":
146 if let type = link.attributes["type"], type.lowercased() == "ima ge/png" { 134 if let type = link.attributes["type"], type.lowercased() == "ima ge/png" {
147 let sizes = parseHTMLIconSizes(link.attributes["sizes"]) 135 let sizes = parseHTMLIconSizes(link.attributes["sizes"])
148 if sizes.count > 0 { 136 if sizes.count > 0 {
149 for size in sizes { 137 for size in sizes {
150 if let type = kRelIconTypeMap[size] { 138 if let type = kRelIconTypeMap[size] {
151 icons.append(DetectedIcon(url: url, 139 icons.append(DetectedIcon(url: url,
152 type: type, 140 type: type,
153 width: size.width, 141 width: size.width,
154 height: size.height)) 142 height: size.height))
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 /// - returns: An array of `DetectedIcon` structures. 236 /// - returns: An array of `DetectedIcon` structures.
249 func extractBrowserConfigXMLIcons(_ document: LBXMLDocument, baseURL: URL) -> [D etectedIcon] { 237 func extractBrowserConfigXMLIcons(_ document: LBXMLDocument, baseURL: URL) -> [D etectedIcon] {
250 var icons: [DetectedIcon] = [] 238 var icons: [DetectedIcon] = []
251 239
252 for tile in document.query("/browserconfig/msapplication/tile/*") { 240 for tile in document.query("/browserconfig/msapplication/tile/*") {
253 if let src = tile.attributes["src"], 241 if let src = tile.attributes["src"],
254 let url = URL(string: src, relativeTo: baseURL)?.absoluteURL { 242 let url = URL(string: src, relativeTo: baseURL)?.absoluteURL {
255 switch tile.name.lowercased() { 243 switch tile.name.lowercased() {
256 case "tileimage": 244 case "tileimage":
257 icons.append(DetectedIcon(url: url, type: .microsoftPinnedSite, width: 144, height: 144)) 245 icons.append(DetectedIcon(url: url, type: .microsoftPinnedSite, width: 144, height: 144))
258 break
259 case "square70x70logo": 246 case "square70x70logo":
260 icons.append(DetectedIcon(url: url, type: .microsoftPinnedSite, width: 70, height: 70)) 247 icons.append(DetectedIcon(url: url, type: .microsoftPinnedSite, width: 70, height: 70))
261 break
262 case "square150x150logo": 248 case "square150x150logo":
263 icons.append(DetectedIcon(url: url, type: .microsoftPinnedSite, width: 150, height: 150)) 249 icons.append(DetectedIcon(url: url, type: .microsoftPinnedSite, width: 150, height: 150))
264 break
265 case "wide310x150logo": 250 case "wide310x150logo":
266 icons.append(DetectedIcon(url: url, type: .microsoftPinnedSite, width: 310, height: 150)) 251 icons.append(DetectedIcon(url: url, type: .microsoftPinnedSite, width: 310, height: 150))
267 break
268 case "square310x310logo": 252 case "square310x310logo":
269 icons.append(DetectedIcon(url: url, type: .microsoftPinnedSite, width: 310, height: 310)) 253 icons.append(DetectedIcon(url: url, type: .microsoftPinnedSite, width: 310, height: 310))
270 break
271 default: 254 default:
272 break 255 break
273 } 256 }
274 } 257 }
275 } 258 }
276 259
277 return icons 260 return icons
278 } 261 }
279 262
280 /// Extracts the Web App Manifest URLs from an HTML document, if any. 263 /// Extracts the Web App Manifest URLs from an HTML document, if any.
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 for size in string.components(separatedBy: .whitespaces) { 307 for size in string.components(separatedBy: .whitespaces) {
325 let parts = size.components(separatedBy: "x") 308 let parts = size.components(separatedBy: "x")
326 if parts.count != 2 { continue } 309 if parts.count != 2 { continue }
327 if let width = Int(parts[0]), let height = Int(parts[1]) { 310 if let width = Int(parts[0]), let height = Int(parts[1]) {
328 sizes.append(IconSize(width: width, height: height)) 311 sizes.append(IconSize(width: width, height: height))
329 } 312 }
330 } 313 }
331 } 314 }
332 return sizes 315 return sizes
333 } 316 }
LEFTRIGHT

Powered by Google App Engine
This is Rietveld