Skip to content

Commit df40a22

Browse files
committed
ldh:LeftSidebar fixes
1 parent 0b6a88c commit df40a22

2 files changed

Lines changed: 237 additions & 61 deletions

File tree

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

Lines changed: 237 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -61,68 +61,81 @@ LIMIT 10
6161
<xsl:template name="ldh:LeftSidebar">
6262
<xsl:param name="base" select="ldt:base()" as="xs:anyURI"/>
6363

64-
<h2 class="nav-header btn">
65-
<xsl:apply-templates select="key('resources', 'document-tree', document(resolve-uri('static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/translations.rdf', $ac:contextUri)))" mode="ac:label"/>
66-
</h2>
67-
68-
<ul class="well well-small nav nav-list">
69-
<!-- TO-DO: generalize -->
70-
<li>
71-
<button class="btn btn-small btn-expand-tree"></button>
72-
<a href="{$base}" class="btn-logo btn-container">
73-
<xsl:apply-templates select="key('resources', 'root', document(resolve-uri('static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/translations.rdf', $ac:contextUri)))" mode="ac:label"/>
74-
</a>
75-
</li>
76-
<!-- non-expandable containers (not based on ldh:SelectChildren) -->
77-
<!--
78-
<li>
79-
<a href="{$base}geo/" class="btn-logo btn-geo">
80-
<xsl:apply-templates select="key('resources', 'geo', document(resolve-uri('static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/translations.rdf', $ac:contextUri)))" mode="ac:label"/>
81-
</a>
82-
</li>
83-
<li>
84-
<a href="{$base}latest/" class="btn-logo btn-latest">
85-
<xsl:apply-templates select="key('resources', 'latest', document(resolve-uri('static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/translations.rdf', $ac:contextUri)))" mode="ac:label"/>
86-
</a>
87-
</li>
88-
-->
89-
</ul>
90-
91-
<h2 class="nav-header btn">
92-
<xsl:apply-templates select="key('resources', 'classes', document(resolve-uri('static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/translations.rdf', $ac:contextUri)))" mode="ac:label"/>
93-
</h2>
94-
95-
<ul class="well well-small nav nav-list" id="class-list">
96-
<!-- class list will be loaded dynamically -->
97-
</ul>
64+
<!-- Document tree container -->
65+
<div id="document-tree">
66+
<h2 class="nav-header btn">
67+
<xsl:apply-templates select="key('resources', 'document-tree', document(resolve-uri('static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/translations.rdf', $ac:contextUri)))" mode="ac:label"/>
68+
</h2>
69+
70+
<ul class="well well-small nav nav-list">
71+
<!-- TO-DO: generalize -->
72+
<li>
73+
<button class="btn btn-small btn-expand-tree"></button>
74+
<a href="{$base}" class="btn-logo btn-container">
75+
<xsl:apply-templates select="key('resources', 'root', document(resolve-uri('static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/translations.rdf', $ac:contextUri)))" mode="ac:label"/>
76+
</a>
77+
</li>
78+
<!-- non-expandable containers (not based on ldh:SelectChildren) -->
79+
<!--
80+
<li>
81+
<a href="{$base}geo/" class="btn-logo btn-geo">
82+
<xsl:apply-templates select="key('resources', 'geo', document(resolve-uri('static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/translations.rdf', $ac:contextUri)))" mode="ac:label"/>
83+
</a>
84+
</li>
85+
<li>
86+
<a href="{$base}latest/" class="btn-logo btn-latest">
87+
<xsl:apply-templates select="key('resources', 'latest', document(resolve-uri('static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/translations.rdf', $ac:contextUri)))" mode="ac:label"/>
88+
</a>
89+
</li>
90+
-->
91+
</ul>
92+
</div>
93+
94+
<!-- Class list container -->
95+
<div id="class-list-container">
96+
<h2 class="nav-header btn">
97+
<xsl:apply-templates select="key('resources', 'classes', document(resolve-uri('static/com/atomgraph/linkeddatahub/xsl/bootstrap/2.3.2/translations.rdf', $ac:contextUri)))" mode="ac:label"/>
98+
</h2>
99+
100+
<ul class="well well-small nav nav-list" id="class-list">
101+
<!-- class list will be loaded dynamically -->
102+
</ul>
103+
</div>
98104
</xsl:template>
99105

