solid-panes 4.1.0 → 4.2.1-b9452f7f

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.
@@ -26,47 +26,9 @@ var _default = exports.default = {
26
26
  mintClass: UI.ns.solid('DokieliDocument'),
27
27
  // @@ A better class?
28
28
 
29
+ // Don't provide viewing - let humanReadablePane handle that with appropriate icon
29
30
  label: function (subject, context) {
30
- const kb = context.session.store;
31
- const ns = UI.ns;
32
- const allowed = [
33
- // 'text/plain',
34
- 'text/html', 'application/xhtml+xml'
35
- // 'image/png', 'image/jpeg', 'application/pdf',
36
- // 'video/mp4'
37
- ];
38
- const hasContentTypeIn = function (kb, x, displayables) {
39
- const cts = kb.fetcher.getHeader(x, 'content-type');
40
- if (cts) {
41
- for (let j = 0; j < cts.length; j++) {
42
- for (let k = 0; k < displayables.length; k++) {
43
- if (cts[j].indexOf(displayables[k]) >= 0) {
44
- return true;
45
- }
46
- }
47
- }
48
- }
49
- return false;
50
- };
51
-
52
- // This data coul d come from a fetch OR from ldp comtaimner
53
- const hasContentTypeIn2 = function (kb, x, displayables) {
54
- const t = kb.findTypeURIs(x);
55
- for (let k = 0; k < displayables.length; k++) {
56
- if ($rdf.Util.mediaTypeClass(displayables[k]).uri in t) {
57
- return true;
58
- }
59
- }
60
- return false;
61
- };
62
- if (!subject.uri) return null; // no bnodes
63
-
64
- const t = kb.findTypeURIs(subject);
65
- if (t[ns.link('WebPage').uri]) return 'view';
66
- if (hasContentTypeIn(kb, subject, allowed) || hasContentTypeIn2(kb, subject, allowed)) {
67
- return 'Dok';
68
- }
69
- return null;
31
+ return null; // Viewing now handled by humanReadablePane
70
32
  },
71
33
  // Create a new folder in a Solid system, with a dokieli editable document in it
72
34
  mintNew: function (context, newPaneOptions) {
@@ -106,64 +68,8 @@ var _default = exports.default = {
106
68
  console.log('Error creating dokieli doc at ' + newPaneOptions.newInstance + ': ' + err);
107
69
  });
108
70
  });
109
- },
110
- // Derived from: humanReadablePane .. share code?
111
- render: function (subject, context) {
112
- const myDocument = context.dom;
113
- const div = myDocument.createElement('div');
114
- const kb = context.session.store;
115
-
116
- // @@ When we can, use CSP to turn off scripts within the iframe
117
- div.setAttribute('class', 'docView');
118
- const iframe = myDocument.createElement('IFRAME');
119
-
120
- // Function to set iframe attributes
121
- const setIframeAttributes = (iframe, blob, lines) => {
122
- const objectURL = URL.createObjectURL(blob);
123
- iframe.setAttribute('src', objectURL);
124
- iframe.setAttribute('type', blob.type);
125
- iframe.setAttribute('class', 'doc');
126
- iframe.setAttribute('style', `border: 1px solid; padding: 1em; height:${lines}em; width:800px; resize: both; overflow: auto;`);
127
-
128
- // Apply sandbox attribute only for HTML files
129
- // @@ NOte beflow - if we set ANY sandbox, then Chrome and Safari won't display it if it is PDF.
130
- // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe
131
- // You can;'t have any sandbox and allow plugins.
132
- // We could sandbox only HTML files I suppose.
133
- // HTML5 bug: https://lists.w3.org/Archives/Public/public-html/2011Jun/0330.html
134
- if (blob.type === 'text/html' || blob.type === 'application/xhtml+xml') {
135
- iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin');
136
- }
137
- };
138
-
139
- // Fetch and process the blob
140
- kb.fetcher._fetch(subject.uri).then(response => response.blob()).then(blob => {
141
- const blobTextPromise = blob.type.startsWith('text') ? blob.text() : Promise.resolve('');
142
- return blobTextPromise.then(blobText => ({
143
- blob,
144
- blobText
145
- }));
146
- }).then(({
147
- blob,
148
- blobText
149
- }) => {
150
- const newLines = blobText.includes('<script src="https://dokie.li/scripts/dokieli.js">') ? -10 : 5;
151
- const lines = Math.min(30, blobText.split(/\n/).length + newLines);
152
- setIframeAttributes(iframe, blob, lines);
153
- }).catch(err => {
154
- console.log('Error fetching or processing blob:', err);
155
- });
156
- const cts = kb.fetcher.getHeader(subject.doc(), 'content-type');
157
- const ct = cts ? cts[0].split(';', 1)[0].trim() : null;
158
- if (ct) {
159
- console.log('dokieliPane: c-t:' + ct);
160
- } else {
161
- console.log('dokieliPane: unknown content-type?');
162
- }
163
- const tr = myDocument.createElement('tr');
164
- tr.appendChild(iframe);
165
- div.appendChild(tr);
166
- return div;
167
71
  }
72
+
73
+ // render: removed - now handled by humanReadablePane with appropriate dokieli icon
168
74
  }; // ends
