solid-panes 4.0.0 → 4.1.0-120fc635

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.
@@ -1 +1 @@
1
- {"version":3,"file":"dashboardPane.d.ts","sourceRoot":"","sources":["../../src/dashboard/dashboardPane.ts"],"names":[],"mappings":"AAIA,OAAO,EAAsB,cAAc,EAAE,MAAM,eAAe,CAAA;AAElE,eAAO,MAAM,aAAa,EAAE,cAqC3B,CAAA;AAuCD,eAAe,aAAa,CAAA"}
1
+ {"version":3,"file":"dashboardPane.d.ts","sourceRoot":"","sources":["../../src/dashboard/dashboardPane.ts"],"names":[],"mappings":"AAIA,OAAO,EAAsB,cAAc,EAAE,MAAM,eAAe,CAAA;AAElE,eAAO,MAAM,aAAa,EAAE,cAoC3B,CAAA;AAuCD,eAAe,aAAa,CAAA"}
@@ -11,8 +11,7 @@ const dashboardPane = exports.dashboardPane = {
11
11
  icon: _solidUi.icons.iconBase + 'noun_547570.svg',
12
12
  name: 'dashboard',
13
13
  label: subject => {
14
- console.log();
15
- if (subject.uri === subject.site().uri) {
14
+ if (subject.termType === 'NamedNode' && subject.uri === subject.site().uri) {
16
15
  return 'Dashboard';
17
16
  }
18
17
  return null;
@@ -1 +1 @@
1
- {"version":3,"file":"dashboardPane.js","names":["_solidUi","require","_solidLogic","_homepage","dashboardPane","exports","icon","icons","iconBase","name","label","subject","console","log","uri","site","render","context","dom","container","createElement","runBuildPage","innerHTML","buildPage","authn","currentUser","authSession","events","on","webId","URL","window","location","href","searchParams","get","buildDashboard","buildHomePage","outliner","getOutliner","getDashboard","then","dashboard","appendChild","wrapper","document","shadow","attachShadow","mode","link","rel","generateHomepage","store","fetcher","homepage","_default","default"],"sources":["../../src/dashboard/dashboardPane.ts"],"sourcesContent":["import { icons } from 'solid-ui'\nimport { authn, authSession, store } from 'solid-logic'\nimport { Fetcher, NamedNode } from 'rdflib'\nimport { generateHomepage } from './homepage'\nimport { DataBrowserContext, PaneDefinition } from 'pane-registry'\n\nexport const dashboardPane: PaneDefinition = {\n icon: icons.iconBase + 'noun_547570.svg',\n name: 'dashboard',\n label: subject => {\n console.log()\n if (subject.uri === subject.site().uri) {\n return 'Dashboard'\n }\n return null\n },\n render: (subject, context) => {\n console.log('Dashboard Pane Render')\n const dom = context.dom\n const container = dom.createElement('div')\n const runBuildPage = () => {\n container.innerHTML = ''\n buildPage(\n container,\n authn.currentUser() || null,\n context,\n subject\n )\n }\n\n authSession.events.on('login', () => {\n // console.log('On Login')\n runBuildPage()\n })\n authSession.events.on('sessionRestore', () => {\n // console.log('On Session Restore')\n runBuildPage()\n })\n // console.log('Initial Load')\n runBuildPage()\n\n return container\n }\n}\n\nfunction buildPage (\n container: HTMLElement,\n webId: NamedNode | null,\n context: DataBrowserContext,\n subject: NamedNode\n) {\n // if uri then SolidOS is a browse.html web app\n const uri = (new URL(window.location.href)).searchParams.get('uri')\n if (webId && (uri || webId.site().uri === subject.site().uri)) {\n return buildDashboard(container, context)\n }\n return buildHomePage(container, subject)\n}\n\nfunction buildDashboard (container: HTMLElement, context: DataBrowserContext) {\n // console.log('build dashboard')\n // @@ TODO get a proper type\n const outliner: any = context.getOutliner(context.dom)\n outliner\n .getDashboard()\n .then((dashboard: HTMLElement) => container.appendChild(dashboard))\n}\n\nfunction buildHomePage (container: HTMLElement, subject: NamedNode) {\n // console.log('build home page')\n const wrapper = document.createElement('div')\n container.appendChild(wrapper)\n const shadow = wrapper.attachShadow({ mode: 'open' })\n const link = document.createElement('link')\n link.rel = 'stylesheet'\n link.href = '/common/css/bootstrap.min.css'\n shadow.appendChild(link)\n generateHomepage(subject, store, store.fetcher as Fetcher).then(homepage =>\n shadow.appendChild(homepage)\n )\n}\n\nexport default dashboardPane\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"dashboardPane.js","names":["_solidUi","require","_solidLogic","_homepage","dashboardPane","exports","icon","icons","iconBase","name","label","subject","termType","uri","site","render","context","console","log","dom","container","createElement","runBuildPage","innerHTML","buildPage","authn","currentUser","authSession","events","on","webId","URL","window","location","href","searchParams","get","buildDashboard","buildHomePage","outliner","getOutliner","getDashboard","then","dashboard","appendChild","wrapper","document","shadow","attachShadow","mode","link","rel","generateHomepage","store","fetcher","homepage","_default","default"],"sources":["../../src/dashboard/dashboardPane.ts"],"sourcesContent":["import { icons } from 'solid-ui'\nimport { authn, authSession, store } from 'solid-logic'\nimport { Fetcher, NamedNode } from 'rdflib'\nimport { generateHomepage } from './homepage'\nimport { DataBrowserContext, PaneDefinition } from 'pane-registry'\n\nexport const dashboardPane: PaneDefinition = {\n icon: icons.iconBase + 'noun_547570.svg',\n name: 'dashboard',\n label: subject => {\n if (subject.termType === 'NamedNode' && subject.uri === subject.site().uri) {\n return 'Dashboard'\n }\n return null\n },\n render: (subject, context) => {\n console.log('Dashboard Pane Render')\n const dom = context.dom\n const container = dom.createElement('div')\n const runBuildPage = () => {\n container.innerHTML = ''\n buildPage(\n container,\n authn.currentUser() || null,\n context,\n subject\n )\n }\n\n authSession.events.on('login', () => {\n // console.log('On Login')\n runBuildPage()\n })\n authSession.events.on('sessionRestore', () => {\n // console.log('On Session Restore')\n runBuildPage()\n })\n // console.log('Initial Load')\n runBuildPage()\n\n return container\n }\n}\n\nfunction buildPage (\n container: HTMLElement,\n webId: NamedNode | null,\n context: DataBrowserContext,\n subject: NamedNode\n) {\n // if uri then SolidOS is a browse.html web app\n const uri = (new URL(window.location.href)).searchParams.get('uri')\n if (webId && (uri || webId.site().uri === subject.site().uri)) {\n return buildDashboard(container, context)\n }\n return buildHomePage(container, subject)\n}\n\nfunction buildDashboard (container: HTMLElement, context: DataBrowserContext) {\n // console.log('build dashboard')\n // @@ TODO get a proper type\n const outliner: any = context.getOutliner(context.dom)\n outliner\n .getDashboard()\n .then((dashboard: HTMLElement) => container.appendChild(dashboard))\n}\n\nfunction buildHomePage (container: HTMLElement, subject: NamedNode) {\n // console.log('build home page')\n const wrapper = document.createElement('div')\n container.appendChild(wrapper)\n const shadow = wrapper.attachShadow({ mode: 'open' })\n const link = document.createElement('link')\n link.rel = 'stylesheet'\n link.href = '/common/css/bootstrap.min.css'\n shadow.appendChild(link)\n generateHomepage(subject, store, store.fetcher as Fetcher).then(homepage =>\n shadow.appendChild(homepage)\n )\n}\n\nexport default dashboardPane\n"],"mappings":"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","ignoreList":[]}
@@ -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":[]}
@@ -15,8 +15,61 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
15
15
  ** This is for peeking at a page, because the user might not want to leave the data browser.
16
16
  */
17
17
 
18
+ // Helper function to check if a URI has a markdown file extension
19
+ const isMarkdownFile = uri => {
20
+ if (!uri) return false;
21
+ const path = uri.split('?')[0].split('#')[0]; // Remove query string and fragment
22
+ return /\.(md|markdown|mdown|mkd|mkdn)$/i.test(path);
23
+ };
24
+
25
+ // Cache for dokieli detection results (keyed by subject URI)
26
+ const dokieliCache = new Map();
18
27
  const humanReadablePane = {
19
- 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
+ },
20
73
  name: 'humanReadable',
21
74
  label: function (subject, context) {
22
75
  const kb = context.session.store;
@@ -52,7 +105,24 @@ const humanReadablePane = {
52
105
 
53
106
  const t = kb.findTypeURIs(subject);
54
107
  if (t[_solidUi.ns.link('WebPage').uri]) return 'view';
108
+
109
+ // Check file extension for markdown files
110
+ if (isMarkdownFile(subject.uri)) {
111
+ return 'View';
112
+ }
55
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
+ }
56
126
  return 'View';
57
127
  }
58
128
  return null;
@@ -63,6 +133,9 @@ const humanReadablePane = {
63
133
  const kb = context.session.store;
64
134
  const cts = kb.fetcher.getHeader(subject.doc(), 'content-type');
65
135
  const ct = cts ? cts[0].split(';', 1)[0].trim() : null; // remove content-type parameters
136
+
137
+ // Fallback: detect markdown by file extension if content-type is not text/markdown
138
+ const isMarkdown = ct === 'text/markdown' || isMarkdownFile(subject.uri);
66
139
  if (ct) {
67
140
  // console.log('humanReadablePane: c-t:' + ct)
68
141
  } else {
@@ -71,26 +144,9 @@ const humanReadablePane = {
71
144
 
72
145
  // @@ When we can, use CSP to turn off scripts within the iframe
73
146
  div.setAttribute('class', 'docView');
74
- const element = ct === 'text/markdown' ? 'DIV' : 'IFRAME';
75
- const frame = myDocument.createElement(element);
76
- const setIframeAttributes = (frame, blob, lines) => {
77
- frame.setAttribute('src', URL.createObjectURL(blob));
78
- frame.setAttribute('type', blob.type);
79
- frame.setAttribute('class', 'doc');
80
- frame.setAttribute('style', `border: 1px solid; padding: 1em; height: ${lines}em; width: 800px; resize: both; overflow: auto;`);
81
147
 
82
- // Apply sandbox attribute only for HTML files
83
- // @@ Note below - if we set ANY sandbox, then Chrome and Safari won't display it if it is PDF.
84
- // https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe
85
- // You can't have any sandbox and allow plugins.
86
- // We could sandbox only HTML files I suppose.
87
- if (blob.type === 'text/html' || blob.type === 'application/xhtml+xml') {
88
- frame.setAttribute('sandbox', 'allow-scripts allow-same-origin');
89
- }
90
- };
91
-
92
- // render markdown to html
93
- const markdownHtml = function () {
148
+ // render markdown to html in a DIV element
149
+ const renderMarkdownContent = function (frame) {
94
150
  kb.fetcher.webOperation('GET', subject.uri).then(response => {
95
151
  const markdownText = response.responseText;
96
152
  const lines = Math.min(30, markdownText.split(/\n/).length + 5);
@@ -104,30 +160,46 @@ const humanReadablePane = {
104
160
  frame.innerHTML = '<p>Error loading content</p>';
105
161
  });
106
162
  };
107
- if (ct === 'text/markdown') {
108
- markdownHtml();
163
+ const setIframeAttributes = (frame, lines) => {
164
+ frame.setAttribute('src', subject.uri);
165
+ frame.setAttribute('class', 'doc');
166
+ frame.setAttribute('style', `border: 1px solid; padding: 1em; height: ${lines}em; width: 800px; resize: both; overflow: auto;`);
167
+ };
168
+ if (isMarkdown) {
169
+ // For markdown, use a DIV element and render the content
170
+ const frame = myDocument.createElement('DIV');
171
+ renderMarkdownContent(frame);
172
+ const tr = myDocument.createElement('TR');
173
+ tr.appendChild(frame);
174
+ div.appendChild(tr);
109
175
  } else {
110
- // Fetch and process the blob
111
- kb.fetcher._fetch(subject.uri).then(response => response.blob()).then(blob => {
112
- const blobTextPromise = blob.type.startsWith('text') ? blob.text() : Promise.resolve('');
113
- return blobTextPromise.then(blobText => ({
114
- blob,
115
- blobText
116
- }));
117
- }).then(({
118
- blob,
119
- blobText
120
- }) => {
176
+ // For other content types, use IFRAME
177
+ const frame = myDocument.createElement('IFRAME');
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;
121
187
  const newLines = blobText.includes('<script src="https://dokie.li/scripts/dokieli.js">') ? -10 : 5;
122
188
  const lines = Math.min(30, blobText.split(/\n/).length + newLines);
123
- setIframeAttributes(frame, blob, lines);
124
- }).catch(err => {
125
- 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);
126
198
  });
199
+ const tr = myDocument.createElement('TR');
200
+ tr.appendChild(frame);
201
+ div.appendChild(tr);
127
202
  }
128
- const tr = myDocument.createElement('TR');
129
- tr.appendChild(frame);
130
- div.appendChild(tr);
131
203
  return div;
132
204
  }
133
205
  };
@@ -1 +1 @@
1
- {"version":3,"file":"humanReadablePane.js","names":["_solidUi","require","_rdflib","_marked","_dompurify","_interopRequireDefault","e","__esModule","default","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","uri","ns","link","render","myDocument","dom","div","createElement","doc","ct","split","trim","console","log","setAttribute","element","frame","setIframeAttributes","blob","lines","URL","createObjectURL","type","markdownHtml","webOperation","then","response","markdownText","responseText","Math","min","res","marked","parse","clean","DOMPurify","sanitize","innerHTML","catch","error","_fetch","blobTextPromise","startsWith","text","Promise","resolve","blobText","newLines","includes","err","tr","appendChild","_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\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 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 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 const element = ct === 'text/markdown' ? 'DIV' : 'IFRAME'\n const frame = myDocument.createElement(element)\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 // render markdown to html\n const markdownHtml = function () {\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 if (ct === 'text/markdown') {\n markdownHtml()\n } else {\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(frame, blob, lines)\n })\n .catch(err => {\n console.log('Error fetching or processing blob:', err)\n })\n }\n\n const tr = myDocument.createElement('TR')\n tr.appendChild(frame)\n div.appendChild(tr)\n return div\n }\n}\n\nexport default humanReadablePane\n// ends\n"],"mappings":";;;;;;AAKA,IAAAA,QAAA,GAAAC,OAAA;AACA,IAAAC,OAAA,GAAAD,OAAA;AACA,IAAAE,OAAA,GAAAF,OAAA;AACA,IAAAG,UAAA,GAAAC,sBAAA,CAAAJ,OAAA;AAAiC,SAAAI,uBAAAC,CAAA,WAAAA,CAAA,IAAAA,CAAA,CAAAC,UAAA,GAAAD,CAAA,KAAAE,OAAA,EAAAF,CAAA;AARjC;AACA;AACA;AACA;AACA;;AAMA,MAAMG,iBAAiB,GAAG;EACxBC,IAAI,EAAEC,cAAK,CAACC,gBAAgB,GAAG,6BAA6B;EAE5DC,IAAI,EAAE,eAAe;EAErBC,KAAK,EAAE,SAAAA,CAAUC,OAAO,EAAEC,OAAO,EAAE;IACjC,MAAMC,EAAE,GAAGD,OAAO,CAACE,OAAO,CAACC,KAAK;;IAEhC;;IAEA,MAAMC,OAAO,GAAG,CACd,YAAY,EACZ,WAAW,EACX,eAAe,EACf,uBAAuB,EACvB,WAAW,EACX,YAAY,EACZ,iBAAiB,EACjB,WAAW,CACZ;IAED,MAAMC,gBAAgB,GAAG,SAAAA,CAAUJ,EAAE,EAAEK,CAAC,EAAEC,YAAY,EAAE;MACtD,MAAMC,GAAG,GAAGP,EAAE,CAACQ,OAAO,CAACC,SAAS,CAACJ,CAAC,EAAE,cAAc,CAAC;MACnD,IAAIE,GAAG,EAAE;QACP,KAAK,IAAIG,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGH,GAAG,CAACI,MAAM,EAAED,CAAC,EAAE,EAAE;UACnC,KAAK,IAAIE,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGN,YAAY,CAACK,MAAM,EAAEC,CAAC,EAAE,EAAE;YAC5C,IAAIL,GAAG,CAACG,CAAC,CAAC,CAACG,OAAO,CAACP,YAAY,CAACM,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE;cACxC,OAAO,IAAI;YACb;UACF;QACF;MACF;MACA,OAAO,KAAK;IACd,CAAC;;IAED;IACA,MAAME,iBAAiB,GAAG,SAAAA,CAAUd,EAAE,EAAEK,CAAC,EAAEC,YAAY,EAAE;MACvD,MAAMS,CAAC,GAAGf,EAAE,CAACgB,YAAY,CAACX,CAAC,CAAC;MAC5B,KAAK,IAAIO,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGN,YAAY,CAACK,MAAM,EAAEC,CAAC,EAAE,EAAE;QAC5C,IAAIK,YAAI,CAACC,cAAc,CAACZ,YAAY,CAACM,CAAC,CAAC,CAAC,CAACO,GAAG,IAAIJ,CAAC,EAAE;UACjD,OAAO,IAAI;QACb;MACF;MACA,OAAO,KAAK;IACd,CAAC;IAED,IAAI,CAACjB,OAAO,CAACqB,GAAG,EAAE,OAAO,IAAI,EAAC;;IAE9B,MAAMJ,CAAC,GAAGf,EAAE,CAACgB,YAAY,CAAClB,OAAO,CAAC;IAClC,IAAIiB,CAAC,CAACK,WAAE,CAACC,IAAI,CAAC,SAAS,CAAC,CAACF,GAAG,CAAC,EAAE,OAAO,MAAM;IAE5C,IACEf,gBAAgB,CAACJ,EAAE,EAAEF,OAAO,EAAEK,OAAO,CAAC,IACtCW,iBAAiB,CAACd,EAAE,EAAEF,OAAO,EAAEK,OAAO,CAAC,EACvC;MACA,OAAO,MAAM;IACf;IAEA,OAAO,IAAI;EACb,CAAC;EAEDmB,MAAM,EAAE,SAAAA,CAAUxB,OAAO,EAAEC,OAAO,EAAE;IAClC,MAAMwB,UAAU,GAAGxB,OAAO,CAACyB,GAAG;IAC9B,MAAMC,GAAG,GAAGF,UAAU,CAACG,aAAa,CAAC,KAAK,CAAC;IAC3C,MAAM1B,EAAE,GAAGD,OAAO,CAACE,OAAO,CAACC,KAAK;IAEhC,MAAMK,GAAG,GAAGP,EAAE,CAACQ,OAAO,CAACC,SAAS,CAACX,OAAO,CAAC6B,GAAG,CAAC,CAAC,EAAE,cAAc,CAAC;IAC/D,MAAMC,EAAE,GAAGrB,GAAG,GAAGA,GAAG,CAAC,CAAC,CAAC,CAACsB,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAACC,IAAI,CAAC,CAAC,GAAG,IAAI,EAAC;IACvD,IAAIF,EAAE,EAAE;MACN;IAAA,CACD,MAAM;MACLG,OAAO,CAACC,GAAG,CAAC,0CAA0C,CAAC;IACzD;;IAEA;IACAP,GAAG,CAACQ,YAAY,CAAC,OAAO,EAAE,SAAS,CAAC;IACpC,MAAMC,OAAO,GAAGN,EAAE,KAAK,eAAe,GAAG,KAAK,GAAG,QAAQ;IACzD,MAAMO,KAAK,GAAGZ,UAAU,CAACG,aAAa,CAACQ,OAAO,CAAC;IAE/C,MAAME,mBAAmB,GAAGA,CAACD,KAAK,EAAEE,IAAI,EAAEC,KAAK,KAAK;MAClDH,KAAK,CAACF,YAAY,CAAC,KAAK,EAAEM,GAAG,CAACC,eAAe,CAACH,IAAI,CAAC,CAAC;MACpDF,KAAK,CAACF,YAAY,CAAC,MAAM,EAAEI,IAAI,CAACI,IAAI,CAAC;MACrCN,KAAK,CAACF,YAAY,CAAC,OAAO,EAAE,KAAK,CAAC;MAClCE,KAAK,CAACF,YAAY,CAAC,OAAO,EAAE,4CAA4CK,KAAK,iDAAiD,CAAC;;MAE/H;MACA;MACA;MACA;MACA;MACA,IAAID,IAAI,CAACI,IAAI,KAAK,WAAW,IAAIJ,IAAI,CAACI,IAAI,KAAK,uBAAuB,EAAE;QACtEN,KAAK,CAACF,YAAY,CAAC,SAAS,EAAE,iCAAiC,CAAC;MAClE;IACF,CAAC;;IAED;IACA,MAAMS,YAAY,GAAG,SAAAA,CAAA,EAAY;MAC/B1C,EAAE,CAACQ,OAAO,CAACmC,YAAY,CAAC,KAAK,EAAE7C,OAAO,CAACqB,GAAG,CAAC,CAACyB,IAAI,CAACC,QAAQ,IAAI;QAC3D,MAAMC,YAAY,GAAGD,QAAQ,CAACE,YAAY;QAC1C,MAAMT,KAAK,GAAGU,IAAI,CAACC,GAAG,CAAC,EAAE,EAAEH,YAAY,CAACjB,KAAK,CAAC,IAAI,CAAC,CAAClB,MAAM,GAAG,CAAC,CAAC;QAC/D,MAAMuC,GAAG,GAAGC,cAAM,CAACC,KAAK,CAACN,YAAY,CAAC;QACtC,MAAMO,KAAK,GAAGC,kBAAS,CAACC,QAAQ,CAACL,GAAG,CAAC;QACrCf,KAAK,CAACqB,SAAS,GAAGH,KAAK;QACvBlB,KAAK,CAACF,YAAY,CAAC,OAAO,EAAE,KAAK,CAAC;QAClCE,KAAK,CAACF,YAAY,CAAC,OAAO,EAAE,4CAA4CK,KAAK,iDAAiD,CAAC;MACjI,CAAC,CAAC,CAACmB,KAAK,CAACC,KAAK,IAAI;QAChB3B,OAAO,CAAC2B,KAAK,CAAC,kCAAkC,EAAEA,KAAK,CAAC;QACxDvB,KAAK,CAACqB,SAAS,GAAG,8BAA8B;MAClD,CAAC,CAAC;IACJ,CAAC;IAED,IAAI5B,EAAE,KAAK,eAAe,EAAE;MAC1Bc,YAAY,CAAC,CAAC;IAChB,CAAC,MAAM;MACP;MACE1C,EAAE,CAACQ,OAAO,CAACmD,MAAM,CAAC7D,OAAO,CAACqB,GAAG,CAAC,CAC3ByB,IAAI,CAACC,QAAQ,IAAIA,QAAQ,CAACR,IAAI,CAAC,CAAC,CAAC,CACjCO,IAAI,CAACP,IAAI,IAAI;QACZ,MAAMuB,eAAe,GAAGvB,IAAI,CAACI,IAAI,CAACoB,UAAU,CAAC,MAAM,CAAC,GAAGxB,IAAI,CAACyB,IAAI,CAAC,CAAC,GAAGC,OAAO,CAACC,OAAO,CAAC,EAAE,CAAC;QACxF,OAAOJ,eAAe,CAAChB,IAAI,CAACqB,QAAQ,KAAK;UAAE5B,IAAI;UAAE4B;QAAS,CAAC,CAAC,CAAC;MAC/D,CAAC,CAAC,CACDrB,IAAI,CAAC,CAAC;QAAEP,IAAI;QAAE4B;MAAS,CAAC,KAAK;QAC5B,MAAMC,QAAQ,GAAGD,QAAQ,CAACE,QAAQ,CAAC,oDAAoD,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC;QAClG,MAAM7B,KAAK,GAAGU,IAAI,CAACC,GAAG,CAAC,EAAE,EAAEgB,QAAQ,CAACpC,KAAK,CAAC,IAAI,CAAC,CAAClB,MAAM,GAAGuD,QAAQ,CAAC;QAClE9B,mBAAmB,CAACD,KAAK,EAAEE,IAAI,EAAEC,KAAK,CAAC;MACzC,CAAC,CAAC,CACDmB,KAAK,CAACW,GAAG,IAAI;QACZrC,OAAO,CAACC,GAAG,CAAC,oCAAoC,EAAEoC,GAAG,CAAC;MACxD,CAAC,CAAC;IACN;IAEA,MAAMC,EAAE,GAAG9C,UAAU,CAACG,aAAa,CAAC,IAAI,CAAC;IACzC2C,EAAE,CAACC,WAAW,CAACnC,KAAK,CAAC;IACrBV,GAAG,CAAC6C,WAAW,CAACD,EAAE,CAAC;IACnB,OAAO5C,GAAG;EACZ;AACF,CAAC;AAAA,IAAA8C,QAAA,GAAAC,OAAA,CAAAjF,OAAA,GAEcC,iBAAiB,EAChC","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":[]}
@@ -203,7 +203,7 @@ function _default(context) {
203
203
  // some choices of predicate
204
204
  lab = UI.utils.predicateLabelForXML(predicate.elements[0], inverse);
205
205
  }
206
- lab = lab.slice(0, 1).toUpperCase() + lab.slice(1);
206
+ lab = lab ? lab.slice(0, 1).toUpperCase() + lab.slice(1) : '...';
207
207
  // if (kb.statementsMatching(predicate,rdf('type'), UI.ns.link('Request')).length) predicateTD.className='undetermined';
208
208
 
209
209
  const labelTD = dom.createElement('TD');
@@ -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