mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-02-21 14:04:12 +01:00
Custom Forms: Allow HTML in labels and help text (#5136)
* Custom Forms: Allow HTML in labels and help text Fixes #5003. * Vue: Sanitize labels and helper text input * Form editor: Fix blur on input for select option values --------- Co-authored-by: Nicolas Dorier <nicolas.dorier@gmail.com>
This commit is contained in:
parent
9f5466a41f
commit
c777746b69
8 changed files with 71 additions and 14 deletions
|
@ -390,6 +390,11 @@ retry:
|
|||
version = Regex.Match(actual, "BootstrapVue ([0-9]+.[0-9]+.[0-9]+)").Groups[1].Value;
|
||||
expected = (await (await client.GetAsync($"https://cdnjs.cloudflare.com/ajax/libs/bootstrap-vue/{version}/bootstrap-vue.min.js")).Content.ReadAsStringAsync()).Trim();
|
||||
EqualJsContent(expected, actual);
|
||||
|
||||
actual = GetFileContent("BTCPayServer", "wwwroot", "vendor", "vue-sanitize-directive", "vue-sanitize-directive.umd.min.js").Trim();
|
||||
version = Regex.Match(actual, "Original file: /npm/vue-sanitize-directive@([0-9]+.[0-9]+.[0-9]+)").Groups[1].Value;
|
||||
expected = (await (await client.GetAsync($"https://cdn.jsdelivr.net/npm/vue-sanitize-directive@{version}/dist/vue-sanitize-directive.umd.min.js")).Content.ReadAsStringAsync()).Trim();
|
||||
EqualJsContent(expected, actual);
|
||||
}
|
||||
|
||||
private void EqualJsContent(string expected, string actual)
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
@if (!Model.Constant)
|
||||
{
|
||||
<fieldset>
|
||||
<legend class="h3 mt-4 mb-3">@Model.Label</legend>
|
||||
<legend class="h3 mt-4 mb-3">@Safe.Raw(Model.Label)</legend>
|
||||
@foreach (var field in Model.Fields)
|
||||
{
|
||||
if (FormComponentProviders.TypeToComponentProvider.TryGetValue(field.Type, out var partial) && !string.IsNullOrEmpty(partial.View))
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
}
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="@Model.Name"@(Model.Required ? " data-required" : "")>
|
||||
@Model.Label
|
||||
@Safe.Raw(Model.Label)
|
||||
</label>
|
||||
<input id="@Model.Name" type="@Model.Type" class="form-control @(errors is null ? "" : "is-invalid")"
|
||||
name="@Model.Name" value="@Model.Value" data-val="true"
|
||||
|
|
|
@ -12,17 +12,15 @@
|
|||
}
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="@Model.Name"@(Model.Required ? " data-required" : "")>
|
||||
@Model.Label
|
||||
@Safe.Raw(Model.Label)
|
||||
</label>
|
||||
|
||||
<select id="@selectField.Name" asp-items="selectField.Options" class="form-select @(errors is null ? "" : "is-invalid")"
|
||||
name="@selectField.Name" data-val="true" aria-describedby="HelpText-@selectField.Name" required="@selectField.Required"
|
||||
data-val-required="@selectField.Label is required.">
|
||||
</select>
|
||||
|
||||
<span class="text-danger" data-valmsg-for="@selectField.Name" data-valmsg-replace="true">@(isInvalid && errors.Any() ? errors.First().ErrorMessage : string.Empty)</span>
|
||||
@if (!string.IsNullOrEmpty(selectField.HelpText))
|
||||
{
|
||||
<div id="@($"HelpText-{selectField.Name}")" class="form-text">@selectField.HelpText</div>
|
||||
<div id="@($"HelpText-{selectField.Name}")" class="form-text">@Safe.Raw(selectField.HelpText)</div>
|
||||
}
|
||||
</div>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
}
|
||||
<div class="form-group">
|
||||
<label class="form-label" for="@Model.Name"@(Model.Required ? " data-required" : "")>
|
||||
@Model.Label
|
||||
@Safe.Raw(Model.Label)
|
||||
</label>
|
||||
<textarea id="@Model.Name" class="form-control @(errors is null ? "" : "is-invalid")"
|
||||
name="@Model.Name" data-val="true"
|
||||
|
|
|
@ -62,7 +62,7 @@
|
|||
</button>
|
||||
<div class="field flex-grow-1">
|
||||
<label :for="`field-option-value-${index}`" class="form-label">Value</label>
|
||||
<input :for="`field-option-value-${index}`" class="form-control" v-model="option.value" />
|
||||
<input :for="`field-option-value-${index}`" class="form-control" v-model.lazy="option.value" />
|
||||
</div>
|
||||
<div class="field flex-grow-1">
|
||||
<label :for="`field-option-text-${index}`" class="form-label">Text</label>
|
||||
|
@ -122,25 +122,25 @@
|
|||
</template>
|
||||
<template id="field-type-input">
|
||||
<div class="form-group mb-0">
|
||||
<label class="form-label" :for="name" :data-required="required" v-text="label"></label>
|
||||
<label class="form-label" :for="name" :data-required="required" v-sanitize="label"></label>
|
||||
<input class="form-control" :id="name" :name="name" :type="type" v-model="value" />
|
||||
<div v-if="helpText" :id="`HelpText-{name}`" class="form-text" v-text="helpText"></div>
|
||||
<div v-if="helpText" :id="`HelpText-{name}`" class="form-text" v-sanitize="helpText"></div>
|
||||
</div>
|
||||
</template>
|
||||
<template id="field-type-textarea">
|
||||
<div class="form-group mb-0">
|
||||
<label class="form-label" :for="name" :data-required="required" v-text="label"></label>
|
||||
<label class="form-label" :for="name" :data-required="required" v-sanitize="label"></label>
|
||||
<textarea class="form-control" :id="name" :name="name" v-model="value"></textarea>
|
||||
<div v-if="helpText" :id="`HelpText-${name}`" class="form-text" v-text="helpText"></div>
|
||||
<div v-if="helpText" :id="`HelpText-${name}`" class="form-text" v-sanitize="helpText"></div>
|
||||
</div>
|
||||
</template>
|
||||
<template id="field-type-select">
|
||||
<div class="form-group mb-0">
|
||||
<label class="form-label" :for="name" :data-required="required" v-text="label"></label>
|
||||
<label class="form-label" :for="name" :data-required="required" v-sanitize="label"></label>
|
||||
<select class="form-select" :id="name" :name="name">
|
||||
<option v-for="option in options" :key="option.value" :value="option.value" :selected="option.value === value" v-text="option.text"></option>
|
||||
</select>
|
||||
<div v-if="helpText" :id="`HelpText-${name}`" class="form-text" v-text="helpText"></div>
|
||||
<div v-if="helpText" :id="`HelpText-${name}`" class="form-text" v-sanitize="helpText"></div>
|
||||
</div>
|
||||
</template>
|
||||
<template id="field-type-fieldset">
|
||||
|
@ -150,6 +150,7 @@
|
|||
</fieldset>
|
||||
</template>
|
||||
<script src="~/vendor/vuejs/vue.min.js" asp-append-version="true"></script>
|
||||
<script src="~/vendor/vue-sanitize-directive/vue-sanitize-directive.umd.min.js" asp-append-version="true"></script>
|
||||
<script src="~/vendor/vue-sortable/sortable.min.js" asp-append-version="true"></script>
|
||||
<script src="~/vendor/vue-sortable/vue-sortable.js" asp-append-version="true"></script>
|
||||
<script src="~/js/form-editor.js" asp-append-version="true"></script>
|
||||
|
|
|
@ -119,6 +119,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||
})
|
||||
|
||||
Vue.use(vSortable)
|
||||
Vue.use(VueSanitizeDirective.default)
|
||||
|
||||
new Vue({
|
||||
el: '#FormEditor',
|
||||
|
|
52
BTCPayServer/wwwroot/vendor/vue-sanitize-directive/vue-sanitize-directive.umd.min.js
vendored
Normal file
52
BTCPayServer/wwwroot/vendor/vue-sanitize-directive/vue-sanitize-directive.umd.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Loading…
Add table
Reference in a new issue