169
75
  //# sourceMappingURL=dokieliPane.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"dokieliPane.js","names":["UI","_interopRequireWildcard","require","$rdf","mime","_new","_interopRequireDefault","e","__esModule","default","t","WeakMap","r","n","o","i","f","__proto__","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","_default","exports","icon","icons","iconBase","name","mintClass","ns","solid","label","subject","context","kb","session","store","allowed","hasContentTypeIn","x","displayables","cts","fetcher","getHeader","j","length","k","indexOf","hasContentTypeIn2","findTypeURIs","Util","mediaTypeClass","uri","link","mintNew","newPaneOptions","newInstance","newBase","endsWith","slice","sym","contentType","lookup","includes","htmlContents","DOKIELI_TEMPLATE","filename","split","decodeURIComponent","encodedTitle","replace","Promise","resolve","webOperation","data","then","console","log","catch","err","render","myDocument","dom","div","createElement","setAttribute","iframe","setIframeAttributes","blob","lines","objectURL","URL","createObjectURL","type","_fetch","response","blobTextPromise","startsWith","text","blobText","newLines","Math","min","doc","ct","trim","tr","appendChild"],"sources":["../../src/dokieli/dokieliPane.js"],"sourcesContent":["/* Human-readable editable \"Dokieli\" Pane\n **\n ** This outline pane contains the document contents for a Dokieli document\n ** The dokeili system allows the user to edit a document including anotations\n ** review. It does not use turtle, but RDF/a\n */\n\nimport * as UI from 'solid-ui'\nimport * as $rdf from 'rdflib'\nimport * as mime from 'mime-types'\n\n// const DOKIELI_TEMPLATE_URI = 'https://dokie.li/new' // Copy to make new dok\n\nimport DOKIELI_TEMPLATE from './new.js' // Distributed with this library\n\nexport default {\n icon: UI.icons.iconBase + 'dokieli-logo.png', // @@ improve? more like doccument?\n\n name: 'Dokieli',\n\n mintClass: UI.ns.solid('DokieliDocument'), // @@ A better class?\n\n label: function (subject, context) {\n const kb = context.session.store\n const ns = UI.ns\n const allowed = [\n // 'text/plain',\n 'text/html',\n 'application/xhtml+xml'\n // 'image/png', 'image/jpeg', 'application/pdf',\n // 'video/mp4'\n ]\n\n const hasContentTypeIn = function (kb, x, displayables) {\n const cts = kb.fetcher.getHeader(x, 'content-type')\n if (cts) {\n for (let j = 0; j < cts.length; j++) {\n for (let k = 0; k < displayables.length; k++) {\n if (cts[j].indexOf(displayables[k]) >= 0) {\n return true\n }\n }\n }\n }\n return false\n }\n\n // This data coul d come from a fetch OR from ldp comtaimner\n const hasContentTypeIn2 = function (kb, x, displayables) {\n const t = kb.findTypeURIs(x)\n for (let k = 0; k < displayables.length; k++) {\n if ($rdf.Util.mediaTypeClass(displayables[k]).uri in t) {\n return true\n }\n }\n return false\n }\n\n if (!subject.uri) return null // no bnodes\n\n const t = kb.findTypeURIs(subject)\n if (t[ns.link('WebPage').uri]) return 'view'\n\n if (\n hasContentTypeIn(kb, subject, allowed) ||\n hasContentTypeIn2(kb, subject, allowed)\n ) {\n return 'Dok'\n }\n\n return null\n },\n\n // Create a new folder in a Solid system, with a dokieli editable document in it\n mintNew: function (context, newPaneOptions) {\n const kb = context.session.store\n let newInstance = newPaneOptions.newInstance\n if (!newInstance) {\n let uri = newPaneOptions.newBase\n if (uri.endsWith('/')) {\n uri = uri.slice(0, -1)\n newPaneOptions.newBase = uri\n }\n newInstance = kb.sym(uri)\n }\n\n const contentType = mime.lookup(newInstance.uri)\n if (!contentType || !contentType.includes('html')) {\n newInstance = $rdf.sym(newInstance.uri + '.html')\n }\n newPaneOptions.newInstance = newInstance // Save for creation system\n\n // console.log('New dokieli will make: ' + newInstance)\n\n let htmlContents = DOKIELI_TEMPLATE\n let filename = newInstance.uri.split('/').slice(-1)[0]\n filename = decodeURIComponent(filename.split('.')[0])\n const encodedTitle = filename\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n htmlContents = htmlContents.replace('<title>', '<title>' + encodedTitle)\n htmlContents = htmlContents.replace(\n '</article>',\n '<h1>' + encodedTitle + '</h1></article>'\n )\n // console.log('@@ New HTML for Dok:' + htmlContents)\n return new Promise(function (resolve) {\n kb.fetcher\n .webOperation('PUT', newInstance.uri, {\n data: htmlContents,\n contentType: 'text/html'\n })\n .then(function () {\n console.log(\n 'new Dokieli document created at ' + newPaneOptions.newInstance\n )\n resolve(newPaneOptions)\n })\n .catch(function (err) {\n console.log(\n 'Error creating dokieli doc at ' +\n newPaneOptions.newInstance +\n ': ' +\n err\n )\n })\n })\n },\n\n // Derived from: humanReadablePane .. share code?\n render: function (subject, context) {\n const myDocument = context.dom\n const div = myDocument.createElement('div')\n const kb = context.session.store\n\n // @@ When we can, use CSP to turn off scripts within the iframe\n div.setAttribute('class', 'docView')\n const iframe = myDocument.createElement('IFRAME')\n\n // Function to set iframe attributes\n const setIframeAttributes = (iframe, blob, lines) => {\n const objectURL = URL.createObjectURL(blob)\n iframe.setAttribute('src', objectURL)\n iframe.setAttribute('type', blob.type)\n iframe.setAttribute('class', 'doc')\n iframe.setAttribute('style', `border: 1px solid; padding: 1em; height:${lines}em; width:800px; resize: both; overflow: auto;`)\n\n // Apply sandbox attribute only for HTML files\n // @@ NOte beflow - if we set ANY sandbox, then Chrome and Safari won't display it if it is PDF.\n // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe\n // You can;'t have any sandbox and allow plugins.\n // We could sandbox only HTML files I suppose.\n // HTML5 bug: https://lists.w3.org/Archives/Public/public-html/2011Jun/0330.html\n if (blob.type === 'text/html' || blob.type === 'application/xhtml+xml') {\n iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin')\n }\n }\n\n // Fetch and process the blob\n kb.fetcher._fetch(subject.uri)\n .then(response => response.blob())\n .then(blob => {\n const blobTextPromise = blob.type.startsWith('text') ? blob.text() : Promise.resolve('')\n return blobTextPromise.then(blobText => ({ blob, blobText }))\n })\n .then(({ blob, blobText }) => {\n const newLines = blobText.includes('<script src=\"https://dokie.li/scripts/dokieli.js\">') ? -10 : 5\n const lines = Math.min(30, blobText.split(/\\n/).length + newLines)\n setIframeAttributes(iframe, blob, lines)\n })\n .catch(err => {\n console.log('Error fetching or processing blob:', err)\n })\n\n const cts = kb.fetcher.getHeader(subject.doc(), 'content-type')\n const ct = cts ? cts[0].split(';', 1)[0].trim() : null\n if (ct) {\n console.log('dokieliPane: c-t:' + ct)\n } else {\n console.log('dokieliPane: unknown content-type?')\n }\n\n const tr = myDocument.createElement('tr')\n tr.appendChild(iframe)\n div.appendChild(tr)\n return div\n }\n}\n// ends\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"dokieliPane.js","names":["UI","_interopRequireWildcard","require","$rdf","mime","_new","_interopRequireDefault","e","__esModule","default","t","WeakMap","r","n","o","i","f","__proto__","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","_default","exports","icon","icons","iconBase","name","mintClass","ns","solid","label","subject","context","mintNew","newPaneOptions","kb","session","store","newInstance","uri","newBase","endsWith","slice","sym","contentType","lookup","includes","htmlContents","DOKIELI_TEMPLATE","filename","split","decodeURIComponent","encodedTitle","replace","Promise","resolve","fetcher","webOperation","data","then","console","log","catch","err"],"sources":["../../src/dokieli/dokieliPane.js"],"sourcesContent":["/* Human-readable editable \"Dokieli\" Pane\n **\n ** This outline pane contains the document contents for a Dokieli document\n ** The dokeili system allows the user to edit a document including anotations\n ** review. It does not use turtle, but RDF/a\n */\n\nimport * as UI from 'solid-ui'\nimport * as $rdf from 'rdflib'\nimport * as mime from 'mime-types'\n\n// const DOKIELI_TEMPLATE_URI = 'https://dokie.li/new' // Copy to make new dok\n\nimport DOKIELI_TEMPLATE from './new.js' // Distributed with this library\n\nexport default {\n icon: UI.icons.iconBase + 'dokieli-logo.png', // @@ improve? more like doccument?\n\n name: 'Dokieli',\n\n mintClass: UI.ns.solid('DokieliDocument'), // @@ A better class?\n\n // Don't provide viewing - let humanReadablePane handle that with appropriate icon\n label: function (subject, context) {\n return null // Viewing now handled by humanReadablePane\n },\n\n // Create a new folder in a Solid system, with a dokieli editable document in it\n mintNew: function (context, newPaneOptions) {\n const kb = context.session.store\n let newInstance = newPaneOptions.newInstance\n if (!newInstance) {\n let uri = newPaneOptions.newBase\n if (uri.endsWith('/')) {\n uri = uri.slice(0, -1)\n newPaneOptions.newBase = uri\n }\n newInstance = kb.sym(uri)\n }\n\n const contentType = mime.lookup(newInstance.uri)\n if (!contentType || !contentType.includes('html')) {\n newInstance = $rdf.sym(newInstance.uri + '.html')\n }\n newPaneOptions.newInstance = newInstance // Save for creation system\n\n // console.log('New dokieli will make: ' + newInstance)\n\n let htmlContents = DOKIELI_TEMPLATE\n let filename = newInstance.uri.split('/').slice(-1)[0]\n filename = decodeURIComponent(filename.split('.')[0])\n const encodedTitle = filename\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n htmlContents = htmlContents.replace('<title>', '<title>' + encodedTitle)\n htmlContents = htmlContents.replace(\n '</article>',\n '<h1>' + encodedTitle + '</h1></article>'\n )\n // console.log('@@ New HTML for Dok:' + htmlContents)\n return new Promise(function (resolve) {\n kb.fetcher\n .webOperation('PUT', newInstance.uri, {\n data: htmlContents,\n contentType: 'text/html'\n })\n .then(function () {\n console.log(\n 'new Dokieli document created at ' + newPaneOptions.newInstance\n )\n resolve(newPaneOptions)\n })\n .catch(function (err) {\n console.log(\n 'Error creating dokieli doc at ' +\n newPaneOptions.newInstance +\n ': ' +\n err\n )\n })\n })\n }\n\n // render: removed - now handled by humanReadablePane with appropriate dokieli icon\n}\n// ends\n"],"mappings":"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","ignoreList":[]}
