<Spelling> - disallow passing value by innerHTML (not reactive and missing whitespaces)

This commit is contained in:
Avris 2021-03-19 20:34:34 +01:00
parent 1d273ad68d
commit 2dd3a16a18
12 changed files with 51 additions and 65 deletions

View File

@ -9,7 +9,7 @@
<li v-for="author in config.contact.authors || []" class="mb-2">
<Icon :v="author.group ? 'users' : 'user'"/>
<a :href="author.link" target="_blank" rel="noopener">
<Spelling>{{author.name}}</Spelling>
<Spelling :text="author.name"/>
</a>
</li>
<li v-if="authors === undefined">
@ -18,7 +18,7 @@
<template v-else>
<li v-for="author in authors" class="mb-2">
<Icon v="user"/>
<Spelling>{{ author.footerName }}</Spelling>
<Spelling :text="author.footerName"/>
<nuxt-link :to="`/@${author.username}`" class="badge bg-light text-dark border">
@{{author.username}}
</nuxt-link>

View File

@ -50,7 +50,7 @@
</ul>
<ul v-if="config.nouns.plurals" class="list-plural">
<li v-for="w in s.el.mascPl">
<Spelling>{{ w }}</Spelling>
<Spelling :text="w"/>
<a :href="`/api/nouns/${w}.png`" target="_blank" rel="noopener"><Icon v="image"/></a>
</li>
</ul>
@ -59,12 +59,12 @@
<p><strong><T>nouns.edited</T>:</strong></p>
<ul class="list-singular">
<li v-for="w in nouns[s.el.base].masc">
<Spelling>{{ w }}</Spelling>
<Spelling :text="w"/>
</li>
</ul>
<ul v-if="config.nouns.plurals" class="list-plural">
<li v-for="w in nouns[s.el.base].mascPl">
<Spelling>{{ w }}</Spelling>
<Spelling :text="w"/>
</li>
</ul>
</small>
@ -81,13 +81,13 @@
<td>
<ul class="list-singular">
<li v-for="w in s.el.fem">
<Spelling>{{ w }}</Spelling>
<Spelling :text="w"/>
<a :href="`/api/nouns/${w}.png`" target="_blank" rel="noopener"><Icon v="image"/></a>
</li>
</ul>
<ul v-if="config.nouns.plurals" class="list-plural">
<li v-for="w in s.el.femPl">
<Spelling>{{ w }}</Spelling>
<Spelling :text="w"/>
<a :href="`/api/nouns/${w}.png`" target="_blank" rel="noopener"><Icon v="image"/></a>
</li>
</ul>
@ -96,12 +96,12 @@
<p><strong><T>nouns.edited</T>:</strong></p>
<ul class="list-singular">
<li v-for="w in nouns[s.el.base].fem">
<Spelling>{{ w }}</Spelling>
<Spelling :text="w"/>
</li>
</ul>
<ul v-if="config.nouns.plurals" class="list-plural">
<li v-for="w in nouns[s.el.base].femPl">
<Spelling>{{ w }}</Spelling>
<Spelling :text="w"/>
</li>
</ul>
</small>
@ -110,14 +110,14 @@
<ul class="list-singular">
<li v-for="w in s.el.neutr">
<Declension v-if="config.nouns.declension" :word="w"/>
<template v-else><Spelling>{{w}}</Spelling></template>
<template v-else><Spelling :text="w"/></template>
<a :href="`/api/nouns/${w}.png`" target="_blank" rel="noopener"><Icon v="image"/></a>
</li>
</ul>
<ul v-if="config.nouns.plurals" class="list-plural">
<li v-for="w in s.el.neutrPl">
<Declension v-if="config.nouns.declension" :word="w" plural :singularOptions="s.el.neutr"/>
<template v-else><Spelling>{{w}}</Spelling></template>
<template v-else><Spelling :text="w"/></template>
<a :href="`/api/nouns/${w}.png`" target="_blank" rel="noopener"><Icon v="image"/></a>
</li>
</ul>
@ -125,10 +125,10 @@
<small v-if="s.el.base && nouns[s.el.base]">
<p><strong><T>nouns.edited</T>:</strong></p>
<ul class="list-singular">
<li v-for="w in nouns[s.el.base].neutr"><Spelling>{{ w }}</Spelling></li>
<li v-for="w in nouns[s.el.base].neutr"><Spelling :text="w"/></li>
</ul>
<ul v-if="config.nouns.plurals" class="list-plural">
<li v-for="w in nouns[s.el.base].neutrPl"><Spelling>{{ w }}</Spelling></li>
<li v-for="w in nouns[s.el.base].neutrPl"><Spelling :text="w"/></li>
</ul>
</small>
</td>

