-
Notifications
You must be signed in to change notification settings - Fork 83
Expand file tree
/
Copy pathtab-for-urls-with-title-and-icon.ini
More file actions
115 lines (94 loc) · 3.1 KB
/
Copy pathtab-for-urls-with-title-and-icon.ini
File metadata and controls
115 lines (94 loc) · 3.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
[Command]
Automatic=true
Command="
copyq:
var tabName = '&URLs';
function lower(data) {
return str(data).toLowerCase()
}
function findHeader(reply, headerName) {
reply.data // fetches data and headers
var headers = reply.headers
for (var i in headers) {
var header = headers[i]
if (lower(header[0]) === headerName)
return header[1]
}
return ''
}
function fetchContent(url, maxRedirects) {
if (maxRedirects === undefined)
maxRedirects = 4
serverLog('Fetching: ' + url)
var reply = networkGet(url)
if (maxRedirects == 0)
return reply
var header = findHeader(reply, 'location')
if (header)
return fetchContent(header, maxRedirects - 1)
return reply
}
function decodeHtml(html) {
return html.replace(/&#(\\d+);/g, function(match, charCode) {
return String.fromCharCode(charCode);
});
}
function isHtml(reply) {
var headers = reply.headers
for (var i in headers) {
var header = headers[i]
if (lower(header[0]) === 'content-type')
return lower(header[1]).indexOf(mimeHtml) === 0
}
return false
}
function grep(content, re) {
return content ? (re.exec(content) || [])[1] : ''
}
function getTitle(content) {
var title = grep(content, /<title[^>]*>([^<]*)<\\/title>/i)
return title ? decodeHtml(title.trim()) : ''
}
function getFavicon(content) {
var iconLine = grep(content, /<link([^>]*rel=[\"'](?:shortcut )?icon[\"'][^>]*)/i)
var icon = grep(iconLine, /href=[\"']([^\"']*)/i)
if (!icon)
return ''
// Icon path can be complete URL.
if (icon.indexOf('://') != -1)
return fetchContent(icon).data
// Icon path can be missing protocol.
if (icon.substr(0, 2) === '//') {
var i = url.search(/\\/\\//)
var protocol = (i == -1) ? 'http:' : url.substr(0, i)
return fetchContent(protocol + icon).data
}
// Icon path can be relative to host URL.
if (icon[0] === '/') {
var baseUrl = url.substr(0, url.search(/[^\\/:](\\/|$)/) + 1)
return fetchContent(baseUrl + icon).data
}
// Icon path can be relative to current URL.
var baseUrl = url.substr(0, url.lastIndexOf('/') + 1)
return fetchContent(baseUrl + icon).data
}
var url = str(input()).trim()
serverLog('Fetching icon and title: ' + url)
// URL already added? (Just check the top of the list.)
if (url === str(read(0)))
abort()
// Fetch HTML.
var reply = fetchContent(url)
if (!isHtml(reply))
abort()
var content = str(reply.data)
var title = getTitle(content)
var icon = getFavicon(content)
setData(mimeText, url)
setData(mimeItemNotes, title || '')
setData(mimeIcon, icon)
setData(mimeOutputTab, tabName)"
Icon=\xf0c1
Input=text/plain
Match=^https?://
Name=Tab for URLs with Title and Icon