@@ -4,8 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
- const DOKIELI_TEMPLATE = `
8
- <!DOCTYPE html>
7
+ const DOKIELI_TEMPLATE = `<!DOCTYPE html>
9
8
  <html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
10
9
  <head>
11
10
  <meta charset="utf-8" />
@@ -23,6 +22,7 @@ const DOKIELI_TEMPLATE = `
23
22
  </article>
24
23
  </main>
25
24
  </body>
26
- </html>`;
25
+ </html>
26
+ `;
27
27
  var _default = exports.default = DOKIELI_TEMPLATE;
28
28
  //# sourceMappingURL=new.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"new.js","names":["DOKIELI_TEMPLATE","_default","exports","default"],"sources":["../../src/dokieli/new.js"],"sourcesContent":["const DOKIELI_TEMPLATE = `\n<!DOCTYPE html>\n<html lang=\"en\" xml:lang=\"en\" xmlns=\"http://www.w3.org/1999/xhtml\">\n <head>\n <meta charset=\"utf-8\" />\n <title></title>\n <meta content=\"width=device-width, initial-scale=1\" name=\"viewport\" />\n <link href=\"https://dokie.li/media/css/basic.css\" media=\"all\" rel=\"stylesheet\" title=\"Basic\" />\n <link href=\"https://dokie.li/media/css/dokieli.css\" media=\"all\" rel=\"stylesheet\" />\n <script src=\"https://dokie.li/scripts/dokieli.js\"></script>\n </head>\n\n <body about=\"\" prefix=\"rdf: http://www.w3.org/1999/02/22-rdf-syntax-ns# rdfs: http://www.w3.org/2000/01/rdf-schema# owl: http://www.w3.org/2002/07/owl# xsd: http://www.w3.org/2001/XMLSchema# rdfa: http://www.w3.org/ns/rdfa# dcterms: http://purl.org/dc/terms/ dctypes: http://purl.org/dc/dcmitype/ foaf: http://xmlns.com/foaf/0.1/ pimspace: http://www.w3.org/ns/pim/space# skos: http://www.w3.org/2004/02/skos/core# prov: http://www.w3.org/ns/prov# mem: http://mementoweb.org/ns# qb: http://purl.org/linked-data/cube# schema: http://schema.org/ void: http://rdfs.org/ns/void# rsa: http://www.w3.org/ns/auth/rsa# cert: http://www.w3.org/ns/auth/cert# wgs: http://www.w3.org/2003/01/geo/wgs84_pos# bibo: http://purl.org/ontology/bibo/ sioc: http://rdfs.org/sioc/ns# doap: http://usefulinc.com/ns/doap# dbr: http://dbpedia.org/resource/ dbp: http://dbpedia.org/property/ sio: http://semanticscience.org/resource/ opmw: http://www.opmw.org/ontology/ deo: http://purl.org/spar/deo/ doco: http://purl.org/spar/doco/ cito: http://purl.org/spar/cito/ fabio: http://purl.org/spar/fabio/ oa: http://www.w3.org/ns/oa# as: https://www.w3.org/ns/activitystreams# ldp: http://www.w3.org/ns/ldp# solid: http://www.w3.org/ns/solid/terms# acl: http://www.w3.org/ns/auth/acl# earl: http://www.w3.org/ns/earl# spec: http://www.w3.org/ns/spec# odrl: http://www.w3.org/ns/odrl/2/ dio: https://w3id.org/dio# rel: https://www.w3.org/ns/iana/link-relations/relation#\" typeof=\"schema:CreativeWork prov:Entity\">\n <main>\n <article about=\"\" typeof=\"schema:Article\">\n\n </article>\n </main>\n </body>\n</html>`\n\nexport default DOKIELI_TEMPLATE\n"],"mappings":";;;;;;AAAA,MAAMA,gBAAgB,GAAG;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AAAA,IAAAC,QAAA,GAAAC,OAAA,CAAAC,OAAA,GAEOH,gBAAgB","ignoreList":[]}