100106
<xsl:template name="ldh:DocTreeActivateHref">
101107
<xsl:context-item as="element()" use="required"/> <!-- document tree container -->
102108
<xsl:param name="href" as="xs:anyURI"/>
103-
109+
110+
<!-- Strip query params from href to ensure consistent matching -->
111+
<xsl:variable name="target-uri" select="ac:document-uri($href)" as="xs:anyURI"/>
112+
104113
<xsl:message>
105-
ldh:DocTreeActivateHref $href: <xsl:value-of select="$href"/>
114+
ldh:DocTreeActivateHref $href: <xsl:value-of select="$href"/>, stripped: <xsl:value-of select="$target-uri"/>
106115
</xsl:message>
107116

108117
<!-- make the previously active list items inactive -->
109118
<xsl:for-each select=".//li[contains-token(@class, 'active')]">
110119
<xsl:sequence select="ixsl:call(ixsl:get(., 'classList'), 'toggle', [ 'active', false() ])[current-date() lt xs:date('2000-01-01')]"/>
111120
</xsl:for-each>
112-
<xsl:for-each select=".//li[a/@href = $href]">
121+
<!-- Find li elements whose href (without query params) matches target href (without query params) -->
122+
<xsl:for-each select=".//li[a[ac:document-uri(xs:anyURI(@href)) = $target-uri]]">
113123
<!-- mark the new list item as active -->
114124
<xsl:sequence select="ixsl:call(ixsl:get(., 'classList'), 'toggle', [ 'active', true() ])[current-date() lt xs:date('2000-01-01')]"/>
115125
</xsl:for-each>
116126
</xsl:template>
117127

118-
<!-- Update both left-sidebar and class-list after navigation -->
128+
<!-- Update both document-tree and class-list after navigation -->
119129
<xsl:template name="ldh:NavigationUpdate">
120130
<xsl:param name="href" as="xs:anyURI"/>
121131

122132
<!-- activate the current URL in the document tree -->
123-
<xsl:for-each select="id('left-sidebar', ixsl:page())">
124-
<xsl:call-template name="ldh:DocTreeActivateHref">
125-
<xsl:with-param name="href" select="$href"/>
133+
<xsl:for-each select="id('document-tree', ixsl:page())">
134+
<xsl:variable name="href-string" select="string($href)" as="xs:string"/>
135+
<xsl:variable name="target" select="xs:anyURI(if (contains($href-string, '?')) then substring-before($href-string, '?') else $href-string)" as="xs:anyURI"/>
136+
<xsl:call-template name="ldh:DocTreeExpandPathAndActivate">
137+
<xsl:with-param name="container" select="."/>
138+
<xsl:with-param name="target" select="$target"/>
126139
</xsl:call-template>
127140
</xsl:for-each>
128141

@@ -135,6 +148,27 @@ LIMIT 10
135148
</xsl:for-each>
136149
</xsl:template>
137150

151+
<xsl:template name="ldh:DocTreeExpandPathAndActivate">
152+
<xsl:param name="container" as="element()"/> <!-- document-tree element -->
153+
<xsl:param name="target" as="xs:anyURI"/> <!-- target document URI (already stripped of query params) -->
154+
155+
<xsl:message>ldh:DocTreeExpandPathAndActivate - starting descent for target: <xsl:value-of select="$target"/></xsl:message>
156+
157+
<!-- Find the root <li> element (first top-level li in the tree) -->
158+
<xsl:variable name="root-li" select="$container/ul/li[1]" as="element()?"/>
159+
160+
<xsl:choose>
161+
<xsl:when test="$root-li">
162+
<xsl:message>ldh:DocTreeExpandPathAndActivate - found root: <xsl:value-of select="$root-li/a/@href"/></xsl:message>
163+
<!-- Start recursive descent from root -->
164+
<xsl:sequence select="ldh:doctree-descend($root-li, $target, $container)[current-date() lt xs:date('2000-01-01')]"/>
165+
</xsl:when>
166+
<xsl:otherwise>
167+
<xsl:message>ldh:DocTreeExpandPathAndActivate - no root found in tree</xsl:message>
168+
</xsl:otherwise>
169+
</xsl:choose>
170+
</xsl:template>
171+
138172
<xsl:template name="ldh:DocTreeResourceLoad">
139173
<xsl:param name="container" as="element()"/>
140174
<xsl:param name="uri" as="xs:anyURI"/>
@@ -223,15 +257,15 @@ LIMIT 10
223257
</xsl:if>
224258
</xsl:template>
225259

