Skip to content

Commit 3f602c3

Browse files
namedgraphclaude
andcommitted
Path-aware view ordering for modal search; assorted fixes
View block now derives a variable→predicate-URI-set map from the SELECT's BGPs (handling alternative property paths like rdfs:label|sh:name|... whose items are URIs) and drives three things from it: the order-by dropdown (one option per variable, deduped), auto-pickup of ORDER BY from the SELECT, and a COALESCE-style client-side sort key that prefers literals whose @xml:lang primary subtag matches $ac:lang. `ORDER BY ?label` baked into $select-labelled-string so the modal search returns alphabetically by label. Search modal: form moved into the modal-header with a magnifier submit button; `.search-form-modal` CSS extends `.search-form`'s flex layout so input + button fit naturally. Empty address-bar submit button removed from the navbar-form (its ldh:logo template was never added; pressing Enter still submits). $ac:lang now reads the primary subtag of navigator.language so existing `lang($ac:lang)` checks (which spec-match `xml:lang='en'` for input `'en'`, not for `'en-US'`) keep working under browser preferences like `en-US`. Block mousemove handler guards the LinkedDataHub.contents cache lookup with ixsl:contains to avoid a warning per pixel when the hovered document-body's URI isn't cached. Local-document navigation handlers (tab activate, tab-close fallback, popstate, generic link click) now strip the query string from $uri via ac:absolute-path before passing it to ldh:DocumentNavigate. The cache key downstream now matches document-body/@about / tab data-uri, both already canonicalised via ac:absolute-path. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent daa15c5 commit 3f602c3

7 files changed

Lines changed: 357 additions & 188 deletions

File tree

src/main/webapp/static/com/atomgraph/linkeddatahub/css/bootstrap.css

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
html { height: 100%; overscroll-behavior-y: none; }
1+
html { height: 100%; }
22
/* only the main navbar is fixed-top now; tab bar + action bar are sticky inside #tab-body */
33
body { height: calc(100% - 51px); padding-top: 51px; padding-bottom: 0; }
44
#tab-bar { position: sticky; top: 51px; z-index: 1000; margin-bottom: 0; }
@@ -27,8 +27,10 @@ ul.dropdown-menu ul { margin: 0; }
2727
.dropdown-menu li form { margin-bottom: 0; }
2828
.dropdown-menu li form button { width: 100%; text-align: left; }
2929
#collapsing-top-navbar .brand.context { display: inline-block; vertical-align: middle; }
30-
.navbar-form input#uri { width: calc(100% - 50px); }
31-
.navbar-form .btn-search { background-image: url('../icons/ic_search_white_24px.svg'); background-position: center center; background-repeat: no-repeat; width: 34px; height: 34px; }
30+
.btn-search { background-image: url('../icons/ic_search_white_24px.svg'); background-position: center center; background-repeat: no-repeat; width: 34px; height: 34px; }
31+
.search-form .input-append, .search-form-modal .input-append { display: flex; width: 100%; align-items: stretch; }
32+
.search-form .input-append .search-query, .search-form-modal .input-append .search-query { flex: 1 1 auto; min-width: 0; height: 34px; box-sizing: border-box; margin: 0; }
33+
.search-form .input-append .btn-search, .search-form-modal .input-append .btn-search { flex: 0 0 34px; margin: 0; }
3234
.action-bar { position: sticky; top: var(--action-bar-top, 51px); z-index: 999; background: #dfdfdf; padding: 0; box-shadow: none; }
3335
.action-bar form { margin-bottom: 0; }
3436
.action-bar .span7 .row-fluid > * { margin-top: 10px; }
@@ -165,7 +167,7 @@ fieldset fieldset { margin-left: 3%; margin-bottom: 3%; }
165167
.constructor-triple .controls label.radio { display: inline-block; padding-top: 10px; margin-right: 10px; }
166168
.constructor-triple .controls .help-inline { vertical-align: top; padding-top: 5px; }
167169
.control-group.error .checkbox, .control-group.error .radio, .control-group.error input, .control-group.error select, .control-group.error textarea { color: unset; }
168-
#uri { height: 24px; }
170+
#uri { height: 24px; width: 100%; }
169171
#query-form fieldset { border: initial; margin: initial; }
170172
button.add-typeahead { width: 219px; }
171173
.btn.btn-remove-property, .btn.btn-remove-resource { background-image: url('../icons/ic_remove_black_24px.svg'); background-position: center center; background-repeat: no-repeat; height: 30px; width: 30px; }

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

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

238238
<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">
239239
<xsl:variable name="uri" select="xs:anyURI(ancestor::div[contains-token(@class, 'document-body')]/@about)" as="xs:anyURI"/>
240-
<xsl:variable name="results" select="ixsl:get(ixsl:get(ixsl:get(ixsl:window(), 'LinkedDataHub.contents'), '`' || $uri || '`'), 'results')" as="document-node()"/>
241-
<xsl:variable name="mode" select="ac:mode($results)" as="xs:anyURI"/>
242-
243-
<xsl:if test="$mode = xs:anyURI('&ldh;ContentMode')">
240+
<xsl:variable name="contents" select="ixsl:get(ixsl:window(), 'LinkedDataHub.contents')"/>
241+
<xsl:variable name="cache-key" select="'`' || $uri || '`'" as="xs:string"/>
242+
<!-- cache may not have an entry for the hovered block's document URI (e.g. inactive tab); skip silently to avoid an ixsl:get warning on every mousemove -->
243+
<xsl:if test="ixsl:contains($contents, $cache-key) and ixsl:contains(ixsl:get($contents, $cache-key), 'results')">
244+
<xsl:variable name="results" select="ixsl:get(ixsl:get($contents, $cache-key), 'results')" as="document-node()"/>
245+
<xsl:variable name="mode" select="ac:mode($results)" as="xs:anyURI"/>
246+
247+
<xsl:if test="$mode = xs:anyURI('&ldh;ContentMode')">
244248
<xsl:variable name="dom-x" select="ixsl:get(ixsl:event(), 'clientX')" as="xs:double"/>
245249
<xsl:variable name="rect" select="ixsl:call(., 'getBoundingClientRect', [])"/>
246250
<xsl:variable name="offset-x" select="$dom-x - ixsl:get($rect, 'x')" as="xs:double"/>
@@ -286,10 +290,11 @@ exclude-result-prefixes="#all"
286290
</xsl:choose>
287291

288292
<!-- call the next matching template to preserve existing block controls functionality -->
289-
<xsl:next-match/>
293+
<xsl:next-match/>
294+
</xsl:if>
290295
</xsl:if>
291296
</xsl:template>
292-
297+
293298
<!-- hide drag handle when mouse leaves block -->
294299

295300
<xsl:template match="div[contains-token(@class, 'block')][key('elements-by-class', 'drag-handle', .)][acl:mode() = '&acl;Write']" mode="ixsl:onmouseout">

0 commit comments

Comments
 (0)