View File

@ -2,7 +2,7 @@
<span>
<span v-for="part in example[(example.isHonorific ? pronoun.isPluralHonorific(counter) : pronoun.isPlural(counter)) ? 'pluralParts' : 'singularParts']">
<strong v-if="part.variable"><Spelling :text="pronoun.getMorpheme(part.str, counter)"/></strong>
<span v-else><Spelling>{{part.str}}</Spelling></span>
<span v-else><Spelling :text="part.str"/></span>
</span>
<small v-if="link">
(<nuxt-link :to="'/' + pronoun.canonicalName"><Spelling :text="pronoun.canonicalName"/></nuxt-link>)

View File

@ -1,11 +1,11 @@
<template>
<a v-if="link" :href="`/${config.nouns.route}/${config.nouns.terms.route}#${link.toLowerCase()}`" :title="alt">
<img :src="img" alt="" class="rounded"/>
<Spelling>{{ name }}</Spelling>
<Spelling :text="name"/>
</a>
<span v-else :title="alt">
<img :src="img" alt="" class="rounded"/>
<Spelling>{{ name }}</Spelling>
<Spelling :text="name"/>
</span>
</template>

View File

@ -58,7 +58,7 @@
<div class="btn-group-vertical d-flex nav-custom mb-2">
<nuxt-link v-for="link in links" :key="link.link" :to="link.link" :class="`btn btn-sm ${isActiveRoute(link) ? 'active' : ''}`">
<Icon :v="link.icon"/>
<Spelling>{{ link.textLong || link.text }}</Spelling>
<Spelling :text="link.textLong || link.text"/>
</nuxt-link>
</div>
</div>
@ -72,7 +72,7 @@
<div class="btn-group-vertical d-flex nav-custom nav-custom-start mb-2">
<nuxt-link v-for="link in links" :key="link.link" :to="link.link" :class="`btn btn-sm ${isActiveRoute(link) ? 'active' : ''}`">
<Icon :v="link.icon"/>
<Spelling>{{ link.textLong || link.text }}</Spelling>
<Spelling :text="link.textLong || link.text"/>
</nuxt-link>
</div>
</div>
@ -82,7 +82,7 @@
<nuxt-link v-for="link in links" :key="link.link" :to="link.link" :class="`btn btn-sm ${isActiveRoute(link) ? 'active' : ''}`">
<Icon :v="link.icon" size="1.6"/>
<br/>
<span class="text-nowrap"><Spelling>{{ link.text }}</Spelling></span>
<span class="text-nowrap"><Spelling :text="link.text"/></span>
</nuxt-link>
</div>
</div>

View File

@ -2,23 +2,23 @@
<span>
<strong v-if="opinion === 1">
<img src="../node_modules/@fortawesome/fontawesome-pro/svgs/solid/heart.svg" :aria-label="$t('profile.opinion.yes')" class="icon"/>
<nuxt-link v-if="link" :to="link"><Spelling>{{ word }}</Spelling></nuxt-link>
<span v-else><Spelling>{{ word }}</Spelling></span>
<nuxt-link v-if="link" :to="link"><Spelling :text="word"/></nuxt-link>
<span v-else><Spelling :text="word"/></span>
</strong>
<span v-else-if="opinion === 2">
<Icon v="grin-tongue" :aria-label="$t('profile.opinion.jokingly')"/>
<nuxt-link v-if="link" :to="link"><Spelling>{{ word }}</Spelling></nuxt-link>
<span v-else><Spelling>{{ word }}</Spelling></span>
<nuxt-link v-if="link" :to="link"><Spelling :text="word"/></nuxt-link>
<span v-else><Spelling :text="word"/></span>
</span>
<span v-else-if="opinion === 0">
<Icon v="thumbs-up" :aria-label="$t('profile.opinion.meh')"/>
<nuxt-link v-if="link" :to="link"><Spelling>{{ word }}</Spelling></nuxt-link>
<span v-else><Spelling>{{ word }}</Spelling></span>
<nuxt-link v-if="link" :to="link"><Spelling :text="word"/></nuxt-link>
<span v-else><Spelling :text="word"/></span>
</span>
<span v-else-if="opinion === -1" class="text-muted small">
<Icon v="thumbs-down" :aria-label="$t('profile.opinion.no')"/>
<nuxt-link v-if="link" :to="link"><Spelling>{{ word }}</Spelling></nuxt-link>
<span v-else><Spelling>{{ word }}</Spelling></span>
<nuxt-link v-if="link" :to="link"><Spelling :text="word"/></nuxt-link>
<span v-else><Spelling :text="word"/></span>
</span>
</span>
</template>

View File

