forked from SolidOS/solid-ui
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlabel.ts
More file actions
120 lines (108 loc) · 3.76 KB
/
label.ts
File metadata and controls
120 lines (108 loc) · 3.76 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
116
117
118
119
120
import * as log from '../log'
import { store } from 'solid-logic-jss'
import ns from '../ns'
import * as rdf from 'rdflib' // pull in first avoid cross-refs
const UI = { log, ns, rdf }
// This ubiquitous function returns the best label for a thing
//
// The hacks in this code make a major difference to the usability
export function label (thing, initialCap = false): string {
function doCap (label: string) {
if (initialCap) {
return label.slice(0, 1).toUpperCase() + label.slice(1)
}
return label
}
function cleanUp (label: string) {
let result = ''
if (label.slice(-1) === '/') label = label.slice(0, -1) // chop trailing slash
for (let i = 0; i < label.length; i++) {
if (label[i] === '_' || label[i] === '-') {
result += ' '
continue
}
result += label[i]
if (
i + 1 < label.length &&
label[i].toUpperCase() !== label[i] &&
label[i + 1].toLowerCase() !== label[i + 1]
) {
result += ' '
}
}
if (result.slice(0, 4) === 'has ') result = result.slice(4)
return doCap(result)
}
const label = getWellKnownLabel(thing)
if (label) {
return doCap(label.value)
}
// Default to label just generated from the URI
if (thing.termType === 'BlankNode') {
return '...'
}
if (thing.termType === 'Collection') {
return '(' + thing.elements.length + ')'
}
let s = thing.uri
if (typeof s === 'undefined') return thing.toString() // can't be a symbol
// s = decodeURI(s) // This can crash is random valid @ signs are presentation
// The idea was to clean up eg URIs encoded in query strings
// Also encoded character in what was filenames like @ [] {}
try {
s = s
.split('/')
.map(decodeURIComponent)
.join('/') // If it is properly encoded
} catch (_e) {
// try individual decoding of ASCII code points
for (let i = s.length - 3; i > 0; i--) {
const hex = '0123456789abcefABCDEF' // The while upacks multiple layers of encoding
while (
s[i] === '%' &&
hex.indexOf(s[i + 1]) >= 0 &&
hex.indexOf(s[i + 2]) >= 0
) {
s =
s.slice(0, i) +
String.fromCharCode(parseInt(s.slice(i + 1, i + 3), 16)) +
s.slice(i + 3)
}
}
}
s = slice(s, '/profile/card#me')
s = slice(s, '#this')
s = slice(s, '#me')
const hash = s.indexOf('#')
if (hash >= 0) return cleanUp(s.slice(hash + 1))
// Eh? Why not do this? e.g. dc:title needs it only trim URIs, not rdfs:labels
const slash = s.lastIndexOf('/', s.length - 2) // (len-2) excludes trailing slash
if (slash >= 0 && slash < thing.uri.length) return cleanUp(s.slice(slash + 1))
return doCap(decodeURIComponent(thing.uri))
}
function slice (s: string, suffix: string) {
const length = suffix.length * -1
if (s.slice(length) === suffix) {
return s.slice(0, length)
}
return s
}
// Hard coded known label predicates
// @@ TBD: Add subproperties of rdfs:label
function getWellKnownLabel (thing) {
return store.any(thing, UI.ns.ui('label')) || // Prioritize ui:label
store.any(thing, UI.ns.link('message')) ||
store.any(thing, UI.ns.vcard('fn')) ||
store.any(thing, UI.ns.foaf('name')) ||
store.any(thing, UI.ns.dct('title')) ||
store.any(thing, UI.ns.dc('title')) ||
store.any(thing, UI.ns.rss('title')) ||
store.any(thing, UI.ns.contact('fullName')) ||
store.any(thing, store.sym('http://www.w3.org/2001/04/roadmap/org#name')) ||
store.any(thing, UI.ns.cal('summary')) ||
store.any(thing, UI.ns.foaf('nick')) ||
store.any(thing, UI.ns.as('name')) ||
store.any(thing, UI.ns.schema('name')) ||
store.any(thing, UI.ns.rdfs('label')) ||
store.any(thing, store.sym('http://www.w3.org/2004/02/skos/core#prefLabel'))
}