Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 18 additions & 10 deletions src/humanReadablePane.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
** This outline pane contains the document contents for an HTML document
** This is for peeking at a page, because the user might not want to leave the data browser.
*/
import { icons, ns } from 'solid-ui'
import { ns } from 'solid-ui'
import { lucideIcons } from './icons/lucide'
import { Util } from 'rdflib'
import { marked } from 'marked'
import DOMPurify from 'dompurify'
Expand Down Expand Up @@ -47,7 +48,14 @@ const humanReadablePane: HumanReadablePaneDefinition = {
icon: function (subject: NamedNode, context: DataBrowserContext): HumanReadableIcon {
// Markdown files detected by extension
if (subject && isMarkdownFile(subject.uri)) {
return icons.iconBase + 'markdown.svg'
// lucide file-text — https://lucide.dev/icons/file-text (ISC license)
return 'data:image/svg+xml;utf8,' + encodeURIComponent(
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">' +
'<path d="M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z"/>' +
'<path d="M14 2v5a1 1 0 0 0 1 1h5"/>' +
'<path d="M10 9H8"/><path d="M16 13H8"/><path d="M16 17H8"/>' +
'</svg>'
)
}

// Dokieli files detected by content check
Expand All @@ -57,9 +65,9 @@ const humanReadablePane: HumanReadablePaneDefinition = {
// Check cache from previous detection
const cachedResult = dokieliCache.get(subject.uri)
if (cachedResult === 'dokieli') {
return icons.iconBase + 'dokieli-logo.png'
return lucideIcons.filePen /* was dokieli-logo.png */
} else if (cachedResult === 'html') {
return icons.originalIconBase + 'tango/22-text-x-generic.png'
return lucideIcons.info /* was tango/22-text-x-generic.png — generic HTML doc */
}

// Check if content already fetched (synchronous)
Expand All @@ -70,8 +78,8 @@ const humanReadablePane: HumanReadablePaneDefinition = {
text.includes('dokieli.css')
dokieliCache.set(subject.uri, isDokieli ? 'dokieli' : 'html')
return isDokieli
? icons.iconBase + 'dokieli-logo.png'
: icons.originalIconBase + 'tango/22-text-x-generic.png'
? lucideIcons.filePen /* was dokieli-logo.png */
: lucideIcons.info /* was tango/22-text-x-generic.png — generic HTML doc */
}

// Content not yet fetched - return a promise (async detection)
Expand All @@ -86,18 +94,18 @@ const humanReadablePane: HumanReadablePaneDefinition = {
text.includes('dokieli.css')
dokieliCache.set(subject.uri, isDokieli ? 'dokieli' : 'html')
return isDokieli
? icons.iconBase + 'dokieli-logo.png'
: icons.originalIconBase + 'tango/22-text-x-generic.png'
? lucideIcons.filePen /* was dokieli-logo.png */
: lucideIcons.info /* was tango/22-text-x-generic.png — generic HTML doc */
})
.catch(() => {
dokieliCache.set(subject.uri, 'html')
return icons.originalIconBase + 'tango/22-text-x-generic.png'
return lucideIcons.info /* was tango/22-text-x-generic.png — generic HTML doc */
})
}
}

// Default for all other human-readable content
return icons.originalIconBase + 'tango/22-text-x-generic.png'
return lucideIcons.info /* was tango/22-text-x-generic.png — generic HTML doc */
},

name: 'humanReadable',
Expand Down
130 changes: 117 additions & 13 deletions src/outline/manager.css
Original file line number Diff line number Diff line change
@@ -1,14 +1,73 @@
/* Styles extracted from manager.js */

.obj {
margin: 0.2em;
border: none;
padding: 0;
vertical-align: top;
}