1
+ {"version":3,"file":"new.js","names":["DOKIELI_TEMPLATE","_default","exports","default"],"sources":["../../src/dokieli/new.js"],"sourcesContent":["const DOKIELI_TEMPLATE = `<!DOCTYPE html>\n<html lang=\"en\" xml:lang=\"en\" xmlns=\"http://www.w3.org/1999/xhtml\">\n <head>\n <meta charset=\"utf-8\" />\n <title></title>\n <meta content=\"width=device-width, initial-scale=1\" name=\"viewport\" />\n <link href=\"https://dokie.li/media/css/basic.css\" media=\"all\" rel=\"stylesheet\" title=\"Basic\" />\n <link href=\"https://dokie.li/media/css/dokieli.css\" media=\"all\" rel=\"stylesheet\" />\n <script src=\"https://dokie.li/scripts/dokieli.js\"></script>\n </head>\n\n <body about=\"\" prefix=\"rdf: http://www.w3.org/1999/02/22-rdf-syntax-ns# rdfs: http://www.w3.org/2000/01/rdf-schema# owl: http://www.w3.org/2002/07/owl# xsd: http://www.w3.org/2001/XMLSchema# rdfa: http://www.w3.org/ns/rdfa# dcterms: http://purl.org/dc/terms/ dctypes: http://purl.org/dc/dcmitype/ foaf: http://xmlns.com/foaf/0.1/ pimspace: http://www.w3.org/ns/pim/space# skos: http://www.w3.org/2004/02/skos/core# prov: http://www.w3.org/ns/prov# mem: http://mementoweb.org/ns# qb: http://purl.org/linked-data/cube# schema: http://schema.org/ void: http://rdfs.org/ns/void# rsa: http://www.w3.org/ns/auth/rsa# cert: http://www.w3.org/ns/auth/cert# wgs: http://www.w3.org/2003/01/geo/wgs84_pos# bibo: http://purl.org/ontology/bibo/ sioc: http://rdfs.org/sioc/ns# doap: http://usefulinc.com/ns/doap# dbr: http://dbpedia.org/resource/ dbp: http://dbpedia.org/property/ sio: http://semanticscience.org/resource/ opmw: http://www.opmw.org/ontology/ deo: http://purl.org/spar/deo/ doco: http://purl.org/spar/doco/ cito: http://purl.org/spar/cito/ fabio: http://purl.org/spar/fabio/ oa: http://www.w3.org/ns/oa# as: https://www.w3.org/ns/activitystreams# ldp: http://www.w3.org/ns/ldp# solid: http://www.w3.org/ns/solid/terms# acl: http://www.w3.org/ns/auth/acl# earl: http://www.w3.org/ns/earl# spec: http://www.w3.org/ns/spec# odrl: http://www.w3.org/ns/odrl/2/ dio: https://w3id.org/dio# rel: https://www.w3.org/ns/iana/link-relations/relation#\" typeof=\"schema:CreativeWork prov:Entity\">\n <main>\n <article about=\"\" typeof=\"schema:Article\">\n\n </article>\n </main>\n </body>\n</html>\n`\n\nexport default DOKIELI_TEMPLATE\n"],"mappings":";;;;;;AAAA,MAAMA,gBAAgB,GAAG;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AAAA,IAAAC,QAAA,GAAAC,OAAA,CAAAC,OAAA,GAEcH,gBAAgB","ignoreList":[]}
@@ -21,8 +21,55 @@ const isMarkdownFile = uri => {
21
21
  const path = uri.split('?')[0].split('#')[0]; // Remove query string and fragment
22
22
  return /\.(md|markdown|mdown|mkd|mkdn)$/i.test(path);
23
23
  };
