@oml/markdown 0.10.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/out/md/md-execution.d.ts +16 -0
- package/out/md/md-executor.d.ts +1 -0
- package/out/md/md-executor.js +219 -35
- package/out/md/md-executor.js.map +1 -1
- package/out/renderers/chart-renderer.js +72 -4
- package/out/renderers/chart-renderer.js.map +1 -1
- package/out/renderers/diagram-renderer.js +896 -245
- package/out/renderers/diagram-renderer.js.map +1 -1
- package/out/renderers/graph-renderer.js +452 -18
- package/out/renderers/graph-renderer.js.map +1 -1
- package/out/renderers/matrix-renderer.d.ts +0 -2
- package/out/renderers/matrix-renderer.js +45 -40
- package/out/renderers/matrix-renderer.js.map +1 -1
- package/out/renderers/renderer.d.ts +4 -1
- package/out/renderers/renderer.js +98 -0
- package/out/renderers/renderer.js.map +1 -1
- package/out/renderers/table-renderer.d.ts +12 -2
- package/out/renderers/table-renderer.js +126 -39
- package/out/renderers/table-renderer.js.map +1 -1
- package/out/renderers/types.d.ts +16 -0
- package/out/renderers/wikilink-utils.d.ts +1 -0
- package/out/renderers/wikilink-utils.js +60 -32
- package/out/renderers/wikilink-utils.js.map +1 -1
- package/out/static/browser-runtime.bundle.js +8011 -1292
- package/out/static/browser-runtime.bundle.js.map +4 -4
- package/out/static/browser-runtime.js +15 -2
- package/out/static/browser-runtime.js.map +1 -1
- package/package.json +2 -2
- package/src/md/md-execution.ts +20 -0
- package/src/md/md-executor.ts +268 -40
- package/src/renderers/chart-renderer.ts +93 -2
- package/src/renderers/diagram-renderer.ts +964 -253
- package/src/renderers/graph-renderer.ts +512 -12
- package/src/renderers/matrix-renderer.ts +57 -44
- package/src/renderers/renderer.ts +105 -1
- package/src/renderers/table-renderer.ts +190 -41
- package/src/renderers/types.ts +20 -0
- package/src/renderers/wikilink-utils.ts +66 -31
- package/src/static/browser-runtime.ts +20 -2
- package/src/static/markdown-webview.css +44 -15
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// Copyright (c) 2026 Modelware. All rights reserved.
|
|
2
|
+
import { appendInlineValue, createWikiLinkElement, isUrlValue, shortLabelFromIri } from './wikilink-utils.js';
|
|
2
3
|
let iriLabelSnapshot;
|
|
3
4
|
export function setIriLabelSnapshot(snapshot) {
|
|
4
5
|
if (!snapshot) {
|
|
@@ -88,6 +89,41 @@ export class BaseMarkdownBlockRenderer {
|
|
|
88
89
|
}
|
|
89
90
|
}
|
|
90
91
|
export class QueryMarkdownBlockRenderer extends BaseMarkdownBlockRenderer {
|
|
92
|
+
renderCellValue(raw, typedValue) {
|
|
93
|
+
const value = document.createElement('span');
|
|
94
|
+
value.className = 'table-value';
|
|
95
|
+
const entries = typedValue?.values ?? [];
|
|
96
|
+
if (entries.length > 0) {
|
|
97
|
+
entries.forEach((entry, index) => {
|
|
98
|
+
if (index > 0) {
|
|
99
|
+
value.appendChild(document.createTextNode(' '));
|
|
100
|
+
}
|
|
101
|
+
value.appendChild(this.renderValueToken(entry));
|
|
102
|
+
});
|
|
103
|
+
return value;
|
|
104
|
+
}
|
|
105
|
+
const display = this.formatCellDisplayText(raw, typedValue);
|
|
106
|
+
const fragment = document.createElement('span');
|
|
107
|
+
fragment.className = 'table-value-part';
|
|
108
|
+
fragment.dataset.value = display;
|
|
109
|
+
appendInlineValue(fragment, display);
|
|
110
|
+
value.appendChild(fragment);
|
|
111
|
+
return value;
|
|
112
|
+
}
|
|
113
|
+
formatCellDisplayText(raw, typedValue) {
|
|
114
|
+
if (typedValue?.values?.length) {
|
|
115
|
+
return typedValue.values.map((entry) => {
|
|
116
|
+
if (entry.kind === 'iri') {
|
|
117
|
+
return shortLabelFromIri(entry.value);
|
|
118
|
+
}
|
|
119
|
+
if (entry.kind === 'bnode') {
|
|
120
|
+
return `_:${entry.value}`;
|
|
121
|
+
}
|
|
122
|
+
return entry.value;
|
|
123
|
+
}).join(' ');
|
|
124
|
+
}
|
|
125
|
+
return raw;
|
|
126
|
+
}
|
|
91
127
|
getBlockSource(result) {
|
|
92
128
|
return result.blockSource;
|
|
93
129
|
}
|
|
@@ -97,6 +133,33 @@ export class QueryMarkdownBlockRenderer extends BaseMarkdownBlockRenderer {
|
|
|
97
133
|
getBlockRange(result) {
|
|
98
134
|
return { start: result.blockLineStart, end: result.blockLineEnd };
|
|
99
135
|
}
|
|
136
|
+
renderValueToken(entry) {
|
|
137
|
+
const fragment = document.createElement('span');
|
|
138
|
+
fragment.className = 'table-value-part';
|
|
139
|
+
fragment.dataset.value = entry.value;
|
|
140
|
+
if (entry.kind === 'iri') {
|
|
141
|
+
if (isBuiltInOntologyIri(entry.value)) {
|
|
142
|
+
appendInlineValue(fragment, shortLabelFromIri(entry.value));
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
fragment.appendChild(createWikiLinkElement(entry.value, shortLabelFromIri(entry.value)));
|
|
146
|
+
}
|
|
147
|
+
return fragment;
|
|
148
|
+
}
|
|
149
|
+
if (entry.kind === 'bnode') {
|
|
150
|
+
appendInlineValue(fragment, `_:${entry.value}`);
|
|
151
|
+
return fragment;
|
|
152
|
+
}
|
|
153
|
+
if (isUrlValue(entry.value)) {
|
|
154
|
+
const link = document.createElement('a');
|
|
155
|
+
link.href = entry.value;
|
|
156
|
+
link.textContent = entry.value;
|
|
157
|
+
fragment.appendChild(link);
|
|
158
|
+
return fragment;
|
|
159
|
+
}
|
|
160
|
+
appendInlineValue(fragment, entry.value);
|
|
161
|
+
return fragment;
|
|
162
|
+
}
|
|
100
163
|
}
|
|
101
164
|
export class CanvasMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
102
165
|
canRender(result) {
|
|
@@ -111,4 +174,39 @@ export class CanvasMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
|
111
174
|
return container;
|
|
112
175
|
}
|
|
113
176
|
}
|
|
177
|
+
const BUILT_IN_ONTOLOGY_IRIS = new Set([
|
|
178
|
+
'http://opencaesar.io/oml',
|
|
179
|
+
'http://www.w3.org/2001/XMLSchema',
|
|
180
|
+
'http://www.w3.org/1999/02/22-rdf-syntax-ns',
|
|
181
|
+
'http://www.w3.org/2000/01/rdf-schema',
|
|
182
|
+
'http://www.w3.org/2002/07/owl',
|
|
183
|
+
'http://www.w3.org/2003/11/swrl',
|
|
184
|
+
'http://www.w3.org/2003/11/swrlb',
|
|
185
|
+
]);
|
|
186
|
+
function ontologyLookupKeyFromIri(value) {
|
|
187
|
+
const iri = String(value ?? '').trim().replace(/^<|>$/g, '');
|
|
188
|
+
if (!iri || !/^[A-Za-z][A-Za-z0-9+.-]*:[^\s]+$/.test(iri)) {
|
|
189
|
+
return undefined;
|
|
190
|
+
}
|
|
191
|
+
const hashIndex = iri.indexOf('#');
|
|
192
|
+
if (hashIndex >= 0) {
|
|
193
|
+
return normalizeOntologyLookupKey(iri.slice(0, hashIndex + 1));
|
|
194
|
+
}
|
|
195
|
+
const schemeIndex = iri.indexOf('://');
|
|
196
|
+
const slashIndex = iri.lastIndexOf('/');
|
|
197
|
+
if (slashIndex > schemeIndex + 2) {
|
|
198
|
+
return normalizeOntologyLookupKey(iri.slice(0, slashIndex + 1));
|
|
199
|
+
}
|
|
200
|
+
return normalizeOntologyLookupKey(iri);
|
|
201
|
+
}
|
|
202
|
+
function normalizeOntologyLookupKey(value) {
|
|
203
|
+
return value.trim().replace(/^<|>$/g, '').replace(/[\/#]+$/, '');
|
|
204
|
+
}
|
|
205
|
+
function isBuiltInOntologyIri(iri) {
|
|
206
|
+
const key = ontologyLookupKeyFromIri(iri);
|
|
207
|
+
if (!key) {
|
|
208
|
+
return false;
|
|
209
|
+
}
|
|
210
|
+
return BUILT_IN_ONTOLOGY_IRIS.has(normalizeOntologyLookupKey(key));
|
|
211
|
+
}
|
|
114
212
|
//# sourceMappingURL=renderer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderer.js","sourceRoot":"","sources":["../../src/renderers/renderer.ts"],"names":[],"mappings":"AAAA,qDAAqD;
|
|
1
|
+
{"version":3,"file":"renderer.js","sourceRoot":"","sources":["../../src/renderers/renderer.ts"],"names":[],"mappings":"AAAA,qDAAqD;AAGrD,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAO9G,IAAI,gBAAyD,CAAC;AAE9D,MAAM,UAAU,mBAAmB,CAAC,QAA+D;IAC/F,IAAI,CAAC,QAAQ,EAAE,CAAC;QACZ,gBAAgB,GAAG,SAAS,CAAC;QAC7B,OAAO;IACX,CAAC;IACD,IAAI,QAAQ,YAAY,GAAG,EAAE,CAAC;QAC1B,gBAAgB,GAAG,QAAQ,CAAC;QAC5B,OAAO;IACX,CAAC;IACD,gBAAgB,GAAG,IAAI,GAAG,CACtB,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,oBAAoB,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAU,CAAC,CACtG,CAAC;AACN,CAAC;AAED,MAAM,UAAU,uBAAuB,CACnC,QAA0E,EAC1E,MAAe;IAEf,MAAM,QAAQ,GAAG,gBAAgB,CAAC;IAClC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IAC9B,IAAI,CAAC;QACD,OAAO,MAAM,EAAE,CAAC;IACpB,CAAC;YAAS,CAAC;QACP,gBAAgB,GAAG,QAAQ,CAAC;IAChC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,GAAW;IAC3C,MAAM,UAAU,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC;IAC7C,IAAI,CAAC,UAAU,EAAE,CAAC;QACd,OAAO,GAAG,CAAC;IACf,CAAC;IAED,MAAM,OAAO,GAAG,gBAAgB,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;IAClD,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpD,OAAO,OAAO,CAAC;IACnB,CAAC;IAED,MAAM,aAAa,GAAG,UAAU,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAClD,IAAI,aAAa,IAAI,CAAC,IAAI,aAAa,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9D,OAAO,qBAAqB,CAAC,UAAU,CAAC,KAAK,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC,CAAC;IACtE,CAAC;IAED,MAAM,YAAY,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,UAAU,CAAC;IACjF,MAAM,UAAU,GAAG,YAAY,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACjD,IAAI,UAAU,IAAI,CAAC,IAAI,UAAU,GAAG,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1D,OAAO,qBAAqB,CAAC,YAAY,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC;IACrE,CAAC;IAED,OAAO,UAAU,CAAC;AACtB,CAAC;AAED,SAAS,oBAAoB,CAAC,GAAW;IACrC,OAAO,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;AAC1D,CAAC;AAED,SAAS,qBAAqB,CAAC,KAAa;IACxC,IAAI,CAAC;QACD,OAAO,kBAAkB,CAAC,KAAK,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,KAAK,CAAC;IACjB,CAAC;AACL,CAAC;AAKD,MAAM,OAAgB,yBAAyB;IAIjC,qBAAqB,CAAC,MAAwC;QACpE,MAAM,SAAS,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAChD,SAAS,CAAC,SAAS,GAAG,+BAA+B,MAAM,EAAE,CAAC;QAC9D,OAAO,SAAS,CAAC;IACrB,CAAC;IAES,sBAAsB,CAAC,IAAY;QACzC,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC9C,OAAO,CAAC,SAAS,GAAG,uBAAuB,CAAC;QAC5C,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;QAC3B,OAAO,OAAO,CAAC;IACnB,CAAC;IAES,uBAAuB,CAAC,OAAe,EAAE,YAAY,GAAG,UAAU,EAAE,aAAa,GAAG,KAAK;QAC/F,MAAM,QAAQ,GAAG,IAAI,CAAC,qBAAqB,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;QACzE,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,kBAAkB,EAAE;YAC9C,MAAM,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE;SAChC,CAAC,CAAC;QACH,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC;IAEO,qBAAqB,CAAC,YAAoB,EAAE,aAAqB;QACrE,MAAM,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAC;QACtE,IAAI,QAAQ,GAAG,YAAY,CAAC;QAC5B,IAAI,SAAS,EAAE,CAAC;YACZ,MAAM,QAAQ,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;YAClD,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;YAClD,IAAI,QAAQ,EAAE,CAAC;gBACX,QAAQ,GAAG,QAAQ,CAAC;YACxB,CAAC;QACL,CAAC;QACD,MAAM,SAAS,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAChD,MAAM,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QAC1D,MAAM,SAAS,GAAG,aAAa,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,KAAK,CAAC;QAC5D,OAAO,GAAG,SAAS,IAAI,EAAE,IAAI,SAAS,EAAE,CAAC;IAC7C,CAAC;CACJ;AAED,MAAM,OAAgB,0BAA2B,SAAQ,yBAAyB;IACpE,eAAe,CAAC,GAAW,EAAE,UAAwB;QAC3D,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAC7C,KAAK,CAAC,SAAS,GAAG,aAAa,CAAC;QAChC,MAAM,OAAO,GAAG,UAAU,EAAE,MAAM,IAAI,EAAE,CAAC;QACzC,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;gBAC7B,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;oBACZ,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC;gBACpD,CAAC;gBACD,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC;YACpD,CAAC,CAAC,CAAC;YACH,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,qBAAqB,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QAC5D,MAAM,QAAQ,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAChD,QAAQ,CAAC,SAAS,GAAG,kBAAkB,CAAC;QACxC,QAAQ,CAAC,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC;QACjC,iBAAiB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACrC,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;QAC5B,OAAO,KAAK,CAAC;IACjB,CAAC;IAES,qBAAqB,CAAC,GAAW,EAAE,UAAwB;QACjE,IAAI,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;YAC7B,OAAO,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;gBACnC,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;oBACvB,OAAO,iBAAiB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;gBAC1C,CAAC;gBACD,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;oBACzB,OAAO,KAAK,KAAK,CAAC,KAAK,EAAE,CAAC;gBAC9B,CAAC;gBACD,OAAO,KAAK,CAAC,KAAK,CAAC;YACvB,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACjB,CAAC;QACD,OAAO,GAAG,CAAC;IACf,CAAC;IAES,cAAc,CAAC,MAA8B;QACnD,OAAO,MAAM,CAAC,WAAW,CAAC;IAC9B,CAAC;IAES,YAAY,CAAC,MAA8B;QACjD,OAAO,MAAM,CAAC,SAAS,CAAC;IAC5B,CAAC;IAES,aAAa,CAAC,MAA8B;QAClD,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,cAAc,EAAE,GAAG,EAAE,MAAM,CAAC,YAAY,EAAE,CAAC;IACtE,CAAC;IAEO,gBAAgB,CAAC,KAAuB;QAC5C,MAAM,QAAQ,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAChD,QAAQ,CAAC,SAAS,GAAG,kBAAkB,CAAC;QACxC,QAAQ,CAAC,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;QACrC,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;YACvB,IAAI,oBAAoB,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;gBACpC,iBAAiB,CAAC,QAAQ,EAAE,iBAAiB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;YAChE,CAAC;iBAAM,CAAC;gBACJ,QAAQ,CAAC,WAAW,CAAC,qBAAqB,CAAC,KAAK,CAAC,KAAK,EAAE,iBAAiB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAC7F,CAAC;YACD,OAAO,QAAQ,CAAC;QACpB,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YACzB,iBAAiB,CAAC,QAAQ,EAAE,KAAK,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;YAChD,OAAO,QAAQ,CAAC;QACpB,CAAC;QACD,IAAI,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;YACzC,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC;YACxB,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC;YAC/B,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;YAC3B,OAAO,QAAQ,CAAC;QACpB,CAAC;QACD,iBAAiB,CAAC,QAAQ,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;QACzC,OAAO,QAAQ,CAAC;IACpB,CAAC;CACJ;AAED,MAAM,OAAgB,2BAA4B,SAAQ,0BAA0B;IAGhF,SAAS,CAAC,MAA8B;QACpC,OAAO,MAAM,CAAC,MAAM,KAAK,IAAI;eACtB,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAuB,CAAC,CAAC;IACrE,CAAC;IAES,oBAAoB,CAAC,MAA8B;QACzD,MAAM,SAAS,GAAG,IAAI,CAAC,qBAAqB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC5D,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;QAC3C,MAAM,UAAU,GAAG,MAAM,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,8CAA8C,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5G,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,sBAAsB,CAAC,iBAAiB,MAAM,CAAC,IAAI,4BAA4B,UAAU,EAAE,CAAC,CAAC,CAAC;QACzH,OAAO,SAAS,CAAC;IACrB,CAAC;CACJ;AAED,MAAM,sBAAsB,GAAG,IAAI,GAAG,CAAC;IACnC,0BAA0B;IAC1B,kCAAkC;IAClC,4CAA4C;IAC5C,sCAAsC;IACtC,+BAA+B;IAC/B,gCAAgC;IAChC,iCAAiC;CACpC,CAAC,CAAC;AAEH,SAAS,wBAAwB,CAAC,KAAa;IAC3C,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAC7D,IAAI,CAAC,GAAG,IAAI,CAAC,kCAAkC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACxD,OAAO,SAAS,CAAC;IACrB,CAAC;IACD,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACnC,IAAI,SAAS,IAAI,CAAC,EAAE,CAAC;QACjB,OAAO,0BAA0B,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC;IACnE,CAAC;IACD,MAAM,WAAW,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACvC,MAAM,UAAU,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACxC,IAAI,UAAU,GAAG,WAAW,GAAG,CAAC,EAAE,CAAC;QAC/B,OAAO,0BAA0B,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC;IACpE,CAAC;IACD,OAAO,0BAA0B,CAAC,GAAG,CAAC,CAAC;AAC3C,CAAC;AAED,SAAS,0BAA0B,CAAC,KAAa;IAC7C,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;AACrE,CAAC;AAED,SAAS,oBAAoB,CAAC,GAAW;IACrC,MAAM,GAAG,GAAG,wBAAwB,CAAC,GAAG,CAAC,CAAC;IAC1C,IAAI,CAAC,GAAG,EAAE,CAAC;QACP,OAAO,KAAK,CAAC;IACjB,CAAC;IACD,OAAO,sBAAsB,CAAC,GAAG,CAAC,0BAA0B,CAAC,GAAG,CAAC,CAAC,CAAC;AACvE,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { QueryMarkdownBlockRenderer, type TableBlockKind } from './renderer.js';
|
|
2
|
-
import type { MdBlockExecutionResult } from './types.js';
|
|
2
|
+
import type { MdBlockExecutionResult, MdTableCell } from './types.js';
|
|
3
3
|
type TableEditorActionKind = 'add' | 'remove' | 'validate' | 'link' | 'undo' | 'redo' | 'ai' | 'properties';
|
|
4
4
|
type TableEditorActionContext = {
|
|
5
5
|
action: TableEditorActionKind;
|
|
@@ -48,7 +48,7 @@ export declare class TableMarkdownBlockRenderer extends QueryMarkdownBlockRender
|
|
|
48
48
|
protected shouldIgnoreRowDoubleClick(_event: MouseEvent): boolean;
|
|
49
49
|
protected onRowDoubleClick(_context: Omit<TableEditorActionContext, 'action'>): void;
|
|
50
50
|
protected dispatchTableEditorAction(context: TableEditorActionContext): void;
|
|
51
|
-
protected renderInteractiveTable(columns: string[], rows: string[][], stylesheet: CompiledTableStyleRule[], options: Record<string, unknown> | undefined, blockSource?: string): HTMLElement;
|
|
51
|
+
protected renderInteractiveTable(columns: string[], rows: string[][], rowsTyped: MdTableCell[][] | undefined, stylesheet: CompiledTableStyleRule[], options: Record<string, unknown> | undefined, blockSource?: string, blockId?: string): HTMLElement;
|
|
52
52
|
protected extractTypeOptions(_blockSource: string | undefined): string[];
|
|
53
53
|
private resolveTreeSourceRows;
|
|
54
54
|
private filterTreeRowsBySearch;
|
|
@@ -58,6 +58,7 @@ export declare class TableMarkdownBlockRenderer extends QueryMarkdownBlockRender
|
|
|
58
58
|
private renderTreeCell;
|
|
59
59
|
private createTreeActionButton;
|
|
60
60
|
private applyFiltersAndSorting;
|
|
61
|
+
private getDisplayFilterCells;
|
|
61
62
|
private applyStylesheet;
|
|
62
63
|
private matchesRule;
|
|
63
64
|
private resolveValueTargets;
|
|
@@ -67,6 +68,7 @@ export declare class TableMarkdownBlockRenderer extends QueryMarkdownBlockRender
|
|
|
67
68
|
private installColumnResizeHandle;
|
|
68
69
|
private autosizeColumnWidth;
|
|
69
70
|
private measureTreePrefixWidth;
|
|
71
|
+
private measureRenderedCellContentWidth;
|
|
70
72
|
private resolveFont;
|
|
71
73
|
private measureTextWidth;
|
|
72
74
|
protected formatCellDisplayValue(raw: string, _context: {
|
|
@@ -76,6 +78,14 @@ export declare class TableMarkdownBlockRenderer extends QueryMarkdownBlockRender
|
|
|
76
78
|
options?: Record<string, unknown>;
|
|
77
79
|
}): string;
|
|
78
80
|
private renderValue;
|
|
81
|
+
protected createUploadCsvButton(_columns: string[], _rows: Array<{
|
|
82
|
+
index: number;
|
|
83
|
+
cells: string[];
|
|
84
|
+
}>, _isTree: boolean, _blockSource: string | undefined): HTMLElement | undefined;
|
|
85
|
+
protected transformCsvDownloadData(columns: string[], rows: string[][]): {
|
|
86
|
+
columns: string[];
|
|
87
|
+
rows: string[][];
|
|
88
|
+
};
|
|
79
89
|
private requestCsvDownload;
|
|
80
90
|
private requestTreeJsonDownload;
|
|
81
91
|
private createTreeJsonKeys;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Copyright (c) 2026 Modelware. All rights reserved.
|
|
2
2
|
import { QueryMarkdownBlockRenderer } from './renderer.js';
|
|
3
|
-
import {
|
|
3
|
+
import { shortLabelFromIri } from './wikilink-utils.js';
|
|
4
4
|
export class TableMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
5
5
|
constructor() {
|
|
6
6
|
super(...arguments);
|
|
@@ -16,7 +16,7 @@ export class TableMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
|
16
16
|
const container = this.createResultContainer(result.status);
|
|
17
17
|
container.classList.add('oml-md-result-table');
|
|
18
18
|
const stylesheet = compileTableStylesheet(result.options);
|
|
19
|
-
const tableRoot = this.renderInteractiveTable(result.payload?.columns ?? [], result.payload?.rows ?? [], stylesheet, result.options, result.blockSource);
|
|
19
|
+
const tableRoot = this.renderInteractiveTable(result.payload?.columns ?? [], result.payload?.rows ?? [], result.payload?.rowsTyped, stylesheet, result.options, result.blockSource, result.blockId);
|
|
20
20
|
if (typeof result.blockId === 'string' && result.blockId.length > 0) {
|
|
21
21
|
tableRoot.dataset.tableBlockId = result.blockId;
|
|
22
22
|
}
|
|
@@ -39,11 +39,15 @@ export class TableMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
|
39
39
|
const event = new CustomEvent('oml-table-editor-action', { detail: context });
|
|
40
40
|
window.dispatchEvent(event);
|
|
41
41
|
}
|
|
42
|
-
renderInteractiveTable(columns, rows, stylesheet, options, blockSource) {
|
|
42
|
+
renderInteractiveTable(columns, rows, rowsTyped, stylesheet, options, blockSource, blockId) {
|
|
43
43
|
const root = document.createElement('div');
|
|
44
44
|
root.className = 'table-root graph-root';
|
|
45
45
|
const isTree = this.tableKinds.includes('tree');
|
|
46
|
-
const allRowsWithIndex = rows.map((cells, index) => ({
|
|
46
|
+
const allRowsWithIndex = rows.map((cells, index) => ({
|
|
47
|
+
index,
|
|
48
|
+
cells,
|
|
49
|
+
typedCells: rowsTyped?.[index],
|
|
50
|
+
}));
|
|
47
51
|
const containmentColumns = isTree ? resolveContainmentColumns(columns, options) : [];
|
|
48
52
|
const baseVisibleColumnIndexes = isTree
|
|
49
53
|
? columns.map((_, index) => index).filter((index) => !containmentColumns.includes(index))
|
|
@@ -52,6 +56,7 @@ export class TableMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
|
52
56
|
const baseRowsWithIndex = allRowsWithIndex.map((row) => ({
|
|
53
57
|
...row,
|
|
54
58
|
cells: baseVisibleColumnIndexes.map((columnIndex) => row.cells[columnIndex] ?? ''),
|
|
59
|
+
typedCells: baseVisibleColumnIndexes.map((columnIndex) => row.typedCells?.[columnIndex]),
|
|
55
60
|
}));
|
|
56
61
|
const selectorRowsByIndex = new Map(baseRowsWithIndex.map((row) => [row.index, row]));
|
|
57
62
|
const baseColumnContexts = createColumnContexts(baseVisibleColumns, baseRowsWithIndex);
|
|
@@ -61,7 +66,18 @@ export class TableMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
|
61
66
|
const rowsWithIndex = allRowsWithIndex.map((row) => ({
|
|
62
67
|
...row,
|
|
63
68
|
cells: visibleColumnIndexes.map((columnIndex) => row.cells[columnIndex] ?? ''),
|
|
69
|
+
typedCells: visibleColumnIndexes.map((columnIndex) => row.typedCells?.[columnIndex]),
|
|
64
70
|
}));
|
|
71
|
+
root.__omlAiContext = {
|
|
72
|
+
columns: visibleColumns.slice(),
|
|
73
|
+
rows: rowsWithIndex
|
|
74
|
+
.map((row) => ({
|
|
75
|
+
iri: (row.cells[0] ?? '').trim(),
|
|
76
|
+
cells: row.cells.slice(),
|
|
77
|
+
}))
|
|
78
|
+
.filter((row) => row.iri.length > 0),
|
|
79
|
+
blockSource,
|
|
80
|
+
};
|
|
65
81
|
const columnContexts = createColumnContexts(visibleColumns, rowsWithIndex);
|
|
66
82
|
const treeModel = isTree
|
|
67
83
|
? this.createTreeModel(columns, allRowsWithIndex, visibleColumnIndexes, options)
|
|
@@ -69,17 +85,33 @@ export class TableMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
|
69
85
|
const fullyExpandedTreeRows = isTree && treeModel
|
|
70
86
|
? this.flattenAllTreeRows(treeModel)
|
|
71
87
|
: undefined;
|
|
88
|
+
const persistedState = blockId
|
|
89
|
+
? window.__omlGetPersistedTableUiState?.(blockId)
|
|
90
|
+
: undefined;
|
|
72
91
|
const state = {
|
|
73
|
-
search: '',
|
|
74
|
-
pageSize: 50,
|
|
75
|
-
page: 0,
|
|
76
|
-
sortKey: '',
|
|
77
|
-
sortDir: 'asc',
|
|
78
|
-
hasUserSort: false,
|
|
92
|
+
search: persistedState?.search ?? '',
|
|
93
|
+
pageSize: persistedState?.pageSize ?? 50,
|
|
94
|
+
page: persistedState?.page ?? 0,
|
|
95
|
+
sortKey: persistedState?.sortKey ?? '',
|
|
96
|
+
sortDir: persistedState?.sortDir ?? 'asc',
|
|
97
|
+
hasUserSort: persistedState?.hasUserSort ?? false,
|
|
79
98
|
columnWidths: new Array(columns.length).fill(undefined),
|
|
80
99
|
initialAutosizeApplied: false,
|
|
81
100
|
expanded: new Set(treeModel?.expandableNodes ?? []),
|
|
82
101
|
};
|
|
102
|
+
const persistUiState = () => {
|
|
103
|
+
if (!blockId) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
window.__omlSetPersistedTableUiState?.(blockId, {
|
|
107
|
+
search: state.search,
|
|
108
|
+
pageSize: state.pageSize,
|
|
109
|
+
page: state.page,
|
|
110
|
+
sortKey: state.sortKey,
|
|
111
|
+
sortDir: state.sortDir,
|
|
112
|
+
hasUserSort: state.hasUserSort,
|
|
113
|
+
});
|
|
114
|
+
};
|
|
83
115
|
const controls = document.createElement('div');
|
|
84
116
|
controls.className = 'table-controls';
|
|
85
117
|
const controlsLeft = document.createElement('div');
|
|
@@ -95,9 +127,11 @@ export class TableMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
|
95
127
|
}
|
|
96
128
|
pageSize.appendChild(option);
|
|
97
129
|
}
|
|
130
|
+
pageSize.value = String(state.pageSize);
|
|
98
131
|
pageSize.addEventListener('change', () => {
|
|
99
132
|
state.pageSize = Number.parseInt(pageSize.value, 10);
|
|
100
133
|
state.page = 0;
|
|
134
|
+
persistUiState();
|
|
101
135
|
renderPage();
|
|
102
136
|
});
|
|
103
137
|
if (!isTree) {
|
|
@@ -123,9 +157,11 @@ export class TableMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
|
123
157
|
searchInput.type = 'search';
|
|
124
158
|
searchInput.className = 'tree-filter';
|
|
125
159
|
searchInput.placeholder = 'Filter...';
|
|
160
|
+
searchInput.value = state.search;
|
|
126
161
|
searchInput.addEventListener('input', () => {
|
|
127
162
|
state.search = searchInput.value.trim().toLowerCase();
|
|
128
163
|
state.page = 0;
|
|
164
|
+
persistUiState();
|
|
129
165
|
renderPage();
|
|
130
166
|
});
|
|
131
167
|
controlsRight.appendChild(searchInput);
|
|
@@ -146,16 +182,21 @@ export class TableMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
|
146
182
|
downloadButton.appendChild(iconSvg);
|
|
147
183
|
downloadButton.addEventListener('click', () => {
|
|
148
184
|
const sourceRows = isTree && treeModel
|
|
149
|
-
? this.resolveTreeSourceRows(treeModel, visibleColumns, state.expanded, state.search)
|
|
185
|
+
? this.resolveTreeSourceRows(treeModel, visibleColumns, state.expanded, state.search, blockSource, options)
|
|
150
186
|
: rowsWithIndex;
|
|
151
187
|
if (isTree && treeModel) {
|
|
152
188
|
this.requestTreeJsonDownload(visibleColumns, treeModel, sourceRows);
|
|
153
189
|
return;
|
|
154
190
|
}
|
|
155
|
-
const filtered = this.applyFiltersAndSorting(
|
|
156
|
-
this.
|
|
191
|
+
const filtered = this.applyFiltersAndSorting(visibleColumns, sourceRows, state, blockSource, options);
|
|
192
|
+
const csvExport = this.transformCsvDownloadData(visibleColumns, filtered.map((entry) => entry.cells));
|
|
193
|
+
this.requestCsvDownload(csvExport.columns, csvExport.rows);
|
|
157
194
|
});
|
|
158
195
|
controlsRight.appendChild(downloadButton);
|
|
196
|
+
const uploadButton = this.createUploadCsvButton(visibleColumns, rowsWithIndex, isTree, blockSource);
|
|
197
|
+
if (uploadButton) {
|
|
198
|
+
controlsRight.appendChild(uploadButton);
|
|
199
|
+
}
|
|
159
200
|
controls.appendChild(controlsLeft);
|
|
160
201
|
controls.appendChild(controlsRight);
|
|
161
202
|
root.appendChild(controls);
|
|
@@ -191,6 +232,7 @@ export class TableMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
|
191
232
|
}
|
|
192
233
|
if (state.page > 0) {
|
|
193
234
|
state.page -= 1;
|
|
235
|
+
persistUiState();
|
|
194
236
|
renderPage();
|
|
195
237
|
}
|
|
196
238
|
});
|
|
@@ -198,10 +240,11 @@ export class TableMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
|
198
240
|
if (isTree) {
|
|
199
241
|
return;
|
|
200
242
|
}
|
|
201
|
-
const filtered = this.applyFiltersAndSorting(
|
|
243
|
+
const filtered = this.applyFiltersAndSorting(visibleColumns, rowsWithIndex, state, blockSource, options);
|
|
202
244
|
const totalPages = Math.max(1, Math.ceil(filtered.length / state.pageSize));
|
|
203
245
|
if (state.page < totalPages - 1) {
|
|
204
246
|
state.page += 1;
|
|
247
|
+
persistUiState();
|
|
205
248
|
renderPage();
|
|
206
249
|
}
|
|
207
250
|
});
|
|
@@ -218,9 +261,11 @@ export class TableMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
|
218
261
|
root.appendChild(footer);
|
|
219
262
|
const renderPage = () => {
|
|
220
263
|
const sourceRows = isTree && treeModel
|
|
221
|
-
? this.resolveTreeSourceRows(treeModel, visibleColumns, state.expanded, state.search)
|
|
264
|
+
? this.resolveTreeSourceRows(treeModel, visibleColumns, state.expanded, state.search, blockSource, options)
|
|
222
265
|
: rowsWithIndex;
|
|
223
|
-
const filtered = isTree
|
|
266
|
+
const filtered = isTree
|
|
267
|
+
? sourceRows.slice()
|
|
268
|
+
: this.applyFiltersAndSorting(visibleColumns, sourceRows, state, blockSource, options);
|
|
224
269
|
const total = filtered.length;
|
|
225
270
|
const totalTreeRows = isTree
|
|
226
271
|
? (fullyExpandedTreeRows?.length ?? total)
|
|
@@ -228,6 +273,7 @@ export class TableMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
|
228
273
|
const totalPages = isTree ? 1 : Math.max(1, Math.ceil(total / state.pageSize));
|
|
229
274
|
if (!isTree && state.page >= totalPages) {
|
|
230
275
|
state.page = totalPages - 1;
|
|
276
|
+
persistUiState();
|
|
231
277
|
}
|
|
232
278
|
const gridTemplateColumns = this.buildGridTemplate(visibleColumns.length, state.columnWidths);
|
|
233
279
|
headerRow.innerHTML = '';
|
|
@@ -255,6 +301,7 @@ export class TableMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
|
255
301
|
}
|
|
256
302
|
state.hasUserSort = true;
|
|
257
303
|
state.page = 0;
|
|
304
|
+
persistUiState();
|
|
258
305
|
renderPage();
|
|
259
306
|
});
|
|
260
307
|
}
|
|
@@ -281,6 +328,7 @@ export class TableMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
|
281
328
|
const rowContext = createRowContext(baseVisibleColumns, selectorRow);
|
|
282
329
|
for (let columnIndex = 0; columnIndex < visibleColumns.length; columnIndex += 1) {
|
|
283
330
|
const value = rowEntry.cells[columnIndex] ?? '';
|
|
331
|
+
const typedValue = rowEntry.typedCells?.[columnIndex];
|
|
284
332
|
const td = document.createElement('div');
|
|
285
333
|
td.className = 'table-cell';
|
|
286
334
|
const valueElement = this.renderValue(this.formatCellDisplayValue(value, {
|
|
@@ -288,7 +336,7 @@ export class TableMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
|
288
336
|
columns: visibleColumns,
|
|
289
337
|
blockSource,
|
|
290
338
|
options,
|
|
291
|
-
}));
|
|
339
|
+
}), typedValue);
|
|
292
340
|
if (isTree && columnIndex === 0) {
|
|
293
341
|
const treeCell = this.renderTreeCell(valueElement, rowEntry, treeModel, state.expanded, () => renderPage());
|
|
294
342
|
td.appendChild(treeCell);
|
|
@@ -355,13 +403,13 @@ export class TableMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
|
355
403
|
extractTypeOptions(_blockSource) {
|
|
356
404
|
return [];
|
|
357
405
|
}
|
|
358
|
-
resolveTreeSourceRows(model, columns, expanded, search) {
|
|
406
|
+
resolveTreeSourceRows(model, columns, expanded, search, blockSource, options) {
|
|
359
407
|
if (search) {
|
|
360
|
-
return this.filterTreeRowsBySearch(model, columns, search);
|
|
408
|
+
return this.filterTreeRowsBySearch(model, columns, search, blockSource, options);
|
|
361
409
|
}
|
|
362
410
|
return this.flattenTreeRows(model, expanded);
|
|
363
411
|
}
|
|
364
|
-
filterTreeRowsBySearch(model, columns, search) {
|
|
412
|
+
filterTreeRowsBySearch(model, columns, search, blockSource, options) {
|
|
365
413
|
const fullyExpanded = this.flattenTreeRows(model, new Set(model.expandableNodes));
|
|
366
414
|
const matchedIds = new Set();
|
|
367
415
|
for (const row of fullyExpanded) {
|
|
@@ -369,7 +417,7 @@ export class TableMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
|
369
417
|
if (!nodeId) {
|
|
370
418
|
continue;
|
|
371
419
|
}
|
|
372
|
-
if (matchesFilterQuery(columns, row
|
|
420
|
+
if (matchesFilterQuery(columns, this.getDisplayFilterCells(row, columns, blockSource, options), search)) {
|
|
373
421
|
matchedIds.add(nodeId);
|
|
374
422
|
}
|
|
375
423
|
}
|
|
@@ -405,6 +453,7 @@ export class TableMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
|
405
453
|
const projectRow = (row) => ({
|
|
406
454
|
...row,
|
|
407
455
|
cells: visibleColumnIndexes.map((columnIndex) => row.cells[columnIndex] ?? ''),
|
|
456
|
+
typedCells: visibleColumnIndexes.map((columnIndex) => row.typedCells?.[columnIndex]),
|
|
408
457
|
});
|
|
409
458
|
for (const row of allRows) {
|
|
410
459
|
const id = row.cells[idColumnIndex] ?? '';
|
|
@@ -449,7 +498,7 @@ export class TableMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
|
449
498
|
const syntheticAll = new Array(allColumns.length).fill('');
|
|
450
499
|
syntheticAll[idColumnIndex] = child;
|
|
451
500
|
const synthetic = visibleColumnIndexes.map((columnIndex) => syntheticAll[columnIndex] ?? '');
|
|
452
|
-
const syntheticRow = { index: allRows.length + rowsById.size, cells: synthetic };
|
|
501
|
+
const syntheticRow = { index: allRows.length + rowsById.size, cells: synthetic, typedCells: new Array(visibleColumnIndexes.length).fill(undefined) };
|
|
453
502
|
rowsById.set(child, syntheticRow);
|
|
454
503
|
order.push(child);
|
|
455
504
|
}
|
|
@@ -588,9 +637,9 @@ export class TableMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
|
588
637
|
button.appendChild(iconSvg);
|
|
589
638
|
return button;
|
|
590
639
|
}
|
|
591
|
-
applyFiltersAndSorting(columns, rows, state) {
|
|
640
|
+
applyFiltersAndSorting(columns, rows, state, blockSource, options) {
|
|
592
641
|
const filtered = state.search
|
|
593
|
-
? rows.filter((row) => matchesFilterQuery(columns, row
|
|
642
|
+
? rows.filter((row) => matchesFilterQuery(columns, this.getDisplayFilterCells(row, columns, blockSource, options), state.search))
|
|
594
643
|
: rows.slice();
|
|
595
644
|
if (!state.hasUserSort) {
|
|
596
645
|
return filtered;
|
|
@@ -606,6 +655,21 @@ export class TableMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
|
606
655
|
return a.localeCompare(b, undefined, { numeric: true, sensitivity: 'base' }) * dir;
|
|
607
656
|
});
|
|
608
657
|
}
|
|
658
|
+
getDisplayFilterCells(row, columns, blockSource, options) {
|
|
659
|
+
return columns.map((_, columnIndex) => {
|
|
660
|
+
const raw = row.cells[columnIndex] ?? '';
|
|
661
|
+
const typedValue = row.typedCells?.[columnIndex];
|
|
662
|
+
if (typedValue?.values?.length) {
|
|
663
|
+
return this.formatCellDisplayText(raw, typedValue);
|
|
664
|
+
}
|
|
665
|
+
return this.formatCellDisplayValue(raw, {
|
|
666
|
+
columnIndex,
|
|
667
|
+
columns,
|
|
668
|
+
blockSource,
|
|
669
|
+
options,
|
|
670
|
+
});
|
|
671
|
+
});
|
|
672
|
+
}
|
|
609
673
|
applyStylesheet(cellElement, valueElement, rules, contexts) {
|
|
610
674
|
for (const rule of rules) {
|
|
611
675
|
if (rule.target !== 'value') {
|
|
@@ -740,13 +804,12 @@ export class TableMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
|
740
804
|
}
|
|
741
805
|
autosizeColumnWidth(columnIndex, columns, rows, referenceCellOrFont, headerFontOverride) {
|
|
742
806
|
const headerText = `${columns[columnIndex] ?? ''} ▲`;
|
|
743
|
-
const values = rows.map((row) => formatCellDisplayText(row.cells[columnIndex] ?? ''));
|
|
744
807
|
const valueFont = typeof referenceCellOrFont === 'string'
|
|
745
808
|
? referenceCellOrFont
|
|
746
809
|
: this.resolveFont(referenceCellOrFont);
|
|
747
810
|
const headerFont = headerFontOverride ?? valueFont;
|
|
748
|
-
const widestValue =
|
|
749
|
-
const width = this.
|
|
811
|
+
const widestValue = rows.reduce((max, row) => {
|
|
812
|
+
const width = this.measureRenderedCellContentWidth(row, columnIndex, columns, valueFont);
|
|
750
813
|
return Math.max(max, width);
|
|
751
814
|
}, 0);
|
|
752
815
|
const headerWidth = this.measureTextWidth(headerText, headerFont);
|
|
@@ -774,6 +837,34 @@ export class TableMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
|
774
837
|
return Math.max(max, prefix);
|
|
775
838
|
}, 0);
|
|
776
839
|
}
|
|
840
|
+
measureRenderedCellContentWidth(row, columnIndex, columns, font) {
|
|
841
|
+
const rawValue = row.cells[columnIndex] ?? '';
|
|
842
|
+
const typedValue = row.typedCells?.[columnIndex];
|
|
843
|
+
const formattedValue = this.formatCellDisplayValue(rawValue, {
|
|
844
|
+
columnIndex,
|
|
845
|
+
columns,
|
|
846
|
+
});
|
|
847
|
+
const valueElement = this.renderValue(formattedValue, typedValue);
|
|
848
|
+
const decorated = this.decorateCellValueElement({
|
|
849
|
+
row: { index: row.index, cells: row.cells },
|
|
850
|
+
columnIndex,
|
|
851
|
+
columns,
|
|
852
|
+
value: rawValue,
|
|
853
|
+
valueElement,
|
|
854
|
+
});
|
|
855
|
+
const probe = document.createElement('div');
|
|
856
|
+
probe.style.position = 'fixed';
|
|
857
|
+
probe.style.left = '-10000px';
|
|
858
|
+
probe.style.top = '-10000px';
|
|
859
|
+
probe.style.visibility = 'hidden';
|
|
860
|
+
probe.style.whiteSpace = 'nowrap';
|
|
861
|
+
probe.style.font = font;
|
|
862
|
+
probe.appendChild(decorated);
|
|
863
|
+
document.body.appendChild(probe);
|
|
864
|
+
const width = probe.getBoundingClientRect().width;
|
|
865
|
+
probe.remove();
|
|
866
|
+
return width;
|
|
867
|
+
}
|
|
777
868
|
resolveFont(referenceCell) {
|
|
778
869
|
const computed = window.getComputedStyle(referenceCell);
|
|
779
870
|
const lineHeight = computed.lineHeight && computed.lineHeight !== 'normal' ? computed.lineHeight : computed.fontSize;
|
|
@@ -791,11 +882,14 @@ export class TableMarkdownBlockRenderer extends QueryMarkdownBlockRenderer {
|
|
|
791
882
|
formatCellDisplayValue(raw, _context) {
|
|
792
883
|
return raw;
|
|
793
884
|
}
|
|
794
|
-
renderValue(raw) {
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
return
|
|
885
|
+
renderValue(raw, typedValue) {
|
|
886
|
+
return this.renderCellValue(raw, typedValue);
|
|
887
|
+
}
|
|
888
|
+
createUploadCsvButton(_columns, _rows, _isTree, _blockSource) {
|
|
889
|
+
return undefined;
|
|
890
|
+
}
|
|
891
|
+
transformCsvDownloadData(columns, rows) {
|
|
892
|
+
return { columns, rows };
|
|
799
893
|
}
|
|
800
894
|
requestCsvDownload(columns, rows) {
|
|
801
895
|
if (columns.length === 0) {
|
|
@@ -1124,13 +1218,6 @@ function resolveHiddenColumns(columns, columnContexts, rules) {
|
|
|
1124
1218
|
}
|
|
1125
1219
|
return hidden;
|
|
1126
1220
|
}
|
|
1127
|
-
function formatCellDisplayText(raw) {
|
|
1128
|
-
const parts = raw.split(/[\s,]+/).filter((entry) => entry.length > 0);
|
|
1129
|
-
if (parts.length === 0) {
|
|
1130
|
-
return raw;
|
|
1131
|
-
}
|
|
1132
|
-
return parts.map((part) => isIriValue(part) ? shortLabelFromIri(part) : part).join(' ');
|
|
1133
|
-
}
|
|
1134
1221
|
function matchesFilterQuery(columns, cells, rawQuery) {
|
|
1135
1222
|
const terms = parseFilterTerms(rawQuery);
|
|
1136
1223
|
if (terms.length === 0) {
|