226-
<xsl:template match="div[@id = 'left-sidebar']//li/a[@href]" mode="ixsl:onclick" priority="1">
260+
<xsl:template match="div[@id = 'document-tree']//li/a[@href]" mode="ixsl:onclick" priority="1">
227261
<xsl:variable name="href" select="@href" as="xs:anyURI"/>
228-
229-
<xsl:for-each select="ancestor::div[@id = 'left-sidebar']">
262+
263+
<xsl:for-each select="ancestor::div[@id = 'document-tree']">
230264
<xsl:call-template name="ldh:DocTreeActivateHref">
231265
<xsl:with-param name="href" select="$href"/>
232266
</xsl:call-template>
233267
</xsl:for-each>
234-
268+
235269
<xsl:next-match/>
236270
</xsl:template>
237271

@@ -387,6 +421,164 @@ LIMIT 10
387421
<xsl:sequence select="$context"/>
388422
</xsl:function>
389423

424+
<!-- Recursive descent function: expands path from current-li down to target-uri -->
425+
<xsl:function name="ldh:doctree-descend" as="map(*)" ixsl:updating="yes">
426+
<xsl:param name="current-li" as="element()"/> <!-- the <li> element we're currently at -->
427+
<xsl:param name="target-uri" as="xs:anyURI"/> <!-- the document URI we want to reach -->
428+
<xsl:param name="tree-container" as="element()"/> <!-- the document-tree element -->
429+
430+
<xsl:variable name="current-href-full" select="xs:anyURI($current-li/a/@href)" as="xs:anyURI"/>
431+
<!-- Strip query parameters for comparison -->
432+
<xsl:variable name="current-href" select="ac:document-uri($current-href-full)" as="xs:anyURI"/>
433+
434+
<xsl:message>ldh:doctree-descend - current: <xsl:value-of select="$current-href"/>, target: <xsl:value-of select="$target-uri"/></xsl:message>
435+
436+
<xsl:choose>
437+
<!-- Case 1: We've reached the target - activate it -->
438+
<xsl:when test="$current-href = $target-uri">
439+
<xsl:message>ldh:doctree-descend - reached target, activating</xsl:message>
440+
<xsl:for-each select="$tree-container">
441+
<xsl:call-template name="ldh:DocTreeActivateHref">
442+
<xsl:with-param name="href" select="$target-uri"/>
443+
</xsl:call-template>
444+
</xsl:for-each>
445+
<xsl:sequence select="map{}"/>
446+
</xsl:when>
447+
448+
<!-- Case 2: Target URI starts with current href - need to descend further -->
449+
<xsl:when test="starts-with(string($target-uri), string($current-href))">
450+
<xsl:variable name="expand-button" select="$current-li/button[contains-token(@class, 'btn-expand-tree')]" as="element()?"/>
451+
452+
<xsl:choose>
453+
<!-- Case 2a: Has expand button and not expanded yet - expand and load children -->
454+
<xsl:when test="$expand-button and not($current-li/ul)">
455+
<xsl:message>ldh:doctree-descend - expanding: <xsl:value-of select="$current-href"/></xsl:message>
456+
457+
<!-- Create <ul> for children -->
458+
<xsl:for-each select="$current-li">
459+
<xsl:result-document href="?." method="ixsl:append-content">
460+
<ul class="well well-small nav nav-list"></ul>
461+
</xsl:result-document>
462+
</xsl:for-each>
463+
464+
<!-- Toggle button class -->
465+
<xsl:for-each select="$expand-button">
466+
<xsl:sequence select="ixsl:call(ixsl:get(., 'classList'), 'toggle', [ 'btn-expand-tree', false() ])[current-date() lt xs:date('2000-01-01')]"/>
467+
<xsl:sequence select="ixsl:call(ixsl:get(., 'classList'), 'toggle', [ 'btn-expanded-tree', true() ])[current-date() lt xs:date('2000-01-01')]"/>
468+
</xsl:for-each>
469+
470+
<!-- Load children and continue descent after loading -->
471+
<!-- Build query to load children (inline from ldh:DocTreeResourceLoad) -->
472+
<xsl:variable name="select-string" select="key('resources', '&ldh;SelectChildren', document(ac:document-uri('&ldh;')))/sp:text" as="xs:string"/>
473+
<xsl:variable name="select-string" select="replace($select-string, '$this', '&lt;' || $current-href || '&gt;', 'q')" as="xs:string"/>
474+
<xsl:variable name="select-json" as="item()">
475+
<xsl:variable name="select-builder" select="ixsl:call(ixsl:get(ixsl:get(ixsl:window(), 'SPARQLBuilder'), 'SelectBuilder'), 'fromString', [ $select-string ])"/>
476+
<xsl:sequence select="ixsl:call($select-builder, 'build', [])"/>
477+
</xsl:variable>
478+
<xsl:variable name="select-json-string" select="ixsl:call(ixsl:get(ixsl:window(), 'JSON'), 'stringify', [ $select-json ])" as="xs:string"/>
479+
<xsl:variable name="select-xml" as="document-node()">
480+
<xsl:document>
481+
<xsl:apply-templates select="json-to-xml($select-json-string)" mode="ldh:replace-variables">
482+
<xsl:with-param name="var-names" select="('child')" tunnel="yes"/>
483+
</xsl:apply-templates>
484+
</xsl:document>
485+
</xsl:variable>
486+
487+
<!-- Wrap SELECT into a DESCRIBE -->
488+
<xsl:variable name="query-xml" as="element()">
489+
<xsl:apply-templates select="$select-xml" mode="ldh:wrap-describe"/>
490+
</xsl:variable>
491+
<xsl:variable name="query-json-string" select="xml-to-json($query-xml)" as="xs:string"/>
492+
<xsl:variable name="query-json" select="ixsl:call(ixsl:get(ixsl:window(), 'JSON'), 'parse', [ $query-json-string ])"/>
493+
<xsl:variable name="query-string" select="ixsl:call(ixsl:call(ixsl:get(ixsl:get(ixsl:window(), 'SPARQLBuilder'), 'SelectBuilder'), 'fromQuery', [ $query-json ]), 'toString', [])" as="xs:string"/>
494+
<xsl:variable name="results-uri" select="ac:build-uri(sd:endpoint(), map{ 'query': $query-string })" as="xs:anyURI"/>
495+
<xsl:variable name="request-uri" select="ldh:href($results-uri, map{})" as="xs:anyURI"/>
496+
<xsl:variable name="request" select="map{ 'method': 'GET', 'href': $request-uri, 'headers': map{ 'Accept': 'application/rdf+xml' } }" as="map(*)"/>
497+
498+
<xsl:variable name="load-context" as="map(*)" select="
499+
map{
500+
'request': $request,
501+
'container': $current-li/ul,
502+
'uri': $current-href
503+
}"/>
504+
505+
<ixsl:promise select="ixsl:http-request($load-context('request')) =>
506+
ixsl:then(ldh:rethread-response($load-context, ?)) =>
507+
ixsl:then(ldh:handle-response#1) =>
508+
ixsl:then(ldh:left-sidebar-resource-response#1) =>
509+
ixsl:then(ldh:doctree-descend-after-load(?, $current-li, $target-uri, $tree-container))"/>
510+
<xsl:sequence select="map{}"/>
511+
</xsl:when>
512+
513+
<!-- Case 2b: Already expanded - find next child to descend into -->
514+
<xsl:when test="$current-li/ul/li">
515+
<xsl:message>ldh:doctree-descend - already expanded, finding next child</xsl:message>
516+
517+
<!-- Find which child's href (without query params) is a prefix of target-uri -->
518+
<xsl:variable name="next-li" select="$current-li/ul/li[starts-with(string($target-uri), string(ac:document-uri(xs:anyURI(a/@href))))][1]" as="element()?"/>
519+
520+
<xsl:choose>
521+
<xsl:when test="$next-li">
522+
<xsl:message>ldh:doctree-descend - descending to: <xsl:value-of select="$next-li/a/@href"/></xsl:message>
523+
<xsl:sequence select="ldh:doctree-descend($next-li, $target-uri, $tree-container)"/>
524+
</xsl:when>
525+
<xsl:otherwise>
526+
<xsl:message>ldh:doctree-descend - no matching child found, activating target</xsl:message>
527+
<xsl:for-each select="$tree-container">
528+
<xsl:call-template name="ldh:DocTreeActivateHref">
529+
<xsl:with-param name="href" select="$target-uri"/>
530+
</xsl:call-template>
531+
</xsl:for-each>
532+
<xsl:sequence select="map{}"/>
533+
</xsl:otherwise>
534+
</xsl:choose>
535+
</xsl:when>
536+
537+
<!-- Case 2c: Has expand button but <ul> exists and is empty (loading in progress) -->
538+
<xsl:otherwise>
539+
<xsl:message>ldh:doctree-descend - waiting for children to load</xsl:message>
540+
<xsl:sequence select="map{}"/>
541+
</xsl:otherwise>
542+
</xsl:choose>
543+
</xsl:when>
544+
545+
<!-- Case 3: Target is not under this branch -->
546+
<xsl:otherwise>
547+
<xsl:message>ldh:doctree-descend - target not under this branch</xsl:message>
548+
<xsl:sequence select="map{}"/>
549+
</xsl:otherwise>
550+
</xsl:choose>
551+
</xsl:function>
552+
553+
<!-- Helper to continue descent after children are loaded -->
554+
<xsl:function name="ldh:doctree-descend-after-load" as="map(*)" ixsl:updating="yes">
555+
<xsl:param name="load-context" as="map(*)"/> <!-- context from loading -->
556+
<xsl:param name="current-li" as="element()"/>
557+
<xsl:param name="target-uri" as="xs:anyURI"/>
558+
<xsl:param name="tree-container" as="element()"/>
559+
560+
<xsl:message>ldh:doctree-descend-after-load - children loaded for: <xsl:value-of select="$current-li/a/@href"/></xsl:message>
561+
562+
<!-- Find which child's href (without query params) is a prefix of target-uri -->
563+
<xsl:variable name="next-li" select="$current-li/ul/li[starts-with(string($target-uri), string(ac:document-uri(xs:anyURI(a/@href))))][1]" as="element()?"/>
564+
565+
<xsl:choose>
566+
<xsl:when test="$next-li">
567+
<xsl:message>ldh:doctree-descend-after-load - descending to: <xsl:value-of select="$next-li/a/@href"/></xsl:message>
568+
<xsl:sequence select="ldh:doctree-descend($next-li, $target-uri, $tree-container)"/>
569+
</xsl:when>
570+
<xsl:otherwise>
571+
<xsl:message>ldh:doctree-descend-after-load - no matching child, activating target</xsl:message>
572+
<xsl:for-each select="$tree-container">
573+
<xsl:call-template name="ldh:DocTreeActivateHref">
574+
<xsl:with-param name="href" select="$target-uri"/>
575+
</xsl:call-template>
576+
</xsl:for-each>
577+
<xsl:sequence select="$load-context"/>
578+
</xsl:otherwise>
579+
</xsl:choose>
580+
</xsl:function>
581+
390582
<xsl:function name="ldh:left-sidebar-resource-response" as="map(*)" ixsl:updating="yes">
391583
<xsl:param name="context" as="map(*)"/>
392584
<xsl:variable name="response" select="$context('response')" as="map(*)"/>

0 commit comments

Comments
 (0)