Skip to content

Commit 50c7a54

Browse files
namedgraphclaude
andcommitted
XSLT refactoring prep + ldh/ fork entry point
Prep 1: uncomment @typeof on all block outer divs (typed/XHTML/SaxonJS wrapper) in resource.xsl so CSS [typeof~="..."] selectors and depth- independent handler anchors work. Prep 2: emit aria-current="page" on active mode link; emit and keep aria-expanded in sync on left-sidebar show/hide in navigation.xsl. Prep 3: replace depth-locked axes in block.xsl with ancestor::*[...][1] traversal (ondragover/enter/leave/drop document-body lookup, drag-handle span12 lookup); replace sibling-relative btn-edit match with ancestor RDFa match; replace ixsl:style() readback in onmousemove with aria-expanded attribute check. Fork: add xsl/ldh/layout.xsl — imports bootstrap/2.3.2/layout.xsl and overrides structural templates to remove Bootstrap grid classes (row-fluid, span7, span2, container-fluid) while keeping load-bearing DOM anchor classes (document-body, content-body, block, span12). Introduces ldh:BlockContent mode to share SSR/CSR content dispatch without the Bootstrap SaxonJS wrapper's hardcoded div.span12. Add css/ldh.css — initial design layer keyed on RDFa typeof selectors and ARIA state attributes; flex layout for .ldh-content/.ldh-block. Activate the ldh tree by changing the import in static/xsl/layout.xsl from ../bootstrap/2.3.2/layout.xsl to ../ldh/layout.xsl. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 4293ee9 commit 50c7a54

5 files changed

Lines changed: 367 additions & 12 deletions

File tree

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/* LinkedDataHub design layer — loaded on top of the Bootstrap stack.
2+
* Selectors key on RDFa (@typeof, @about) and ARIA, never on Bootstrap grid classes.
3+
* Bootstrap grid classes (span2, span7, row-fluid, etc.) intentionally absent here.
4+
*/
5+
6+
/* ─── Document layout ────────────────────────────────────────── */
7+
8+
.ldh-document {
9+
display: grid;
10+
grid-template-rows: auto 1fr;
11+
}
12+
13+
/* ─── Content area: stacked blocks ───────────────────────────── */
14+
15+
.ldh-content {
16+
display: flex;
17+
flex-direction: column;
18+
gap: 1rem;
19+
padding: 1rem;
20+
}
21+
22+
/* ─── Generic resource block ──────────────────────────────────── */
23+
24+
.ldh-block {
25+
display: flex;
26+
gap: 1rem;
27+
}
28+
29+
.ldh-block-body {
30+
flex: 1 1 auto;
31+
min-width: 0;
32+
}
33+
34+
.ldh-block-nav {
35+
flex: 0 0 200px;
36+
}
37+
38+
/* ─── Resource header ─────────────────────────────────────────── */
39+
40+
.ldh-header {
41+
padding: 0.75rem 0;
42+
border-bottom: 1px solid #e0e0e0;
43+
margin-bottom: 0.75rem;
44+
}
45+
46+
/* ─── RDFa typeof selectors (examples; extend per vocabulary) ─── */
47+
48+
/* Containers get a subtle left border */
49+
[typeof~="https://www.w3.org/ns/ldt/document-hierarchy#Container"] > .ldh-block-body {
50+
border-left: 3px solid #5b9bd5;
51+
padding-left: 0.75rem;
52+
}
53+
54+
/* XHTML content blocks — full width, no nav sidebar */
55+
[typeof~="https://w3id.org/atomgraph/linkeddatahub#XHTML"] {
56+
flex-direction: column;
57+
}
58+
59+
[typeof~="https://w3id.org/atomgraph/linkeddatahub#XHTML"] > .ldh-block-nav {
60+
display: none;
61+
}
62+
63+
/* ─── ARIA state selectors ────────────────────────────────────── */
64+
65+
/* Active mode link */
66+
a[aria-current="page"] {
67+
font-weight: bold;
68+
}
69+
70+
/* Collapsed left sidebar */
71+
.left-sidebar[aria-expanded="false"] {
72+
display: none;
73+
}