24
+
25
+ // Cache for dokieli detection results (keyed by subject URI)
26
+ const dokieliCache = new Map();
24
27
  const humanReadablePane = {
25
- icon: _solidUi.icons.originalIconBase + 'tango/22-text-x-generic.png',
28
+ icon: function (subject, context) {
29
+ // Markdown files detected by extension
30
+ if (subject && isMarkdownFile(subject.uri)) {
31
+ return _solidUi.icons.iconBase + 'markdown.svg';
32
+ }
33
+
34
+ // Dokieli files detected by content check
35
+ if (subject) {
36
+ const kb = context.session.store;
37
+
38
+ // Check cache from previous detection
39
+ const cachedResult = dokieliCache.get(subject.uri);
40
+ if (cachedResult === 'dokieli') {
41
+ return _solidUi.icons.iconBase + 'dokieli-logo.png';
42
+ } else if (cachedResult === 'html') {
43
+ return _solidUi.icons.originalIconBase + 'tango/22-text-x-generic.png';
44
+ }
45
+
46
+ // Check if content already fetched (synchronous)
47
+ const responseText = kb.fetcher.getHeader(subject.doc(), 'content');
48
+ if (responseText && responseText.length > 0) {
49
+ const text = responseText[0];
50
+ const isDokieli = text.includes('<script src="https://dokie.li/scripts/dokieli.js">') || text.includes('dokieli.css');
51
+ dokieliCache.set(subject.uri, isDokieli ? 'dokieli' : 'html');
52
+ return isDokieli ? _solidUi.icons.iconBase + 'dokieli-logo.png' : _solidUi.icons.originalIconBase + 'tango/22-text-x-generic.png';
53
+ }
54
+
55
+ // Content not yet fetched - return a promise (async detection)
56
+ const cts = kb.fetcher.getHeader(subject.doc(), 'content-type');
57
+ const ct = cts ? cts[0].split(';', 1)[0].trim() : null;
58
+ if (ct === 'text/html') {
59
+ return kb.fetcher._fetch(subject.uri).then(response => response.text()).then(text => {
60
+ const isDokieli = text.includes('<script src="https://dokie.li/scripts/dokieli.js">') || text.includes('dokieli.css');
61
+ dokieliCache.set(subject.uri, isDokieli ? 'dokieli' : 'html');
62
+ return isDokieli ? _solidUi.icons.iconBase + 'dokieli-logo.png' : _solidUi.icons.originalIconBase + 'tango/22-text-x-generic.png';
63
+ }).catch(() => {
64
+ dokieliCache.set(subject.uri, 'html');
65
+ return _solidUi.icons.originalIconBase + 'tango/22-text-x-generic.png';
66
+ });
67
+ }
68
+ }
69
+
70
+ // Default for all other human-readable content
71
+ return _solidUi.icons.originalIconBase + 'tango/22-text-x-generic.png';
72
+ },
26
73
  name: 'humanReadable',
27
74
  label: function (subject, context) {
28
75
  const kb = context.session.store;
@@ -64,6 +111,18 @@ const humanReadablePane = {
64
111
  return 'View';
65
112
  }
66
113
  if (hasContentTypeIn(kb, subject, allowed) || hasContentTypeIn2(kb, subject, allowed)) {
114
+ // For HTML files, check if it's dokieli (async check, store result for later)
115
+ const cts = kb.fetcher.getHeader(subject.doc(), 'content-type');
116
+ const ct = cts ? cts[0].split(';', 1)[0].trim() : null;
117
+ if (ct === 'text/html' && !dokieliCache.has(subject.uri)) {
118
+ // Async check for dokieli, don't wait for result
119
+ kb.fetcher._fetch(subject.uri).then(response => response.text()).then(text => {
120
+ const isDokieli = text.includes('<script src="https://dokie.li/scripts/dokieli.js">') || text.includes('dokieli.css');
121
+ dokieliCache.set(subject.uri, isDokieli ? 'dokieli' : 'html');
122
+ }).catch(() => {
123
+ dokieliCache.set(subject.uri, 'html');
124
+ });
125
+ }
67
126
  return 'View';
68
127
  }
69
128
  return null;
@@ -101,20 +160,10 @@ const humanReadablePane = {
101
160
  frame.innerHTML = '<p>Error loading content</p>';
102
161
  });
103
162
  };
