2020-10-11 05:50:33 -07:00
|
|
|
<template>
|
2021-07-10 04:18:22 -07:00
|
|
|
<span class="position-relative">
|
2020-10-12 11:28:20 -07:00
|
|
|
<template v-if="declensionTemplate">
|
2021-07-10 04:18:22 -07:00
|
|
|
<a v-if="!open" href="#" @click.prevent="visible = !visible" :class="tooltip && visible ? 'fw-bold' : ''">{{ word }}</a>
|
|
|
|
<ul v-if="visible" :class="['list-unstyled', 'small', open ? '' : 'm-2 p-3 pe-5 border bg-light', tooltip ? 'tooltip' : '']">
|
2020-10-16 03:53:46 -07:00
|
|
|
<li v-for="(declined, c) in declensionTemplate.decline(word, plural)" class="text-nowrap">
|
|
|
|
<strong>{{c}} <small v-if="!condense">({{cases[c]}})</small></strong> {{ declined.join(' / ') }}
|
2020-10-11 05:50:33 -07:00
|
|
|
</li>
|
2021-07-10 04:18:22 -07:00
|
|
|
<li v-if="tooltip" class="close"><a href="#" @click.prevent="visible = false"><Icon v="times"/></a></li>
|
2020-10-11 05:50:33 -07:00
|
|
|
</ul>
|
|
|
|
</template>
|
|
|
|
<template v-else>{{ word }}</template>
|
|
|
|
</span>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
|
|
|
import { nounDeclensionTemplates } from "../src/data";
|
2020-10-12 06:49:33 -07:00
|
|
|
import cases from "../data/nouns/cases";
|
2020-10-11 05:50:33 -07:00
|
|
|
|
|
|
|
export default {
|
|
|
|
props: {
|
|
|
|
word: { required: true },
|
|
|
|
plural: { type: Boolean },
|
2020-10-12 11:28:20 -07:00
|
|
|
singularOptions: { },
|
|
|
|
template: { },
|
2020-10-16 03:53:46 -07:00
|
|
|
open: { type: Boolean },
|
|
|
|
condense: { type: Boolean },
|
2021-07-10 04:18:22 -07:00
|
|
|
tooltip: { type: Boolean },
|
2020-10-11 05:50:33 -07:00
|
|
|
},
|
|
|
|
data() {
|
|
|
|
return {
|
2020-10-12 11:28:20 -07:00
|
|
|
declensionTemplate: this.template || this.findTemplate(),
|
2020-10-11 05:50:33 -07:00
|
|
|
cases,
|
2020-10-16 03:53:46 -07:00
|
|
|
visible: this.open,
|
2020-10-11 05:50:33 -07:00
|
|
|
}
|
|
|
|
},
|
|
|
|
methods: {
|
|
|
|
findTemplate() {
|
|
|
|
let longestMatch = 0;
|
|
|
|
let templates = [];
|
|
|
|
for (let t of nounDeclensionTemplates) {
|
|
|
|
const matchLength = t.matches(this.word, this.plural);
|
|
|
|
if (matchLength === 0) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (matchLength > longestMatch) {
|
|
|
|
longestMatch = matchLength;
|
|
|
|
templates = [t];
|
|
|
|
} else if (matchLength === longestMatch) {
|
|
|
|
templates.push(t);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!templates.length) {
|
|
|
|
return null;
|
|
|
|
} else if (templates.length === 1) {
|
|
|
|
return templates[0];
|
|
|
|
} else if (this.plural && this.singularOptions) {
|
|
|
|
for (let t of templates) {
|
|
|
|
for (let s of this.singularOptions) {
|
|
|
|
if (t.matches(s)) {
|
|
|
|
return t;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return templates[0];
|
|
|
|
},
|
|
|
|
},
|
2021-08-03 10:25:48 -07:00
|
|
|
watch: {
|
|
|
|
template() {
|
|
|
|
this.declensionTemplate = this.template || this.findTemplate();
|
|
|
|
},
|
|
|
|
}
|
2020-10-11 05:50:33 -07:00
|
|
|
};
|
|
|
|
</script>
|
2021-07-10 04:18:22 -07:00
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
ul.tooltip {
|
|
|
|
position: absolute;
|
|
|
|
top: 1rem;
|
|
|
|
left: 0;
|
|
|
|
z-index: 999;
|
|
|
|
li.close {
|
|
|
|
position: absolute;
|
|
|
|
top: 1rem;
|
|
|
|
right: 1rem;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
</style>
|