src/main/webapp/static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/client/block.xsl

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ exclude-result-prefixes="#all"
237237

238238
<!-- show drag handle on left edge hover, but not when left sidebar is active -->
239239

240-
<xsl:template match="div[contains-token(@class, 'block')][key('elements-by-class', 'drag-handle', .)][acl:mode() = '&acl;Write'][not(ixsl:style(ancestor::div[contains-token(@class, 'tab-pane')]/div[contains-token(@class, 'left-sidebar')])?display = 'block')]" mode="ixsl:onmousemove" priority="2">
240+
<xsl:template match="div[contains-token(@class, 'block')][key('elements-by-class', 'drag-handle', .)][acl:mode() = '&acl;Write'][not(ancestor::div[contains-token(@class, 'tab-pane')][1]/div[contains-token(@class, 'left-sidebar')]/@aria-expanded = 'true')]" mode="ixsl:onmousemove" priority="2">
241241
<xsl:variable name="uri" select="xs:anyURI(ancestor::div[contains-token(@class, 'document-body')]/@about)" as="xs:anyURI"/>
242242
<xsl:variable name="contents" select="ixsl:get(ixsl:window(), 'LinkedDataHub.contents')"/>
243243
<xsl:variable name="cache-key" select="'`' || $uri || '`'" as="xs:string"/>
@@ -258,7 +258,7 @@ exclude-result-prefixes="#all"
258258
<xsl:choose>
259259
<xsl:when test="$offset-x &lt;= $left-edge-threshold and ixsl:style($drag-handle)?display = 'none'">
260260
<!-- get both block and span12 rectangles to calculate intersection -->
261-
<xsl:variable name="span12" select="$drag-handle/parent::*[contains-token(@class, 'span12')]" as="element()"/>
261+
<xsl:variable name="span12" select="$drag-handle/ancestor::*[contains-token(@class, 'span12')][1]" as="element()"/>
262262
<xsl:variable name="block-rect" select="$rect"/> <!-- block's getBoundingClientRect -->
263263
<xsl:variable name="span12-rect" select="ixsl:call($span12, 'getBoundingClientRect', [])"/>
264264

@@ -311,7 +311,7 @@ exclude-result-prefixes="#all"
311311

312312
<!-- override inline editing form for block types (do nothing if the button is disabled) - prioritize over form.xsl -->
313313

314-
<xsl:template match="div[following-sibling::div[@typeof = ('&ldh;XHTML', '&ldh;Object')]]//button[contains-token(@class, 'btn-edit')][not(contains-token(@class, 'disabled'))]" mode="ixsl:onclick" priority="1">
314+
<xsl:template match="button[contains-token(@class, 'btn-edit')][not(contains-token(@class, 'disabled'))][ancestor::*[@typeof = ('&ldh;XHTML', '&ldh;Object')][1]]" mode="ixsl:onclick" priority="1">
315315
<xsl:param name="block" select="ancestor::div[contains-token(@class, 'block')][1]" as="element()"/>
316316
<!-- for block types, button.btn-edit is placed in its own div.row-fluid, therefore the next row is the actual container -->
317317
<xsl:param name="container" select="$block/descendant::div[@typeof][1]" as="element()"/> <!-- other resources can be nested within object -->
@@ -419,7 +419,7 @@ exclude-result-prefixes="#all"
419419

420420
<xsl:template match="*[ancestor-or-self::div[contains-token(@class, 'block')][parent::div[contains-token(@class, 'content-body')]][acl:mode() = '&acl;Write']]" mode="ixsl:ondragover" priority="1">
421421
<xsl:variable name="block" select="ancestor-or-self::div[contains-token(@class, 'block')][parent::div[contains-token(@class, 'content-body')]][1]" as="element()"/>
422-
<xsl:variable name="uri" select="xs:anyURI($block/parent::div/parent::div[contains-token(@class, 'document-body')]/@about)" as="xs:anyURI"/>
422+
<xsl:variable name="uri" select="xs:anyURI($block/ancestor::*[contains-token(@class, 'document-body')][1]/@about)" as="xs:anyURI"/>
423423
<xsl:variable name="results" select="ixsl:get(ixsl:get(ixsl:get(ixsl:window(), 'LinkedDataHub.contents'), '`' || $uri || '`'), 'results')" as="document-node()"/>
424424
<xsl:variable name="mode" select="ac:mode($results)" as="xs:anyURI"/>
425425