104
- const setIframeAttributes = (frame, blob, lines) => {
105
- frame.setAttribute('src', URL.createObjectURL(blob));
106
- frame.setAttribute('type', blob.type);
163
+ const setIframeAttributes = (frame, lines) => {
164
+ frame.setAttribute('src', subject.uri);
107
165
  frame.setAttribute('class', 'doc');
108
166
  frame.setAttribute('style', `border: 1px solid; padding: 1em; height: ${lines}em; width: 800px; resize: both; overflow: auto;`);
109
-
110
- // Apply sandbox attribute only for HTML files
111
- // @@ Note below - if we set ANY sandbox, then Chrome and Safari won't display it if it is PDF.
112
- // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe
113
- // You can't have any sandbox and allow plugins.
114
- // We could sandbox only HTML files I suppose.
115
- if (blob.type === 'text/html' || blob.type === 'application/xhtml+xml') {
116
- frame.setAttribute('sandbox', 'allow-scripts allow-same-origin');
117
- }
118
167
  };
119
168
  if (isMarkdown) {
120
169
  // For markdown, use a DIV element and render the content
@@ -126,30 +175,26 @@ const humanReadablePane = {
126
175
  } else {
127
176
  // For other content types, use IFRAME
128
177
  const frame = myDocument.createElement('IFRAME');
129
- // Fetch and process the blob
130
- kb.fetcher._fetch(subject.uri).then(response => response.blob()).then(blob => {
131
- const blobTextPromise = blob.type.startsWith('text') ? blob.text() : Promise.resolve('');
132
- return blobTextPromise.then(blobText => ({
133
- blob,
134
- blobText
135
- }));
136
- }).then(({
137
- blob,
138
- blobText
139
- }) => {
178
+
179
+ // Apply sandbox for HTML/XHTML
180
+ if (ct === 'text/html' || ct === 'application/xhtml+xml') {
181
+ frame.setAttribute('sandbox', 'allow-scripts allow-same-origin allow-forms');
182
+ }
183
+
184
+ // Fetch content to calculate lines dynamically
185
+ kb.fetcher.webOperation('GET', subject.uri).then(response => {
186
+ const blobText = response.responseText;
140
187
  const newLines = blobText.includes('<script src="https://dokie.li/scripts/dokieli.js">') ? -10 : 5;
141
188
  const lines = Math.min(30, blobText.split(/\n/).length + newLines);
142
- // For text content, create a new blob with proper charset to avoid encoding warnings
143
- if (blob.type.startsWith('text/') && !blob.type.includes('charset')) {
144
- const newBlob = new Blob([blobText], {
145
- type: blob.type + '; charset=utf-8'
146
- });
147
- setIframeAttributes(frame, newBlob, lines);
148
- } else {
149
- setIframeAttributes(frame, blob, lines);
150
- }
151
- }).catch(err => {
152
- console.log('Error fetching or processing blob:', err);
189
+
190
+ // Cache dokieli detection result
191
+ const isDokieli = blobText.includes('<script src="https://dokie.li/scripts/dokieli.js">') || blobText.includes('dokieli.css');
192
+ dokieliCache.set(subject.uri, isDokieli ? 'dokieli' : 'html');
193
+ setIframeAttributes(frame, lines);
194
+ }).catch(error => {
195
+ console.error('Error fetching content for line calculation:', error);
196
+ // Fallback to default height
197
+ setIframeAttributes(frame, 30);
153
198
  });
154
199
  const tr = myDocument.createElement('TR');
155
200
  tr.appendChild(frame);
@@ -1 +1 @@
1
- {"version":3,"file":"humanReadablePane.js","names":["_solidUi","require","_rdflib","_marked","_dompurify","_interopRequireDefault","e","__esModule","default","isMarkdownFile","uri","path","split","test","humanReadablePane","icon","icons","originalIconBase","name","label","subject","context","kb","session","store","allowed","hasContentTypeIn","x","displayables","cts","fetcher","getHeader","j","length","k","indexOf","hasContentTypeIn2","t","findTypeURIs","Util","mediaTypeClass","ns","link","render","myDocument","dom","div","createElement","doc","ct","trim","isMarkdown","console","log","setAttribute","renderMarkdownContent","frame","webOperation","then","response","markdownText","responseText","lines","Math","min","res","marked","parse","clean","DOMPurify","sanitize","innerHTML","catch","error","setIframeAttributes","blob","URL","createObjectURL","type","tr","appendChild","_fetch","blobTextPromise","startsWith","text","Promise","resolve","blobText","newLines","includes","newBlob","Blob","err","_default","exports"],"sources":["../src/humanReadablePane.js"],"sourcesContent":["/* Human-readable Pane\n **\n ** This outline pane contains the document contents for an HTML document\n ** This is for peeking at a page, because the user might not want to leave the data browser.\n */\nimport { icons, ns } from 'solid-ui'\nimport { Util } from 'rdflib'\nimport { marked } from 'marked'\nimport DOMPurify from 'dompurify'\n\n// Helper function to check if a URI has a markdown file extension\nconst isMarkdownFile = (uri) => {\n if (!uri) return false\n const path = uri.split('?')[0].split('#')[0] // Remove query string and fragment\n return /\\.(md|markdown|mdown|mkd|mkdn)$/i.test(path)\n}\n\nconst humanReadablePane = {\n icon: icons.originalIconBase + 'tango/22-text-x-generic.png',\n\n name: 'humanReadable',\n\n label: function (subject, context) {\n const kb = context.session.store\n\n // See also the source pane, which has lower precedence.\n\n const allowed = [\n 'text/plain',\n 'text/html',\n 'text/markdown',\n 'application/xhtml+xml',\n 'image/png',\n 'image/jpeg',\n 'application/pdf',\n 'video/mp4'\n ]\n\n const hasContentTypeIn = function (kb, x, displayables) {\n const cts = kb.fetcher.getHeader(x, 'content-type')\n if (cts) {\n for (let j = 0; j < cts.length; j++) {\n for (let k = 0; k < displayables.length; k++) {\n if (cts[j].indexOf(displayables[k]) >= 0) {\n return true\n }\n }\n }\n }\n return false\n }\n\n // This data could come from a fetch OR from ldp container\n const hasContentTypeIn2 = function (kb, x, displayables) {\n const t = kb.findTypeURIs(x)\n for (let k = 0; k < displayables.length; k++) {\n if (Util.mediaTypeClass(displayables[k]).uri in t) {\n return true\n }\n }\n return false\n }\n\n if (!subject.uri) return null // no bnodes\n\n const t = kb.findTypeURIs(subject)\n if (t[ns.link('WebPage').uri]) return 'view'\n\n // Check file extension for markdown files\n if (isMarkdownFile(subject.uri)) {\n return 'View'\n }\n\n if (\n hasContentTypeIn(kb, subject, allowed) ||\n hasContentTypeIn2(kb, subject, allowed)\n ) {\n return 'View'\n }\n\n return null\n },\n\n render: function (subject, context) {\n const myDocument = context.dom\n const div = myDocument.createElement('div')\n const kb = context.session.store\n\n const cts = kb.fetcher.getHeader(subject.doc(), 'content-type')\n const ct = cts ? cts[0].split(';', 1)[0].trim() : null // remove content-type parameters\n\n // Fallback: detect markdown by file extension if content-type is not text/markdown\n const isMarkdown = ct === 'text/markdown' || isMarkdownFile(subject.uri)\n\n if (ct) {\n // console.log('humanReadablePane: c-t:' + ct)\n } else {\n console.log('humanReadablePane: unknown content-type?')\n }\n\n // @@ When we can, use CSP to turn off scripts within the iframe\n div.setAttribute('class', 'docView')\n\n // render markdown to html in a DIV element\n const renderMarkdownContent = function (frame) {\n kb.fetcher.webOperation('GET', subject.uri).then(response => {\n const markdownText = response.responseText\n const lines = Math.min(30, markdownText.split(/\\n/).length + 5)\n const res = marked.parse(markdownText)\n const clean = DOMPurify.sanitize(res)\n frame.innerHTML = clean\n frame.setAttribute('class', 'doc')\n frame.setAttribute('style', `border: 1px solid; padding: 1em; height: ${lines}em; width: 800px; resize: both; overflow: auto;`)\n }).catch(error => {\n console.error('Error fetching markdown content:', error)\n frame.innerHTML = '<p>Error loading content</p>'\n })\n }\n\n const setIframeAttributes = (frame, blob, lines) => {\n frame.setAttribute('src', URL.createObjectURL(blob))\n frame.setAttribute('type', blob.type)\n frame.setAttribute('class', 'doc')\n frame.setAttribute('style', `border: 1px solid; padding: 1em; height: ${lines}em; width: 800px; resize: both; overflow: auto;`)\n\n // Apply sandbox attribute only for HTML files\n // @@ Note below - if we set ANY sandbox, then Chrome and Safari won't display it if it is PDF.\n // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe\n // You can't have any sandbox and allow plugins.\n // We could sandbox only HTML files I suppose.\n if (blob.type === 'text/html' || blob.type === 'application/xhtml+xml') {\n frame.setAttribute('sandbox', 'allow-scripts allow-same-origin')\n }\n }\n\n if (isMarkdown) {\n // For markdown, use a DIV element and render the content\n const frame = myDocument.createElement('DIV')\n renderMarkdownContent(frame)\n const tr = myDocument.createElement('TR')\n tr.appendChild(frame)\n div.appendChild(tr)\n } else {\n // For other content types, use IFRAME\n const frame = myDocument.createElement('IFRAME')\n // Fetch and process the blob\n kb.fetcher._fetch(subject.uri)\n .then(response => response.blob())\n .then(blob => {\n const blobTextPromise = blob.type.startsWith('text') ? blob.text() : Promise.resolve('')\n return blobTextPromise.then(blobText => ({ blob, blobText }))\n })\n .then(({ blob, blobText }) => {\n const newLines = blobText.includes('<script src=\"https://dokie.li/scripts/dokieli.js\">') ? -10 : 5\n const lines = Math.min(30, blobText.split(/\\n/).length + newLines)\n // For text content, create a new blob with proper charset to avoid encoding warnings\n if (blob.type.startsWith('text/') && !blob.type.includes('charset')) {\n const newBlob = new Blob([blobText], { type: blob.type + '; charset=utf-8' })\n setIframeAttributes(frame, newBlob, lines)\n } else {\n setIframeAttributes(frame, blob, lines)\n }\n })\n .catch(err => {\n console.log('Error fetching or processing blob:', err)\n })\n const tr = myDocument.createElement('TR')\n tr.appendChild(frame)\n div.appendChild(tr)\n }\n\n return div\n }\n}\n\nexport default humanReadablePane\n// ends\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"humanReadablePane.js","names":["_solidUi","require","_rdflib","_marked","_dompurify","_interopRequireDefault","e","__esModule","default","isMarkdownFile","uri","path","split","test","dokieliCache","Map","humanReadablePane","icon","subject","context","icons","iconBase","kb","session","store","cachedResult","get","originalIconBase","responseText","fetcher","getHeader","doc","length","text","isDokieli","includes","set","cts","ct","trim","_fetch","then","response","catch","name","label","allowed","hasContentTypeIn","x","displayables","j","k","indexOf","hasContentTypeIn2","t","findTypeURIs","Util","mediaTypeClass","ns","link","has","render","myDocument","dom","div","createElement","isMarkdown","console","log","setAttribute","renderMarkdownContent","frame","webOperation","markdownText","lines","Math","min","res","marked","parse","clean","DOMPurify","sanitize","innerHTML","error","setIframeAttributes","tr","appendChild","blobText","newLines","_default","exports"],"sources":["../src/humanReadablePane.js"],"sourcesContent":["/* Human-readable Pane\n **\n ** This outline pane contains the document contents for an HTML document\n ** This is for peeking at a page, because the user might not want to leave the data browser.\n */\nimport { icons, ns } from 'solid-ui'\nimport { Util } from 'rdflib'\nimport { marked } from 'marked'\nimport DOMPurify from 'dompurify'\n\n// Helper function to check if a URI has a markdown file extension\nconst isMarkdownFile = (uri) => {\n if (!uri) return false\n const path = uri.split('?')[0].split('#')[0] // Remove query string and fragment\n return /\\.(md|markdown|mdown|mkd|mkdn)$/i.test(path)\n}\n\n// Cache for dokieli detection results (keyed by subject URI)\nconst dokieliCache = new Map()\n\nconst humanReadablePane = {\n icon: function (subject, context) {\n // Markdown files detected by extension\n if (subject && isMarkdownFile(subject.uri)) {\n return icons.iconBase + 'markdown.svg'\n }\n\n // Dokieli files detected by content check\n if (subject) {\n const kb = context.session.store\n\n // Check cache from previous detection\n const cachedResult = dokieliCache.get(subject.uri)\n if (cachedResult === 'dokieli') {\n return icons.iconBase + 'dokieli-logo.png'\n } else if (cachedResult === 'html') {\n return icons.originalIconBase + 'tango/22-text-x-generic.png'\n }\n\n // Check if content already fetched (synchronous)\n const responseText = kb.fetcher.getHeader(subject.doc(), 'content')\n if (responseText && responseText.length > 0) {\n const text = responseText[0]\n const isDokieli = text.includes('<script src=\"https://dokie.li/scripts/dokieli.js\">') ||\n text.includes('dokieli.css')\n dokieliCache.set(subject.uri, isDokieli ? 'dokieli' : 'html')\n return isDokieli\n ? icons.iconBase + 'dokieli-logo.png'\n : icons.originalIconBase + 'tango/22-text-x-generic.png'\n }\n\n // Content not yet fetched - return a promise (async detection)\n const cts = kb.fetcher.getHeader(subject.doc(), 'content-type')\n const ct = cts ? cts[0].split(';', 1)[0].trim() : null\n\n if (ct === 'text/html') {\n return kb.fetcher._fetch(subject.uri)\n .then(response => response.text())\n .then(text => {\n const isDokieli = text.includes('<script src=\"https://dokie.li/scripts/dokieli.js\">') ||\n text.includes('dokieli.css')\n dokieliCache.set(subject.uri, isDokieli ? 'dokieli' : 'html')\n return isDokieli\n ? icons.iconBase + 'dokieli-logo.png'\n : icons.originalIconBase + 'tango/22-text-x-generic.png'\n })\n .catch(() => {\n dokieliCache.set(subject.uri, 'html')\n return icons.originalIconBase + 'tango/22-text-x-generic.png'\n })\n }\n }\n\n // Default for all other human-readable content\n return icons.originalIconBase + 'tango/22-text-x-generic.png'\n },\n\n name: 'humanReadable',\n\n label: function (subject, context) {\n const kb = context.session.store\n\n // See also the source pane, which has lower precedence.\n\n const allowed = [\n 'text/plain',\n 'text/html',\n 'text/markdown',\n 'application/xhtml+xml',\n 'image/png',\n 'image/jpeg',\n 'application/pdf',\n 'video/mp4'\n ]\n\n const hasContentTypeIn = function (kb, x, displayables) {\n const cts = kb.fetcher.getHeader(x, 'content-type')\n if (cts) {\n for (let j = 0; j < cts.length; j++) {\n for (let k = 0; k < displayables.length; k++) {\n if (cts[j].indexOf(displayables[k]) >= 0) {\n return true\n }\n }\n }\n }\n return false\n }\n\n // This data could come from a fetch OR from ldp container\n const hasContentTypeIn2 = function (kb, x, displayables) {\n const t = kb.findTypeURIs(x)\n for (let k = 0; k < displayables.length; k++) {\n if (Util.mediaTypeClass(displayables[k]).uri in t) {\n return true\n }\n }\n return false\n }\n\n if (!subject.uri) return null // no bnodes\n\n const t = kb.findTypeURIs(subject)\n if (t[ns.link('WebPage').uri]) return 'view'\n\n // Check file extension for markdown files\n if (isMarkdownFile(subject.uri)) {\n return 'View'\n }\n\n if (\n hasContentTypeIn(kb, subject, allowed) ||\n hasContentTypeIn2(kb, subject, allowed)\n ) {\n // For HTML files, check if it's dokieli (async check, store result for later)\n const cts = kb.fetcher.getHeader(subject.doc(), 'content-type')\n const ct = cts ? cts[0].split(';', 1)[0].trim() : null\n\n if (ct === 'text/html' && !dokieliCache.has(subject.uri)) {\n // Async check for dokieli, don't wait for result\n kb.fetcher._fetch(subject.uri)\n .then(response => response.text())\n .then(text => {\n const isDokieli = text.includes('<script src=\"https://dokie.li/scripts/dokieli.js\">') ||\n text.includes('dokieli.css')\n dokieliCache.set(subject.uri, isDokieli ? 'dokieli' : 'html')\n })\n .catch(() => {\n dokieliCache.set(subject.uri, 'html')\n })\n }\n\n return 'View'\n }\n\n return null\n },\n\n render: function (subject, context) {\n const myDocument = context.dom\n const div = myDocument.createElement('div')\n const kb = context.session.store\n\n const cts = kb.fetcher.getHeader(subject.doc(), 'content-type')\n const ct = cts ? cts[0].split(';', 1)[0].trim() : null // remove content-type parameters\n\n // Fallback: detect markdown by file extension if content-type is not text/markdown\n const isMarkdown = ct === 'text/markdown' || isMarkdownFile(subject.uri)\n\n if (ct) {\n // console.log('humanReadablePane: c-t:' + ct)\n } else {\n console.log('humanReadablePane: unknown content-type?')\n }\n\n // @@ When we can, use CSP to turn off scripts within the iframe\n div.setAttribute('class', 'docView')\n\n // render markdown to html in a DIV element\n const renderMarkdownContent = function (frame) {\n kb.fetcher.webOperation('GET', subject.uri).then(response => {\n const markdownText = response.responseText\n const lines = Math.min(30, markdownText.split(/\\n/).length + 5)\n const res = marked.parse(markdownText)\n const clean = DOMPurify.sanitize(res)\n frame.innerHTML = clean\n frame.setAttribute('class', 'doc')\n frame.setAttribute('style', `border: 1px solid; padding: 1em; height: ${lines}em; width: 800px; resize: both; overflow: auto;`)\n }).catch(error => {\n console.error('Error fetching markdown content:', error)\n frame.innerHTML = '<p>Error loading content</p>'\n })\n }\n\n const setIframeAttributes = (frame, lines) => {\n frame.setAttribute('src', subject.uri)\n frame.setAttribute('class', 'doc')\n frame.setAttribute('style', `border: 1px solid; padding: 1em; height: ${lines}em; width: 800px; resize: both; overflow: auto;`)\n }\n\n if (isMarkdown) {\n // For markdown, use a DIV element and render the content\n const frame = myDocument.createElement('DIV')\n renderMarkdownContent(frame)\n const tr = myDocument.createElement('TR')\n tr.appendChild(frame)\n div.appendChild(tr)\n } else {\n // For other content types, use IFRAME\n const frame = myDocument.createElement('IFRAME')\n\n // Apply sandbox for HTML/XHTML\n if (ct === 'text/html' || ct === 'application/xhtml+xml') {\n frame.setAttribute('sandbox', 'allow-scripts allow-same-origin allow-forms')\n }\n\n // Fetch content to calculate lines dynamically\n kb.fetcher.webOperation('GET', subject.uri).then(response => {\n const blobText = response.responseText\n const newLines = blobText.includes('<script src=\"https://dokie.li/scripts/dokieli.js\">') ? -10 : 5\n const lines = Math.min(30, blobText.split(/\\n/).length + newLines)\n\n // Cache dokieli detection result\n const isDokieli = blobText.includes('<script src=\"https://dokie.li/scripts/dokieli.js\">') ||\n blobText.includes('dokieli.css')\n dokieliCache.set(subject.uri, isDokieli ? 'dokieli' : 'html')\n\n setIframeAttributes(frame, lines)\n }).catch(error => {\n console.error('Error fetching content for line calculation:', error)\n // Fallback to default height\n setIframeAttributes(frame, 30)\n })\n\n const tr = myDocument.createElement('TR')\n tr.appendChild(frame)\n div.appendChild(tr)\n }\n\n return div\n }\n}\n\nexport default humanReadablePane\n// ends\n"],"mappings":"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","ignoreList":[]}
@@ -500,7 +500,17 @@ function _default(context) {
500
500
  // if only one, simplify interface
501
501
  relevantPanes.forEach((pane, index) => {
502
502
  const label = pane.label(subject, context);
503
- const ico = UI.utils.AJARImage(pane.icon, label, label, dom);
503
+ const iconSrc = typeof pane.icon === 'function' ? pane.icon(subject, context) : pane.icon;
504
+ const ico = UI.utils.AJARImage(iconSrc, label, label, dom);
505
+
506
+ // Handle async icon functions
507
+ if (iconSrc instanceof Promise) {
508
+ iconSrc.then(resolvedIconSrc => {
509
+ ico.setAttribute('src', resolvedIconSrc);
510
+ }).catch(err => {
511
+ console.error('Error resolving async icon:', err);
512
+ });
513
+ }
504
514
  ico.style = pane === tr.firstPane ? paneShownStyle : paneHiddenStyle; // init to something at least
505
515
  // ico.setAttribute('align','right'); @@ Should be better, but ffox bug pushes them down
506
516
  // ico.style.width = iconHeight