Skip to content

Commit b73f7a6

Browse files
namedgraphclaude
andcommitted
Override RDFa editor annotation typeahead and dialog with LDH's Bootstrap UI
Intercepts local:typeahead-field, local:typeahead-set-value, local:typeahead-value, and local:render-overlay in form.xsl (which has higher import precedence than the vendored rdfa-editor/ stylesheets) to replace the upstream's doc()-on-vocabs typeahead with LDH's /ns-querying bs2:Lookup widget and to re-style the annotation dialog using Bootstrap 2.3.2 form classes (.well, .form-horizontal, .control-group, .btn). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent f8f1f20 commit b73f7a6

2 files changed

Lines changed: 138 additions & 0 deletions

File tree

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,12 @@ h2.item-logo { background-image: url('../icons/file.svg'); background-position:
153153
.modal-footer { position: sticky; bottom: 0; background-color: white; z-index: 1060; }
154154
.modal-first-time-message { margin-left: 0; width: 80%; left: 10%; }
155155
.modal-first-time-message .hero-unit { margin-bottom: 0; }
156+
/* Annotation overlay — reset rdfa-editor.css visual overrides; .well provides base styling */
157+
#overlay { background: #f5f5f5 !important; background-image: none !important; border: 1px solid #e3e3e3 !important; border-radius: 4px !important; box-shadow: inset 0 1px 1px rgba(0,0,0,.05) !important; font-family: inherit !important; min-width: 360px !important; max-width: 520px !important; }
158+
#overlay form { padding: 0 !important; }
159+
#overlay .btn.btn-primary { background-color: #0088cc; background-image: linear-gradient(to bottom, #0088cc, #0044cc); color: #fff; border-color: #0044cc; }
160+
#overlay .btn.btn-danger { background-color: #da4f49; background-image: linear-gradient(to bottom, #ee5f5b, #bd362f); color: #fff; border-color: #bd362f; }
161+
#overlay .btn { font-family: inherit; }
156162
.control-group.endpoint-classes ul { max-height: 20em; overflow: auto; }
157163
.nav-tabs > li > a, .pager > li > a.active { cursor: pointer; }
158164
.pager > li.previous > a { text-align: right; font-size: 0; color: transparent; background-image: url('../icons/ic_navigate_before_black_24px.svg'); background-position: center center; background-repeat: no-repeat; width: 64px; height: 24px; }

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

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,138 @@ WHERE
163163
</xsl:call-template>
164164
</xsl:template>
165165

166+
<!-- override RDFa editor annotation typeahead: use LDH's /ns-querying bs2:Lookup instead of doc()-on-vocabs -->
167+
<xsl:function name="local:typeahead-field" as="element()">
168+
<xsl:param name="field" as="xs:string"/>
169+
<xsl:variable name="for-class" as="xs:anyURI" select="if ($field = 'typeof') then xs:anyURI('&owl;Class') else xs:anyURI('&rdf;Property')"/>
170+
<span data-field="{$field}" class="typeahead-field rdfa-editor-ui">
171+
<xsl:call-template name="bs2:Lookup">
172+
<xsl:with-param name="class" select="'property-typeahead typeahead'"/>
173+
<xsl:with-param name="id" select="'annotation-' || $field"/>
174+
<xsl:with-param name="list-class" select="'property-typeahead typeahead dropdown-menu'"/>
175+
<xsl:with-param name="forClass" select="$for-class"/>
176+
</xsl:call-template>
177+
</span>
178+
</xsl:function>
179+
180+
<!-- rebuild the typeahead field and pre-populate with IRI; clears any prior committed button state -->
181+
<xsl:template name="local:typeahead-set-value">
182+
<xsl:param name="form" as="element()"/>
183+
<xsl:param name="field" as="xs:string"/>
184+
<xsl:param name="iri" as="xs:string"/>
185+
<xsl:variable name="for-class" as="xs:anyURI" select="if ($field = 'typeof') then xs:anyURI('&owl;Class') else xs:anyURI('&rdf;Property')"/>
186+
<xsl:for-each select="($form//span[@data-field = $field])[1]">
187+
<xsl:result-document href="?." method="ixsl:replace-content">
188+
<xsl:call-template name="bs2:Lookup">
189+
<xsl:with-param name="class" select="'property-typeahead typeahead'"/>
190+
<xsl:with-param name="id" select="'annotation-' || $field"/>
191+
<xsl:with-param name="list-class" select="'property-typeahead typeahead dropdown-menu'"/>
192+
<xsl:with-param name="forClass" select="$for-class"/>
193+
<xsl:with-param name="value" select="if ($iri ne '') then $iri else ()"/>
194+
</xsl:call-template>
195+
</xsl:result-document>
196+
</xsl:for-each>
197+
</xsl:template>
198+
199+
<!-- read back the IRI from span[@data-field]: committed (hidden input) or typed (property-typeahead text) -->
200+
<xsl:function name="local:typeahead-value" as="xs:string?">
201+
<xsl:param name="form" as="element()"/>
202+
<xsl:param name="field" as="xs:string"/>
203+
<xsl:variable name="wrapper" as="element()?" select="($form//span[@data-field = $field])[1]"/>
204+
<xsl:variable name="hidden" as="element()?" select="($wrapper//input[@type = 'hidden'])[1]"/>
205+
<xsl:choose>
206+
<xsl:when test="exists($hidden)">
207+
<xsl:sequence select="string(ixsl:get($hidden, 'value'))[. ne '']"/>
208+
</xsl:when>
209+
<xsl:otherwise>
210+
<xsl:variable name="input" as="element()?" select="($wrapper//input[contains-token(@class, 'property-typeahead')])[1]"/>
211+
<xsl:variable name="text" as="xs:string" select="normalize-space(string(ixsl:get($input, 'value')))"/>
212+
<xsl:sequence select="if (local:is-absolute-iri($text)) then $text else ()"/>
213+
</xsl:otherwise>
214+
</xsl:choose>
215+
</xsl:function>
216+
217+
<!-- Bootstrap-styled annotation overlay (replaces rdfa-editor's custom HTML structure) -->
218+
<xsl:template name="local:render-overlay">
219+
<div id="overlay" class="rdfa-editor-ui well" role="dialog" aria-modal="true" aria-label="RDFa annotation" style="display: none;">
220+
<div class="modal-header">
221+
<h3>RDFa Annotation</h3>
222+
</div>
223+
<form id="annotation-form" class="form-horizontal">
224+
<div class="control-group">
225+
<label class="control-label">Subject</label>
226+
<div class="controls">
227+
<div id="stmt-subject" class="uneditable-input"/>
228+
</div>
229+
</div>
230+
<div class="control-group">
231+
<label class="control-label">Property</label>
232+
<div class="controls">
233+
<xsl:sequence select="local:typeahead-field('property')"/>
234+
</div>
235+
</div>
236+
<div class="control-group">
237+
<label class="control-label">Value</label>
238+
<div class="controls">
239+
<input type="text" name="value" class="input-xlarge" placeholder="Literal value"/>
240+
<span class="help-block">The selected text; change to emit a machine-readable content value</span>
241+
</div>
242+
</div>
243+
<details id="advanced-fields">
244+
<summary>Type, subject &amp; object</summary>
245+
<div class="control-group">
246+
<label class="control-label">Type (typeof)</label>
247+
<div class="controls">
248+
<xsl:sequence select="local:typeahead-field('typeof')"/>
249+
<span class="help-block">Types the annotated resource; without a subject the typed resource becomes the object of the property (chaining)</span>
250+
</div>
251+
</div>
252+
<div class="control-group">
253+
<label class="control-label">Subject (about)</label>
254+
<div class="controls">
255+
<input type="text" name="subject" class="input-xlarge" placeholder="Overrides the subject in scope"/>
256+
<span class="help-block">IRI or _:blank-node identifier</span>
257+
</div>
258+
</div>
259+
<div class="control-group">
260+
<label class="control-label">Object (resource)</label>
261+
<div class="controls">
262+
<input type="text" name="object" class="input-xlarge" placeholder="Object IRI"/>
263+
<span class="help-block">Makes the object a resource instead of the literal value</span>
264+
</div>
265+
</div>
266+
<div class="control-group">
267+
<label class="control-label">Datatype</label>
268+
<div class="controls">
269+
<select name="datatype">
270+
<option value="">(plain literal)</option>
271+
<xsl:variable name="xsd" as="xs:string" select="'http://www.w3.org/2001/XMLSchema#'"/>
272+
<xsl:for-each select="'string', 'date', 'dateTime', 'time', 'integer', 'decimal', 'double', 'float', 'boolean', 'anyURI'">
273+
<option value="{$xsd || .}">xsd:<xsl:value-of select="."/></option>
274+
</xsl:for-each>
275+
<option value="{$local:custom}">-- Custom datatype --</option>
276+
</select>
277+
<input type="text" name="custom-datatype" class="input-xlarge" placeholder="Datatype IRI" style="display: none;"/>
278+
<span class="help-block">Types the literal; mutually exclusive with a language tag</span>
279+
</div>
280+
</div>
281+
<div class="control-group">
282+
<label class="control-label">Language</label>
283+
<div class="controls">
284+
<input type="text" name="lang" class="input-small" placeholder="e.g. en, fr-CA"/>
285+
<span class="help-block">Language tag for the literal; ignored when a datatype is set</span>
286+
</div>
287+
</div>
288+
</details>
289+
<div class="form-actions">
290+
<button type="button" class="btn btn-danger remove-action" style="display: none;">Remove</button>
291+
<button type="button" class="btn btn-primary spo-action">Annotate</button>
292+
<button type="button" class="btn cancel-action">Cancel</button>
293+
</div>
294+
</form>
295+
</div>
296+
</xsl:template>
297+
166298
<!-- TO-DO: phase out as regular ixsl: event templates -->
167299
<xsl:template match="fieldset//input" mode="ldh:RenderRowForm" priority="1">
168300
<!-- subject value change -->

0 commit comments

Comments
 (0)