@@ -438,7 +438,7 @@ exclude-result-prefixes="#all"
438438

439439
<xsl:template match="*[ancestor-or-self::div[contains-token(@class, 'block')][parent::div[contains-token(@class, 'content-body')]][acl:mode() = '&acl;Write']]" mode="ixsl:ondragenter" priority="1">
440440
<xsl:variable name="block" select="ancestor-or-self::div[contains-token(@class, 'block')][parent::div[contains-token(@class, 'content-body')]][1]" as="element()"/>
441-
<xsl:variable name="uri" select="xs:anyURI($block/parent::div/parent::div[contains-token(@class, 'document-body')]/@about)" as="xs:anyURI"/>
441+
<xsl:variable name="uri" select="xs:anyURI($block/ancestor::*[contains-token(@class, 'document-body')][1]/@about)" as="xs:anyURI"/>
442442
<xsl:variable name="results" select="ixsl:get(ixsl:get(ixsl:get(ixsl:window(), 'LinkedDataHub.contents'), '`' || $uri || '`'), 'results')" as="document-node()"/>
443443
<xsl:variable name="mode" select="ac:mode($results)" as="xs:anyURI"/>
444444

@@ -455,7 +455,7 @@ exclude-result-prefixes="#all"
455455

456456
<xsl:template match="*[ancestor-or-self::div[contains-token(@class, 'block')][parent::div[contains-token(@class, 'content-body')]][acl:mode() = '&acl;Write']]" mode="ixsl:ondragleave" priority="1">
457457
<xsl:variable name="block" select="ancestor-or-self::div[contains-token(@class, 'block')][parent::div[contains-token(@class, 'content-body')]][1]" as="element()"/>
458-
<xsl:variable name="uri" select="xs:anyURI($block/parent::div/parent::div[contains-token(@class, 'document-body')]/@about)" as="xs:anyURI"/>
458+
<xsl:variable name="uri" select="xs:anyURI($block/ancestor::*[contains-token(@class, 'document-body')][1]/@about)" as="xs:anyURI"/>
459459
<xsl:variable name="results" select="ixsl:get(ixsl:get(ixsl:get(ixsl:window(), 'LinkedDataHub.contents'), '`' || $uri || '`'), 'results')" as="document-node()"/>
460460
<xsl:variable name="mode" select="ac:mode($results)" as="xs:anyURI"/>
461461

@@ -478,7 +478,7 @@ exclude-result-prefixes="#all"
478478

479479
<xsl:template match="*[ancestor-or-self::div[contains-token(@class, 'block')][parent::div[contains-token(@class, 'content-body')]][acl:mode() = '&acl;Write']]" mode="ixsl:ondrop" priority="1">
480480
<xsl:variable name="block" select="ancestor-or-self::div[contains-token(@class, 'block')][parent::div[contains-token(@class, 'content-body')]][1]" as="element()"/>
481-
<xsl:variable name="uri" select="xs:anyURI($block/parent::div/parent::div[contains-token(@class, 'document-body')]/@about)" as="xs:anyURI"/>
481+
<xsl:variable name="uri" select="xs:anyURI($block/ancestor::*[contains-token(@class, 'document-body')][1]/@about)" as="xs:anyURI"/>
482482
<xsl:variable name="results" select="ixsl:get(ixsl:get(ixsl:get(ixsl:window(), 'LinkedDataHub.contents'), '`' || $uri || '`'), 'results')" as="document-node()"/>
483483
<xsl:variable name="mode" select="ac:mode($results)" as="xs:anyURI"/>
484484

