-
Notifications
You must be signed in to change notification settings - Fork 52
Expand file tree
/
Copy pathRDFXMLPane.ts
More file actions
134 lines (113 loc) · 3.77 KB
/
Copy pathRDFXMLPane.ts
File metadata and controls
134 lines (113 loc) · 3.77 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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/* RDF/XML content Pane
**
** This pane shows the content of a particular RDF resource
** or at least the RDF semantics we attribute to that resource,
** in generated N3 syntax.
*/
import * as UI from 'solid-ui'
import * as $rdf from 'rdflib'
import type { DataBrowserContext, RenderEnvironment } from 'pane-registry'
import type { NamedNode, Statement } from 'rdflib'
import './RDFXMLPane.css'
import { lucideIcons } from './icons/lucide'
const ns = UI.ns
type RDFXMLPaneDefinition = {
icon: string
name: string
audience: NamedNode[]
label: (subject: NamedNode, context: DataBrowserContext) => string | null
render: (subject: NamedNode, context: DataBrowserContext) => HTMLDivElement
}
function leadingIndentWidth (line: string): number {
if (line.trim().length === 0) {
return 0
}
let width = 0
for (const character of line) {
if (character === ' ') {
width += 1
continue
}
if (character === '\t') {
width += 2
continue
}
break
}
return Math.max(width, 2)
}
function trimLeadingIndent (line: string): string {
return line.replace(/^[ \t]+/, '')
}
export const RDFXMLPane: RDFXMLPaneDefinition = {
icon: lucideIcons.code,
name: 'RDFXML',
audience: [ns.solid('Developer')],
label: function (subject: NamedNode, context: DataBrowserContext): string | null {
const store = context.session.store
if (
'http://www.w3.org/2007/ont/link#ProtocolEvent' in
store.findTypeURIs(subject)
) {
return null
}
const n = store.statementsMatching(undefined, undefined, undefined, subject)
.length
if (n === 0) return null
return 'As RDF/XML (' + n + ')'
},
render: function (
subject: NamedNode,
context: DataBrowserContext
): HTMLDivElement {
const myDocument = context.dom
const kb = context.session.store
function applyEnvironmentAttributes (element: HTMLDivElement): void {
const environment = (context.environment ?? {}) as Partial<RenderEnvironment>
element.dataset.layout = environment.layout ?? 'desktop'
}
const div = myDocument.createElement('div')
div.setAttribute('class', 'rdfxml-pane')
applyEnvironmentAttributes(div)
// Because of smushing etc, this will not be a copy of the original source
// We could instead either fetch and re-parse the source,
// or we could keep all the pre-smushed triples.
const sts = kb.statementsMatching(
undefined,
undefined,
undefined,
subject
) as Statement[] // @@ slow with current store!
/*
var kludge = kb.formula([]) // No features
for (var i=0; i< sts.length; i++) {
s = sts[i]
kludge.add(s.subject, s.predicate, s.object)
}
*/
const sz = $rdf.Serializer(kb)
sz.suggestNamespaces(kb.namespaces)
sz.setBase(subject.uri)
const str = sz.statementsToXML(sts)
const source = myDocument.createElement('div')
source.classList.add('rdfxml-pane__source')
str.split('\n').forEach(line => {
const lineElement = myDocument.createElement('div')
const indentElement = myDocument.createElement('span')
const contentElement = myDocument.createElement('span')
const indentWidth = leadingIndentWidth(line)
lineElement.classList.add('rdfxml-pane__line')
lineElement.style.setProperty('--rdfxml-indent', `${indentWidth}ch`)
indentElement.classList.add('rdfxml-pane__line-indent')
indentElement.setAttribute('aria-hidden', 'true')
contentElement.classList.add('rdfxml-pane__line-content')
contentElement.textContent = line.length > 0 ? trimLeadingIndent(line) : ' '
lineElement.appendChild(indentElement)
lineElement.appendChild(contentElement)
source.appendChild(lineElement)
})
div.appendChild(source)
return div
}
}
// ends