@ -2,12 +2,12 @@
<ul>
<li v-for="pronoun in pronouns" :key="pronoun.canonicalName">
<nuxt-link v-if="typeof pronoun === 'string'" :to="'/' + pronoun">
<strong><Spelling>{{pronoun.replace(/&/g, ' ' + $t('pronouns.or') + ' ')}}</Spelling></strong>
<strong><Spelling :text="pronoun.replace(/&/g, ' ' + $t('pronouns.or') + ' ')"/></strong>
</nuxt-link>
<nuxt-link v-else :to="addSlash('/' + pronoun.canonicalName)">
<strong><Spelling>{{pronoun.name(glue)}}</Spelling></strong><small v-if="pronoun.smallForm">/<Spelling>{{pronoun.morphemes[pronoun.smallForm]}}</Spelling></small>
<strong><Spelling :text="pronoun.name(glue)"/></strong><small v-if="pronoun.smallForm">/<Spelling :text="pronoun.morphemes[pronoun.smallForm]"/></small>
<small><Spelling>{{pronoun.description}}</Spelling></small>
<small><Spelling :text="pronoun.description"/></small>
</nuxt-link>
<NormativeBadge v-if="pronoun.normative"/>
</li>

View File

@ -2,7 +2,7 @@
<div class="my-2" v-if="!deleted">
<h3 class="h6">
<Icon :v="source.icon()"/>
<strong><Spelling v-if="source.author">{{source.author.replace('^', '')}}</Spelling><span v-if="source.author"> </span><em><a v-if="source.link" :href="source.link" target="_blank" rel="noopener"><Spelling :text="addMarks(source.title)"></Spelling></a><Spelling v-else :text="addMarks(source.title)"></Spelling></em></strong><template v-if="source.extra"> (<Spelling>{{source.extra}}</Spelling>)</template>, {{source.year}}<template v-if="source.comment">; <Spelling>{{source.comment}}</Spelling></template>
<strong><Spelling v-if="source.author">{{source.author.replace('^', '')}}</Spelling><span v-if="source.author"> </span><em><a v-if="source.link" :href="source.link" target="_blank" rel="noopener"><Spelling :text="addMarks(source.title)"></Spelling></a><Spelling v-else :text="addMarks(source.title)"></Spelling></em></strong><template v-if="source.extra"> (<Spelling :text="source.extra"/>)</template>, {{source.year}}<template v-if="source.comment">; <Spelling :text="source.comment"/></template>
</h3>
<ul class="list-inline" v-if="manage && $isGranted('sources')">
<li v-if="!source.approved" class="list-inline-item">
@ -50,7 +50,7 @@
</li>
<li class="list-inline-item">
<span v-for="p in source.pronouns" :class="['badge', pronounLibrary.isCanonical(p) ? 'bg-success' : 'bg-danger', 'm-1']">
<Spelling>{{p}}</Spelling>
<Spelling :text="p"/>
</span>
</li>
<li class="list-inline-item" v-if="source.key">

View File

@ -4,21 +4,10 @@
export default {
mixins: [ spelling ],
props: {
text: {},
text: { required: true },
},
render(h) {
return h('span', {domProps: { innerHTML: this.handleSpelling(this.val) }});
return h('span', {domProps: { innerHTML: this.handleSpelling(this.text) }});
},
computed: {
val() {
if (this.text !== undefined) {
return this.text;
}
if (this.$slots.default && this.$slots.default.length) {
return this.$slots.default[0].text;
}
return ''
}
}
}
</script>

View File