.pred, .pred.internal {
/* Add any specific styles for predicate TDs here */
/* Real data tables (dataContentPane's internal property tree).
These are legitimate <table>s, so just give them consistent inter-cell spacing. */
.tableFullWidth,
.collectionAsTables {
border-collapse: separate;
border-spacing: var(--spacing-sm, 0.5rem);
}

/* rdf:List rendering: ordered list using the browser's native numbering. */
.rdf-collection {
margin: 0;
padding-left: 2em; /* room for the native marker */
}
.rdf-collection > li {
padding: 0.1em 0;
}
.rdf-collection > li::marker {
color: var(--color-text-muted, #6B7280);
}

/* Description list of a subject's predicates and values, emitted by appendPropertyTRs.
The two-column visual layout is purely presentational — semantically it stays a <dl>. */
.property-list {
display: grid;
grid-template-columns: minmax(8rem, max-content) 1fr;
gap: 0.35em var(--spacing-sm, 0.5rem);
margin: 0;
align-items: start;
}
.property-list > dt {
grid-column: 1;
font-weight: 500;
color: var(--color-text-muted, #6B7280);
}
.property-list > dd {
grid-column: 2;
margin: 0;
min-width: 0; /* allow long URIs to wrap inside the cell */
}
.property-list > dd.property-more {
grid-column: 2;
}
.property-list > dd.property-more > details {
display: contents;
}
.property-list > dd.property-more > details > summary {
cursor: pointer;
color: var(--color-text-muted, #6B7280);
font-size: 0.9em;
}

/* dataContentPane: per-subject blocks (was a striped <table>) */
.data-content {
display: block;
}
.data-content__subject {
padding: 0.5em 0.75em;
}
.data-content__subject--even {
background-color: var(--color-row-alt, #f0f0f0);
}
.data-content .property-list {
margin: 0;
}

.iconTD {
Expand All @@ -21,28 +80,31 @@

.labelTD {
width: 100%;
padding: 0;
}

.paneIconTray {
display: flex;
justify-content: flex-start;
align-items: center;
gap: 1em;
flex-wrap: wrap;
}

.paneShown {
width: 24px;
border: none !important;
border-radius: var(--border-radius-md, 0.5rem);
border: none;
border-radius: 0.5em;
margin-left: var(--spacing-small, 0.1rem);
padding: 0.188rem; /* 3px */
background-color: var(--header-menu-item-hover, #e6dcff) !important;
padding: 3px;
background-color: var(--header-menu-item-hover, #e6dcff);
}

.paneHidden {
width: 24px;
border-radius: var(--border-radius-md, 0.5rem);
border-radius: 0.5em;
margin-left: var(--spacing-small, 0.1rem);
padding: 0.188rem; /* 3px */
padding: 3px;
}

.header {
Expand All @@ -54,25 +116,67 @@

.strongHeader {
font-size: 150%;
margin: 0 0.6rem 0 0;
padding: 0.1rem 0.4rem;
margin: 0 0.6em 0 0;
padding: 0.1em 0.4em;
background-color: var(--color-background, #F8F9FB);
}

.tableFullWidth {
width: 100%;
background: var(--color-background, #F8F9FB) !important;
}

/* Native disclosure for the object cell of a predicate row */
.obj-disclosure { display: inline-block; }
.obj-disclosure > summary { cursor: pointer; }
.obj-disclosure > .obj-expanded {
margin-top: 0.25em;
padding-left: 1em;
}

.placeholderTable {
width: 100%;
}

.tdFlex {
margin: var(--spacing-xxxs, 0.2rem);
margin: 0.2em;
border: none;
padding: 0;
vertical-align: top;
display: flex;
justify-content: space-between;
flex-direction: row;
background-color: var(--color-background, #F8F9FB);
}

/* Remove-node icon spacing (image.style.marginLeft/marginRight in JS). */
.removeIcon {
margin-left: 5px;
margin-right: 10px;
}

/* Row container holding a sub-pane's rendered content. */
.outlineRow {
text-align: left;
width: 100%;
}

.outlineRow--themed {
background-color: var(--color-background, #F8F9FB);
}

/* .iconTD already sets width: 0px above; the cell grows automatically when
icons are appended by termWidget.addIcon. */

/* Default literal value styling (was rep.setAttribute('style', 'white-space: pre-wrap;')). */
.literalValue { white-space: pre-wrap; }
.literalValue--integer { text-align: right; }
.literalValue--decimal { text-align: '.'; }

/* Table sized full-width when the outline shows a solo subject. */
.outlineTableSolo { width: 100%; }

/* Alternating background classes for legacy table-of-tables rendering
(replaces dynamic style.backgroundColor = 'white'/'#eee'). */
.outlineNestedTable--white { background-color: white; }
.outlineNestedTable--grey { background-color: #eee; }
Loading