src/main/webapp/static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/client/navigation.xsl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ ORDER BY DESC(?created)
105105
<xsl:if test="$class">
106106
<xsl:attribute name="class" select="$class"/>
107107
</xsl:if>
108+
<xsl:attribute name="aria-expanded" select="'false'"/>
108109

109110
<!-- dataspace-scoped search form -->
110111
<form class="form-search search-form" accept-charset="UTF-8" title="{ac:label(key('resources', 'search-title', document(resolve-uri('static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/translations.rdf', lapp:origin()))))}">
@@ -304,6 +305,7 @@ ORDER BY DESC(?created)
304305
<xsl:variable name="active-sidebar" select="id('tab-content', ixsl:page())/div[contains-token(@class, 'tab-pane')][contains-token(@class, 'active')]/div[contains-token(@class, 'left-sidebar')]" as="element()?"/>
305306
<xsl:if test="$active-sidebar">
306307
<ixsl:set-style name="display" select="'block'" object="$active-sidebar"/>
308+
<ixsl:set-attribute name="aria-expanded" select="'true'" object="$active-sidebar"/>
307309
</xsl:if>
308310
</xsl:if>
309311
</xsl:template>
@@ -315,6 +317,7 @@ ORDER BY DESC(?created)
315317
<!-- only hide if the related target does not have this div as ancestor (is not its child) -->
316318
<xsl:if test="not($related-target/ancestor-or-self::div[. is current()])">
317319
<ixsl:set-style name="display" select="'none'"/>
320+
<ixsl:set-attribute name="aria-expanded" select="'false'"/>
318321
</xsl:if>
319322
</xsl:template>
320323

src/main/webapp/static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/resource.xsl

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,9 @@ extension-element-prefixes="ixsl"
425425
<xsl:if test="$href">
426426
<xsl:attribute name="href" select="$href"/>
427427
</xsl:if>
428+
<xsl:if test="$active">
429+
<xsl:attribute name="aria-current" select="'page'"/>
430+
</xsl:if>
428431
<xsl:apply-templates select="." mode="ldh:logo"/>
429432
<xsl:value-of>
430433
<xsl:apply-templates select="." mode="ac:label"/>
@@ -481,9 +484,9 @@ extension-element-prefixes="ixsl"
481484
<xsl:if test="$about">
482485
<xsl:attribute name="about" select="$about"/>
483486
</xsl:if>
484-
<!-- <xsl:if test="exists($typeof)">
487+
<xsl:if test="exists($typeof)">
485488
<xsl:attribute name="typeof" select="string-join($typeof, ' ')"/>
486-
</xsl:if>-->
489+
</xsl:if>
487490
<xsl:if test="$draggable = true()">
488491
<xsl:attribute name="draggable" select="'true'"/>
489492
</xsl:if>
@@ -542,13 +545,13 @@ extension-element-prefixes="ixsl"
542545
<xsl:if test="$about">
543546
<xsl:attribute name="about" select="$about"/>
544547
</xsl:if>
545-
<!-- <xsl:if test="exists($typeof)">
548+
<xsl:if test="exists($typeof)">
546549
<xsl:attribute name="typeof" select="string-join($typeof, ' ')"/>
547-
</xsl:if>-->
550+
</xsl:if>
548551
<xsl:if test="$draggable = true()">
549552
<xsl:attribute name="draggable" select="'true'"/>
550553
</xsl:if>
551-
554+
552555
<div class="span12">
553556
<div class="drag-handle">
554557
<xsl:if test="acl:mode() = '&acl;Write'">
@@ -621,6 +624,9 @@ extension-element-prefixes="ixsl"
621624
<xsl:if test="$about">
622625
<xsl:attribute name="about" select="$about"/>
623626
</xsl:if>
627+
<xsl:if test="exists($typeof)">
628+
<xsl:attribute name="typeof" select="string-join($typeof, ' ')"/>
629+
</xsl:if>
624630

625631
<div class="span12">
626632
<xsl:next-match>

0 commit comments

Comments
 (0)