@ -24,7 +24,7 @@
<ul class="list-group mt-4">
<li v-for="[group, groupPronouns] in pronounLibrary.split()" class="list-group-item">
<p class="h5">
<Spelling>{{ group.name }}</Spelling>
<Spelling :text="group.name"/>
</p>
<div class="small my-1" v-if="group.description">
<Icon v="info-circle"/>
@ -34,7 +34,7 @@
</li>
<li v-if="config.pronouns.multiple !== false" class="list-group-item">
<p class="h5">
<Spelling>{{ config.pronouns.multiple.name }}</Spelling>
<Spelling :text="config.pronouns.multiple.name"/>
</p>
<div class="small my-1" v-if="config.pronouns.multiple.description">
<Icon v="info-circle"/>
@ -57,7 +57,7 @@
<button :class="['btn', multiple.includes(pronounName) ? 'btn-primary' : 'btn-outline-primary', 'btn-sm', 'my-1']"
@click="toggleMultiple(pronounName)"
>
<Spelling>{{pronoun.name()}}</Spelling>
<Spelling :text="pronoun.name()"/>
</button>
</li>
</ul>
@ -70,7 +70,7 @@
</li>
<li v-if="config.pronouns.null !== false" class="list-group-item">
<p class="h5">
<Spelling>{{ config.pronouns.null.description }}</Spelling>
<Spelling :text="config.pronouns.null.description"/>
</p>
<div class="small my-1" v-if="config.pronouns.null.history">
<Icon v="info-circle"/>
@ -83,7 +83,7 @@
</li>
<li v-if="config.pronouns.emoji !== false" class="list-group-item">
<p class="h5">
<Spelling>{{ config.pronouns.emoji.description }}</Spelling>
<Spelling :text="config.pronouns.emoji.description"/>
</p>
<div class="small my-1" v-if="config.pronouns.emoji.history">
<Icon v="info-circle"/>
@ -120,7 +120,7 @@
<button :class="['btn', pronoun.name(glue) === selectedPronoun.name(glue) ? 'btn-primary' : 'btn-outline-primary', 'btn-sm', 'my-1']"
@click="selectedPronoun = pronouns[pronounName].clone()"
>
<Spelling>{{pronoun.name(glue)}}</Spelling>
<Spelling :text="pronoun.name(glue)"/>
</button>
</li>
</ul>
@ -128,7 +128,7 @@
<div class="alert alert-primary">
<p class="h3 mb-0 text-center">
<Spelling>{{ selectedPronoun.name(glue) }}</Spelling>
<Spelling :text="selectedPronoun.name(glue)"/>
<br/>
<input v-model="selectedPronoun.description"
class="form-control form-input p-0 form-control-sm"
@ -152,7 +152,7 @@
@focus="selectedMorpheme = part.str"
@blur="selectedMorpheme = ''"
/>
<span v-else><Spelling>{{part.str}}</Spelling></span>
<span v-else><Spelling :text="part.str"/></span>
</span>
</li>
</ul>

View File

@ -33,7 +33,7 @@
<section v-if="profile.age ||profile.description.trim().length">
<p v-for="line in profile.description.split('\n')" class="mb-1">
<Spelling>{{ line }}</Spelling>
<Spelling :text="line"/>
</p>
<p v-if="profile.age">
<Icon v="birthday-cake"/>

View File

@ -16,21 +16,18 @@
<template v-for="(nameOption, i) in nameOptions">
<nuxt-link :to="'/' + addSlash(nameOption)">
<strong>
<Spelling>{{ nameOption }}</Spelling>
<Spelling :text="nameOption"/>
</strong>
</nuxt-link>
<span v-if="i < nameOptions.length - 1"><Spelling>{{ glue }}</Spelling></span>
<span v-if="i < nameOptions.length - 1"><Spelling :text="glue"/></span>
</template>
</template>
</h2>
<p class="h6 small text-center mb-0 mt-2" v-if="selectedPronoun.description">
<em>
<Spelling>
({{Array.isArray(selectedPronoun.description)
(<Spelling :text="Array.isArray(selectedPronoun.description)
? ($t('pronouns.alt.header') + ': ' + selectedPronoun.description.join(glue))
: selectedPronoun.description
}})
</Spelling>
: selectedPronoun.description"/>)
</em>
</p>
</div>
@ -68,7 +65,7 @@
<ul class="list-group mt-4">
<li class="list-group-item">
<p class="h5">
<Spelling>{{ pronounGroup.group.name }}</Spelling>
<Spelling :text="pronounGroup.group.name"/>
</p>
<div class="small my-1">
<Icon v="info-circle"/>
@ -77,12 +74,12 @@
<ul class="list-unstyled">
<li v-for="pronoun in pronounGroup.groupPronouns" :key="pronoun.canonicalName">
<nuxt-link v-if="typeof pronoun === 'string'" :to="'/' + pronoun">
<strong><Spelling>{{pronoun.replace(/&/g, ' ' + $t('pronouns.or') + ' ')}}</Spelling></strong>
<strong><Spelling :text="pronoun.replace(/&/g, ' ' + $t('pronouns.or') + ' ')"/></strong>
</nuxt-link>
<nuxt-link v-else :to="addSlash('/' + pronoun.canonicalName)">
<strong><Spelling>{{pronoun.name(glue)}}</Spelling></strong><small v-if="pronoun.smallForm">/<Spelling>{{pronoun.morphemes[pronoun.smallForm]}}</Spelling></small>
<strong><Spelling :text="pronoun.name(glue)"/></strong><small v-if="pronoun.smallForm">/<Spelling :text="pronoun.morphemes[pronoun.smallForm]"/></small>
<small><Spelling>{{pronoun.description}}</Spelling></small>
<small><Spelling :text="pronoun.description"/></small>
</nuxt-link>
<NormativeBadge v-if="pronoun.normative"/>
</li>