Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
No results found
Show changes
Showing
with 3727 additions and 1027 deletions
src/assets/background.jpg

451 KiB

File added
File added
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64"
height="64"
viewBox="0 0 16.933333 16.933334"
version="1.1"
id="svg8"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
sodipodi:docname="logo-icon.svg"
inkscape:export-filename="/home/has022/Documents/256.png"
inkscape:export-xdpi="170.66667"
inkscape:export-ydpi="170.66667">
<defs
id="defs2">
<linearGradient
inkscape:collect="always"
id="linearGradient4545">
<stop
style="stop-color:#560027;stop-opacity:1;"
offset="0"
id="stop4541" />
<stop
style="stop-color:#560027;stop-opacity:0;"
offset="1"
id="stop4543" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4545"
id="linearGradient4547"
x1="9.9130554"
y1="277.94998"
x2="28.186945"
y2="277.94998"
gradientUnits="userSpaceOnUse" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:zoom="3.959798"
inkscape:cx="233.45423"
inkscape:cy="-7.9212896"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
units="px"
inkscape:window-width="3840"
inkscape:window-height="2084"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-280.06665)">
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:35.27777863px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#bc477b;fill-opacity:1;stroke:none;stroke-width:0.26458332"
x="1.4181669"
y="295.72998"
id="text3715"><tspan
sodipodi:role="line"
x="1.4181669"
y="295.72998"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:21.16666603px;font-family:'Inria Serif';-inkscape-font-specification:'Inria Serif';fill:#bc477b;fill-opacity:1;stroke-width:0.26458332"
id="tspan21">O</tspan></text>
</g>
</svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="144"
height="144"
viewBox="0 0 38.099999 38.100001"
version="1.1"
id="svg8"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
sodipodi:docname="anchor-icon.svg"
inkscape:export-filename="/home/has022/Documents/logo-transparent.png"
inkscape:export-xdpi="170.66667"
inkscape:export-ydpi="170.66667">
<defs
id="defs2">
<linearGradient
inkscape:collect="always"
id="linearGradient4545">
<stop
style="stop-color:#560027;stop-opacity:1;"
offset="0"
id="stop4541" />
<stop
style="stop-color:#560027;stop-opacity:0;"
offset="1"
id="stop4543" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4545"
id="linearGradient4547"
x1="9.9130554"
y1="277.94998"
x2="28.186945"
y2="277.94998"
gradientUnits="userSpaceOnUse" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:zoom="1.979899"
inkscape:cx="180.06393"
inkscape:cy="31.926411"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
units="px"
inkscape:window-width="3840"
inkscape:window-height="2084"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-258.89998)">
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:35.27777863px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#bc477b;fill-opacity:1;stroke:none;stroke-width:0.26458332"
x="8.4772501"
y="288.745"
id="text3715"><tspan
sodipodi:role="line"
x="8.4772501"
y="288.745"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:31.75px;font-family:'Inria Serif';-inkscape-font-specification:'Inria Serif';fill:#bc477b;fill-opacity:1;stroke-width:0.26458332"
id="tspan21">O</tspan></text>
</g>
</svg>
File added
File added
File added
This diff is collapsed.
<template>
<article v-if="article" :class="dictionary">
<Header :lemmas="article.lemmas" :dictionary="dictionary" :article_id="article.article_id" />
<div class="article_content" :class="$vuetify.breakpoint.name">
<div v-if="article" :lang="{nob:'nb', nno: 'nn', eng: 'en', 'ukr': 'uk'}[dictionary]" class="article-container">
<span :lang="lang_tag_locale" v-if="$vuetify.breakpoint.smAndDown || !$route.name || $route.name == 'lookup'" class="dict-label" role="heading" aria-level="2">{{dict_label}}</span>
<div class="article" v-bind:class="{'expanded': !collapsed && collapsable, 'collapsable': collapsable, 'hide-label': hide_label, 'v-sheet v-card rounded-xl': !$parent.article}" v-if="article">
<div :class="$vuetify.breakpoint.name" v-if="!invalid">
<Header :title_id="title_id" :lemmas="article.lemmas" :dictionary="dictionary" :article_id="article.article_id" @toggle-collapse = "toggle_collapse"/>
<div class="article_content" :class="$vuetify.breakpoint.name" v-show="!collapsed" ref="article_content">
<section v-if="article.body.pronunciation && article.body.pronunciation.length" class="pronunciation">
<h3>Uttale</h3>
<h4 :lang="lang_tag_locale">{{$t('article.headings.pronunciation', content_locale)}}</h4>
<ul>
<DefElement v-for="(element, index) in article.body.pronunciation" :dictionary="dictionary" :key="index" :body='element' @article-click="article_link_click" />
<DefElement v-for="(element, index) in article.body.pronunciation" :dictionary="dictionary" :key="index" :body='element' @article-click="article_link_click" @error="article_error"/>
</ul>
</section>
<section v-if="article.body.etymology && article.body.etymology.length" class="etymology">
<h3>Opphav</h3>
<h4 :lang="lang_tag_locale">{{$t('article.headings.etymology', content_locale)}}</h4>
<ul>
<DefElement v-for="(element, index) in article.body.etymology" :dictionary="dictionary" :key="index" :body='element' @article-click="article_link_click" />
<DefElement v-for="(element, index) in article.body.etymology" :dictionary="dictionary" :key="index" :body='element' @article-click="article_link_click" @error="article_error"/>
</ul>
</section>
<section class="definitions" v-if="has_content" tabindex="0">
<h3 tabindex="0">{{def_label}}</h3>
<section class="definitions" v-if="has_content">
<h4 :lang="lang_tag_locale">{{$t('article.headings.definitions', content_locale)}}</h4>
<ol>
<Definition v-for="definition in article.body.definitions" :dictionary="dictionary" :level="1" :key="definition.id" :body='definition' @article-click="article_link_click" />
<Definition v-for="definition in article.body.definitions" :dictionary="dictionary" :level="1" :key="definition.id" :body='definition' @article-click="article_link_click" @error="article_error"/>
</ol>
</section>
<section v-if="sub_articles.length" class="expressions">
<h3>Faste uttrykk</h3>
<h4 :lang="lang_tag_locale">{{$t('article.headings.expressions', content_locale)}}</h4>
<ul>
<SubArticle :body="subart" v-for="(subart, index) in sub_articles" :dictionary="dictionary" :key="index" @article-click="article_link_click" />
<SubArticle :body="subart" v-for="(subart, index) in sub_articles" :dictionary="dictionary" :key="index" @article-click="article_link_click" @error="article_error"/>
</ul>
</section>
<div class="fade">
<router-link class="choose" :to="link_to_self.ref" @click.native="details_click(link_to_self)">
Velg <v-icon large class="nav_arrow">arrow_right</v-icon>
</router-link>
</div>
</div>
<ArticleFooter :article="article"/>
</article>
<ArticleFooter v-if="!collapsed" :article="article"/>
</div>
<div v-else><v-icon left>warning</v-icon> {{$t('error.article', {no: article.article_id, dict: $t('dicts_inline.'+this.dictionary)})}}</div>
</div>
</div>
</template>
<script src="/dist/vue-social-sharing.js"></script>
<script>
import DefElement from './DefElement.vue'
import Definition from './Definition.vue'
import SubArticle from './SubArticle.vue'
import Header from './Header.vue'
import ArticleFooter from './ArticleFooter.vue'
import entities from '../utils/entities.js'
import Mark from 'mark.js';
function find_sub_articles(definition) {
let sub_art_list = []
let sub_definitions = definition.elements.filter(el => el.type_ == 'definition')
sub_definitions.forEach((subdef, i) => {
sub_art_list = sub_art_list.concat(find_sub_articles(subdef))
})
let sub_articles = definition.elements.filter(el => el.type_ == 'sub_article' && el.lemmas)
sub_art_list = sub_art_list.concat(sub_articles)
try {
let sub_definitions = definition.elements.filter(el => el.type_ == 'definition')
let sub_articles = definition.elements.filter(el => el.type_ == 'sub_article' && el.lemmas)
sub_definitions.forEach((subdef, i) => {
sub_art_list = sub_art_list.concat(find_sub_articles(subdef))
})
sub_art_list = sub_art_list.concat(sub_articles)
return sub_art_list
}
function find_content(definition) {
let content_list = []
let sub_definitions = definition.elements.filter(el => el.type_ == 'definition')
sub_definitions.forEach((subdef, i) => {
content_list = content_list.concat(find_content(subdef))
})
let content_nodes = definition.elements.filter(el => ['explanation', 'example', 'compound_list'].includes(el.type_))
content_list = content_list.concat(content_nodes)
}
catch(error) {
console.log("find_sub_articles", this.article.article_id, this.dictionary, '"'+error.message+'"')
return content_list
return []
}
}
export default {
name: 'Article',
props: {
article: Object
article: Object,
articleLookup: Boolean,
title_id: String,
queryPattern: String,
scope: String,
},
computed: {
link_to_self: function() {
return {
ref: '/' + this.dictionary + '/' + this.article.article_id + '/' + encodeURIComponent(this.article.lemmas[0].lemma),
article: this.article
data: function() {
return {
is_collapsed: true,
invalid: false
}
},
metaInfo() {
if (this.articleLookup) {
return {title: this.article.lemmas[0].lemma + ' | ' + {"bm,nn": "Bokmålsordboka og Nynorskordboka", "bm": "Bokmålsordboka", "nn": "Nynorskordboka"}[this.dictionary],
meta: [{name: 'description', vmid: 'description', content: this.meta_description}],
link: [{rel: "canonical", href: `https://ordbokene.no/${this.article.dictionary}/${this.article.article_id}`} ]
}
}
},
computed: {
hide_label: function() {
//collapsable || (collapsed && $store.state.collapseArticles != 'never')
if (this.$parent.count_bm || this.$parent.count_nn) {
let two_results = (this.$parent.count_bm + this.$parent.count_nn) < 3
if (two_results) {
return false
}
else if (this.$vuetify.breakpoint.mdAndUp && (this.collapsed || this.$store.state.collapseArticles == 'never')) {
return true
}
else {
return false
}
}
},
dictionary: function() {
return this.article.dictionary
},
def_label: function() {
return this.dictionary == 'bob' ? 'Betydning og bruk' : 'Tyding og bruk'
content_locale: function() {
if (this.$i18n.locale == 'eng') {
return 'eng'
} else if (this.$i18n.locale == 'ukr') {
return 'ukr'
} else {
return {bm: 'nob', nn: 'nno'}[this.dictionary]
}
},
example_label: function() {
return this.dictionary == 'bob' ? 'Eksempel' : 'Døme'
fulltext_highlight: function() {
return this.$store.state.fulltextHighlight
},
collapsable: function() {
if (this.$parent.$options.name != 'SearchResults') {
this.is_collapsed = false
return false
}
let collapsable = this.$store.state.collapseArticles
if (collapsable == 'never') {
this.is_collapsed = false
return false
}
if (collapsable == 'always') {
this.is_collapsed = true
return true
}
if (collapsable == 'auto') {
this.is_collapsed = this.$parent.$options.name == 'SearchResults' && (this.$parent.results_bm.length + this.$parent.results_nn.length > 2)
return this.$parent.$options.name == 'SearchResults' && (this.$parent.results_bm.length + this.$parent.results_nn.length > 2)
}
},
collapsed: {
get() {
if (this.$parent.$options.name != 'SearchResults') {
return false
}
if (!this.collapsable) {
this.is_collapsed = false
}
return this.is_collapsed
},
set(value) {
this.is_collapsed = value
}
},
snippet: function() {
if (this.collapsable && this.article.body.definitions) {
return this.meta_description
}
return null
},
meta_description: function() {
return this.parse_definitions(this.article.body.definitions)
},
link_to_self: function() {
try {
return {
ref: '/' + this.dictionary + '/' + this.article.article_id,
article: this.article
}
} catch(error) {
console.log("link_to_self",this.article.article_id, this.dictionary, '"'+error.message+'"')
this.invalid = true
//console.error(error)
return {ref: "", article: this.article}
}
},
lang_tag_locale: function() {
return {nob: "nb", nno: "nn", eng: "en", ukr: "uk"}[this.content_locale]
},
dict_label: function() {
let label = ''
const dictionary = this?.article?.dictionary
if (dictionary) {
if (this.$route.name) {
label = this.$t(`dicts.${dictionary}`, this.content_locale)
} else {
label = this.$t('from', this.content_locale) + " " + this.$t(`dicts_from.${dictionary}`, this.content_locale)
}
}
return label
},
sub_articles: function() {
return this.article.body.definitions.reduce((acc, val) => acc.concat(find_sub_articles(val)), []).sort((s1, s2) => s1.lemmas[0].localeCompare(s2.lemmas[0]))
},
has_content: function() {
return this.article.body.definitions.reduce((acc, val) => acc.concat(find_content(val)), []).length > 0
for (const definition of this.article.body.definitions) {
for (const element of definition.elements) {
if (['explanation', 'example', 'compound_list', 'definition'].includes(element.type_)) {
return true
}
}
}
return false
}
},
components: {
......@@ -106,11 +213,115 @@ export default {
Header,
ArticleFooter
},
mounted: function() {
if (this.scope && this.scope.includes("f")) {
let instance = new Mark(this.$refs.article_content)
if (/[_%|]/.test(this.queryPattern)) {
instance.markRegExp(new RegExp(this.queryPattern), {acrossElements: true, separateWordSearch:false});
}
else {
instance.mark(this.queryPattern, {acrossElements: true, separateWordSearch:false, accuracy: 'exact', wildcards: 'enabled'});
}
}
if (this.$route.hash == "#"+ this.title_id) {
let focused = document.getElementById(this.title_id)
if (focused) focused.focus()
}
else if (this.$route.hash) {
let focused =document.getElementById(this.$route.hash.replace("#",""))
if (focused) focused.scrollIntoView({block: "center"})
}
},
methods: {
article_error: function(payload) {
console.log("DefElement",payload.location, this.article.article_id, this.dictionary, '"'+payload.message+'"')
},
parse_subitems: function(explanation, text) {
let new_string = ""
let old_parts = text.split(/(\$)/)
let linkIndex = 0
let self = this
old_parts.forEach((item) => {
if (item == '$') {
let subitem = explanation.items[linkIndex]
if (/^\d$/.test(subitem.text)) {
if (subitem.type_ == "superscript") {
new_string += "⁰¹²³⁴⁵⁶⁷⁸⁹"[parseInt(subitem.text)]
}
else if (subitem.type_ == "subscript") {
new_string += "₀₁₂₃₄₅₆₇₈₉"[parseInt(subitem.text)]
}
}
else if (subitem.id) {
new_string += entities[self.dictionary][explanation.items[linkIndex].id].expansion
}
else if (subitem.text) {
if (subitem.text.includes('$')) {
new_string += self.parse_subitems(subitem, subitem.text)
}
else new_string += subitem.text
}
else {
if (explanation.items[linkIndex].lemmas) {
new_string += explanation.items[linkIndex].word_form || explanation.items[linkIndex].lemmas[0].lemma
}
}
linkIndex += 1
}
else {
new_string += item
}
})
return new_string
},
parse_definitions: function(node) {
let definitionTexts = []
let self = this
try {
node.forEach((definition) => {
if (definition.elements) {
if (definition.elements[0].content) {
let new_string = self.parse_subitems(definition.elements[0], definition.elements[0].content)
if (new_string.substring(new_string.length, new_string.length - 1) == ":") {
new_string = new_string.slice(0, -1)
}
definitionTexts.push(new_string)
}
else if (definition.elements[0].elements) {
definitionTexts.push(self.parse_definitions(definition.elements))
}
}
})
} catch(error) {
console.log("parse_definitions",this.article.article_id, this.dictionary, '"'+error.message+'"')
this.invalid = true
definitionTexts = []
}
let snippet = definitionTexts.join("\u00A0•\u00A0")
return snippet
},
toggle_collapse: function() {
if (this.collapsed) {
this.$plausible.trackEvent('expand article', {props: {article: `${this.dictionary} ${this.article.article_id}`}})
}
this.collapsed = !this.collapsed
},
article_link_click: function(item) {
this.$emit('article-click', item)
},
details_click: function(item) {
item.title_id = this.title_id
this.$emit('details-click', item)
}
}
......@@ -118,37 +329,43 @@ export default {
</script>
<style>
article {
.article {
position: relative;
padding: 24px;
margin: 10px;
border-radius: 30px;
border: solid 1px var(--v-border-base);
padding-bottom: 12px;
margin-bottom: 20px;
margin-right: 10px;
margin-left: 10px;
background-color: #ffffff;
}
#single_article_container article {
border: solid 2px var(--v-primary-base);
section.xs .article, section.sm .article {
margin-bottom: 10px !important;
}
.fade {
display: none;
section.md .article, section.lg .article, section.xl .article {
padding-top: 10px;
}
section {
padding-top: 1em;
.welcome .article_footer {
display: block;
}
h3 {
color: var(--v-primary-base);
font-variant: small-caps;
#single_article_container .article {
border: none;
margin-top: 10px;
}
section {
padding-top: 10px;
padding-bottom: 10px
}
section.etymology > h3, section.pronunciation > h3 {
section.etymology > h4, section.pronunciation > h4 {
display: inline;
font-size: 14px;
font-variant: revert;
}
section.etymology ul, section.pronunciation ul, section.etymology li, section.pronunciation li {
......@@ -211,13 +428,35 @@ ul li.definition {
list-style: disc;
}
.fade .nav_arrow {
vertical-align: sub;
}
.choose {
color: var(--v-primary-base) !important;
text-decoration: none;
}
.info-card {
padding: 12px;
}
.expanded {
padding-bottom: 34px;
}
.header {
border-radius: 0px !important;
}
.dict-label {
color: var(--v-primary-base) ;
font-weight: bold;
position: absolute;
padding-left: 34px;
margin-top: -2px;
z-index: 2;
font-variant-caps: all-small-caps;
font-size: 1.17em;
}
......
<template>
<div class="article_footer">
<span v-if="hasPointer">
<button aria-label="Del ordboksartikkel på Facebook" class="share_button" tabindex="0">
<ShareNetwork network="facebook"
title=""
:url="share_link"
tabindex="-1">
<v-icon dense>$vuetify.icons.facebook</v-icon>
</ShareNetwork>
</button>
<button aria-label="Del del ordboksartikkel på Twitter" class="share_button" tabindex="0">
<ShareNetwork
network="twitter"
:url="share_link"
:title="dict_label"
hashtags="#ordbøkene"
tabindex="-1">
<v-icon dense>$vuetify.icons.twitter</v-icon>
</ShareNetwork>
</button>
</span>
<button v-if="webShareApiSupported" aria-label="Del ordboksartikkelen med andre" class="share_button" tabindex="0" @click="shareViaWebShare">
<span v-if="!hasPointer" class = "share_text">Del ordet</span>
<v-icon dense>$vuetify.icons.share</v-icon>
</button>
<div class = "footer_title" tabindex="0">Ordbøkene.no
</div>
<div :lang="lang_tag_locale" class="article_footer">
<v-snackbar centered
max-width="300px"
min-width="300px"
max-height="36px"
min-height="36px"
rounded="pill"
v-model='copy_popup'
timeout="1000">
<span class="text-center">{{$t(what_copied, content_locale)}}</span>
</v-snackbar>
<v-btn v-if="showLinkCopy"
small text class="toolbar-button" rounded @click="copy_link">
<v-icon small left>link</v-icon><span class = "button-text">{{$t("article.copy_link", content_locale)}}</span>
</v-btn>
<v-btn v-if="webShareApiSupported" text small class="toolbar-button" rounded @click="shareViaWebShare">
<v-icon small left>share</v-icon><span class = "button-text">{{$t("article.share", content_locale)}}</span>
</v-btn>
<v-dialog max-width="600px" v-model="citation_dialog">
<template v-slot:activator="{ on, attrs }">
<v-btn @click="track_citation" text small class="toolbar-button" rounded v-on="on" v-bind="attrs">
<v-icon left small>format_quote</v-icon> <span class = "button-text">{{$t("article.cite", content_locale)}}</span>
</v-btn>
</template>
<v-card>
<v-toolbar elevation="0">
<v-toolbar-title><span role="heading" aria-level="1">{{$t('article.cite_title')}}</span></v-toolbar-title>
<v-spacer></v-spacer><v-toolbar-items><v-btn @click="close_citation_dialog" text>{{$t('close')}}<v-icon right>close</v-icon></v-btn></v-toolbar-items></v-toolbar>
<v-card-text class="text--primary">
{{$t("article.cite_description[0]", content_locale)}}<em>{{$t('dicts.'+$parent.dictionary)}}</em>{{$t("article.cite_description[1]", content_locale)}}
<br/>
<div id = "citation" v-html="this.create_citation()"/>
</v-card-text>
<v-card-actions>
<v-btn depressed small rounded @click="copy_citation"><br>
<v-icon left small icon>content_copy</v-icon> <span class = "button-text">{{$t("article.copy", content_locale)}}</span>
</v-btn>
<v-btn depressed small rounded @click="download_ris"><br>
<v-icon left small icon>get_app</v-icon> <span class = "button-text">{{$t("article.download")}}</span>
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</div>
</template>
......@@ -36,50 +64,112 @@ export default {
article: Object
},
computed: {
dict_label: function() { // TODO: reuse code used in header
return {
'bob': 'Fra bokmålsordboka',
'nob': 'Frå nynorskordboka'
}[this.article.dictionary] + ': ' + this.article.lemmas[0].lemma || ''
},
webShareApiSupported() {
return navigator.share
},
showLinkCopy() {
return (!navigator.share || this.$vuetify.breakpoint.mdAndUp) && navigator.clipboard
},
hasPointer() {
return window.matchMedia('(hover: hover) and (pointer: fine)').matches
},
share_link: function() {
let host = window.location.hostname === 'localhost'? 'https://dev.ordbok.uib.no/' : window.location.href
return host + this.article.dictionary + '/' + this.article.article_id + '/' + encodeURIComponent(this.article.lemmas[0].lemma)
content_locale: function() {
return this.$parent.content_locale
},
lang_tag_locale: function() {
return this.$parent.lang_tag_locale
}
},
data: function() {
return {
copy_popup: false,
citation_dialog: false,
what_copied: null
}
},
methods: {
track_citation() {
this.$plausible.trackEvent('citation click', {props: {article: `${this.$parent.dictionary} ${this.$parent.article.article_id}`}})
},
shareViaWebShare() {
this.$plausible.trackEvent('webshare', {props: {article: `${this.$parent.dictionary} ${this.$parent.article.article_id}`}})
navigator.share({
title: "Ordbøkene.no: " + this.article.lemmas[0].lemma,
text: "",
url: "/" + this.article.dictionary + '/' + this.article.article_id + '/' + encodeURIComponent(this.article.lemmas[0].lemma)
url: "/" + this.article.dictionary + '/' + this.article.article_id
})
}
},
create_link() {
return 'https://ordbokene.no/' + this.article.dictionary + '/' + this.article.article_id
},
get_citation_info() {
let date = new Date();
let dd = (date.getDate() < 10? '0' : '') + date.getDate()
let mm = (date.getMonth() < 9? '0' : '') + (date.getMonth()+1)
let yyyy = date.getFullYear()
let link = this.create_link()
let lemma = this.article.lemmas[0].lemma
let dict = this.$t(`dicts.${this.article.dictionary}`, this.content_locale)
return [lemma, dd, mm, yyyy, link, dict]
},
create_citation() {
const [lemma, dd, mm, yyyy, link, dict] = this.get_citation_info()
let citation = this.$t("article.citation", {lemma, link, dd, mm, yyyy, dict})
return citation
},
copy_link() {
let link = this.create_link()
console.log(`${this.$parent.dictionary} ${this.$parent.article.article_id}`)
this.$plausible.trackEvent('copy link', {props: {article: `${this.$parent.dictionary} ${this.$parent.article.article_id}`}})
let self = this
navigator.clipboard.writeText(link).then(() => {
self.what_copied = this.$t("article.link_copied")
self.copy_popup = true
}).catch(err => {
console.log("ERROR COPYING:",err)
})
},
copy_citation() {
let citation = document.getElementById("citation").textContent;
navigator.clipboard.writeText(citation)
this.citation_dialog = false
this.what_copied = this.$t("article.citation_copied")
this.copy_popup = true
},
close_citation_dialog() {
this.citation_dialog = false
},
download_ris() {
const [lemma, dd, mm, yyyy, link] = this.get_citation_info()
const a = document.createElement("a")
a.style = "display: none"
a.setAttribute("download", `${lemma}_${this.article.dictionary}.ris`)
const dict = {"bm":"Bokmålsordboka", "nn": "Nynorskordboka"}[this.article.dictionary]
const text = `TY - DICT\nTI - ${lemma}\nT2 - ${dict}\nPB - Språkrådet og Universitetet i Bergen\nUR - ${link}\nY2 - ${yyyy}/${mm}/${dd}/\nER - `
a.setAttribute('href', 'data:application/x-research-info-systems;charset=utf-8,' + encodeURIComponent(text));
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
},
}
}
</script>
<style scoped>
.share_text {
padding-right: 10px;
vertical-align: middle;
}
.v-icon {
color: var(--v-primary-base) !important;
}
.share_button {
padding-right: 4px;
font-weight: bold;
font-size: 14px;
.toolbar-button {
margin-right: 8px;
margin-top: 8px;
font-size: 12px;
}
......@@ -88,11 +178,11 @@ export default {
padding-top: 24px;
}
.footer_title {
font-family: Inria Serif;
font-weight: bold;
font-size: 18px;
float: right;
#citation {
margin-top: 12px;
padding: 12px;
background-color: var(--v-button-base) !important;
margin-bottom: 6px;
}
</style>
<template>
<div class="autocomplete-container" :class="$vuetify.breakpoint.name">
<v-combobox accesskey="s" aria-label="søkefelt"
v-model="select"
:loading="loading"
:items="items"
:search-input.sync="search"
item-text="label"
:menu-props="{maxHeight: $vuetify.breakpoint.name === 'xs' ? 190 : 500, transition: 'fade-transition', allowOverflow: true}"
prepend-inner-icon="search"
:append-icon="null"
return-object
rounded
hide-no-data
auto-select-first
no-filter
hide-details
label="Søk..."
solo
full-width
flat
outlined
placeholder="Søk her"
ref="autocomplete"
color="primary"
:dense="$vuetify.breakpoint.smAndDown"
>
<template v-slot:item="data">
<span class="search-hit">
{{data.item.label}}
</span>
({{{"b": "bm", "n": "nn", "bn": "bm, nn" }[data.item.lang] || ["søker...","ingen treff","avansert søk"][data.item.search]}})
</template>
<template slot="no-data">
<div></div>
</template>
</v-combobox>
</div>
</template>
<script>
export default {
props: {
api: Function,
},
data: function() {
return {
loading: false,
items: [],
search: null,
select: null,
suggesting: null,
}
},
watch: {
search (val) {
const time = Date.now()
if (! val) {
this.items = []
} else {
this.run_query(val, time)
}
},
select(item) {
if (item) {
this.items = []
if (typeof item != 'string') {
this.suggesting = false
this.submit(item)
}
}
}
},
methods: {
run_query(q, time) {
this.suggesting = true
// Search options while waiting for response
var search = 0
if (this.items[0]) {
if (this.items[0].time < time) {
if (/_|\*|\|/.test(q)) {
search = 2
}
// Whitespace necessary in case option already exists in dropdown
this.items.splice(0,1, {q: q, label: q +" ", time: time, search: search})
}
}
else {
this.items.push({q: q, label: q, time: time, search: search})
}
let self = this
self.api.get('suggest?', {params: {q: q, dict: self.$parent.lang, n: 80, scope: 'w', stage: self.$parent.stage}})
.then(async (response) => {
if (self.$refs.autocomplete.searchInput == q & self.suggesting) {
let suggestions = response.data.a.w.map(item => ({q: q, match: item[0], label: item[0], time: time, lang: item[1]}))
if (/_|\*|\|/.test(q)) {
suggestions.unshift({q: q, label: q, time: time, search: 2})
}
if (!suggestions.length) {
self.items = [{q: q, label: q, time: time, search: 1}]
} else {
self.items = suggestions
}
}
self.loading = false
})
},
submit(item) {
this.$emit('submit', item)
let self = this
setTimeout(() => {
self.$refs.autocomplete.$refs.input.select()
this.items = []
this.suggesting = false
}, 1)
}
},
}
</script>
<style scoped>
.search-hit {
font-weight: bold;
margin-right: 5px;
color: var(--v-primary-base);
}
.autocomplete-container {
padding-left: 10px;
padding-right: 10px;
}
</style>
......@@ -5,10 +5,10 @@
<li
:key="index"
v-for="(item, index) in body.elements"
><router-link
>{{' '}}<router-link
:to="'/' + dictionary + '/' + item.article_id + (item.definition_id ? '#def'+item.definition_id : '')"
@click.native="article_link_click(item)"
> {{item.lemmas[0].lemma}}</router-link>
>{{item.lemmas[0].lemma}}</router-link>
</li>
</ul>
</li>
......
<template>
<v-list>
<v-list-item>
<div>
<h2>{{$t('contact.content[0]')}}</h2><p>
{{$t('contact.content[2]')}} <a href="mailto:ordbok@uib.no">ordbok@uib.no</a></p>
<h2>{{$t('contact.content[1]')}}</h2><p>
{{$t('contact.content[3]')}} <span style="white-space: nowrap;"><a href="mailto:ordbok-teknisk@uib.no">ordbok-teknisk@uib.no</a></span></p>
</div>
</v-list-item>
<v-list-item>
<v-list-item-title>
<h2>{{$t('contact.faq.title')}}</h2>
</v-list-item-title>
</v-list-item>
<v-list-group dense prepend-icon="help">
<template v-slot:activator>
<v-list-item-content>{{$t('contact.faq.items[0].title')}}</v-list-item-content>
</template>
<v-list-item><p><em>{{$t('dicts.bm')}}</em>{{$t('and')}}<em>{{$t('dicts.nn')}}</em>{{$t('contact.faq.items[0].text[0]')}}<router-link to="/om" @click.native="$emit('close')">{{$t('contact.faq.items[0].text[1]')}}</router-link></p></v-list-item>
</v-list-group>
<v-list-group prepend-icon="help">
<template v-slot:activator>
<v-list-item-content>{{$t('contact.faq.items[1].title')}}</v-list-item-content>
</template>
<v-list-item>{{$t('contact.faq.items[1].text')}}</v-list-item>
</v-list-group>
<v-list-group prepend-icon="help">
<template v-slot:activator>
<v-list-item-content>{{$t('contact.faq.items[2].title')}}</v-list-item-content>
</template>
<v-list-item>{{$t('contact.faq.items[2].text')}}</v-list-item>
</v-list-group>
</v-list>
</template>
<script>
export default {
name: "Contact",
}
</script>
......@@ -2,12 +2,19 @@
<li :is="tag" :class="body.type_"><!--
--><span :is="item.tag || 'span'" v-for="(item, index) in assemble_text"
:class="item.type"
@error="article_error"
:key="index"
v-bind="item.props"><!--
-->{{item.html}}<!--
--><router-link v-if="item.type == 'article_ref'" :to="item.ref" @click.native="article_link_click(item)"><!--
-->{{item.link_text}}{{item.definition_order ? ` (${item.definition_order})` : ''}}<!--
--></router-link><!--
--><router-link class="article_ref" v-if="item.type == 'article_ref'" :to="item.ref" @click.native="article_link_click(item)" :key="index"><!--
--><DefElement tag='span' v-if="item.link_text.type_" :dictionary="dictionary" :key="item.id+'_sub'" :body='item.link_text'/><span v-else>{{item.link_text}}</span><!--
--><span class="homograph" v-if="item.lemmas[0].hgno" :aria-label="`${dictionary=='bm'? 'Betydning': 'Tyding'} ${item.lemmas[0].hgno}`" :title="`${dictionary=='bm'? 'Betydning': 'Tyding'} ${item.lemmas[0].hgno}`" :key="index"><!--
--> ({{roman_hgno(item.lemmas[0])}}{{item.definition_order ? '': ')'}}</span>
<span class="def_order" v-if="item.definition_order" :aria-label="'definisjon '+item.definition_order">{{item.lemmas[0].hgno ? ', ': ' ('}}{{item.definition_order}})</span>
</router-link>
<!--
--><span class="numerator" v-if="item.type == 'fraction'">{{item.num}}</span><!--
-->{{item.type == 'fraction' ? '' : ''}}<!--
--><span class="denominator" v-if="item.type == 'fraction'">{{item.denom}}</span><!--
......@@ -43,34 +50,58 @@ export default {
}
},
computed: {
fulltext_highlight: function() {
return this.$store.state.fulltextHighlight
},
unparsed: function(){
let lang = this.dictionary
let path = this.path
return this.body.items.map(
function(item){
if (item.type_ == 'usage') return {type: item.type_, html: item.text, tag: 'mark'}
else if (item.type_ == 'article_ref') return {
type: item.type_,
html: '',
link_text: item.word_form || item.lemmas[0].lemma,
ref: '/' + lang + '/' + item.article_id + '/' + encodeURIComponent(item.word_form || item.lemmas[0].lemma) + (item.definition_id ? '#def' + item.definition_id : ''),
article_id: item.article_id,
definition_id: item.definition_id,
source: path
}
else if (item.type_ == 'pronunciation') return {type: item.type_, html: item.string}
else if (item.type_ == 'pronunciation_guide') return {type: item.type_, body: item, html: '', tag: 'DefElement', props: {body: item, tag: 'i', dictionary: lang}}
else if (item.type_ == 'superscript') return {type: item.type_, html: item.text, tag: 'sup'}
else if (item.type_ == 'subscript') return {type: item.type_, html: item.text, 'tag': 'sub'}
else if (item.type_ == 'quote_inset') return {type: item.type_, body: item, html: '', tag: 'DefElement', props: {body: item, tag: 'i', dictionary: lang}}
else if (item.type_ == 'fraction') return helpers.fraction(item.numerator, item.denominator)
else if (item.id) return {type: item.type_, html: (entities[lang][item.id] || {})['expansion'] || item.id}
else return {type: item.type_ || 'plain', html: item}
try {
let lang = this.dictionary
let path = this.path
return this.body.items.map(
function(item){
if (item.type_ == 'usage') {
if (item.items) {
item.content = item.text
return {type: item.type_, html: '', tag: 'DefElement', props: {body: item, tag: 'i', dictionary: lang}}
}
else {
return {type: item.type_, html: item.text, tag: 'i'}
}
}
else if (item.type_ == 'article_ref') {
return {
type: item.type_,
html: '',
lemmas: item.lemmas,
link_text: item.word_form || item.lemmas[0].annotated_lemma || item.lemmas[0].lemma,
ref: '/' + lang + '/' + item.article_id + (item.definition_id ? '#def' + item.definition_id : ''),
article_id: item.article_id,
definition_id: item.definition_id,
definition_order: item.definition_order,
source: path
}
}
else if (item.type_ == 'pronunciation') return {type: item.type_, html: item.string}
else if (item.type_ == 'pronunciation_guide') return {type: item.type_, body: item, html: '', tag: 'DefElement', props: {body: item, tag: 'i', dictionary: lang}}
else if (item.type_ == 'superscript') return {type: item.type_, html: item.text, tag: 'sup'}
else if (item.type_ == 'subscript') return {type: item.type_, html: item.text, tag: 'sub'}
else if (item.type_ == 'quote_inset') return {type: item.type_, body: item, html: '', tag: 'DefElement', props: {body: item, tag: 'i', dictionary: lang}}
else if (item.type_ == 'fraction') return helpers.fraction(item.numerator, item.denominator)
else if (item.id) return {type: item.type_, html: (entities[lang][item.id] || {})['expansion'] || item.id}
else return {type: item.type_ || 'plain', html: item}
}
)
}
catch(error) {
this.$emit('error', {location: "unparsed", message: error.message} )
return {type: 'plain', html: item}
}
},
assemble_text: function(){
var old_parts = this.body.content.split(/(\$)/)
try {
var old_parts = this.body.content.split(/(\$)/)
var text_items = this.unparsed.slice(0).reverse()
var new_parts = []
old_parts.forEach(function(item){
......@@ -81,12 +112,23 @@ export default {
}
})
return new_parts
}
catch(error) {
this.$emit('error', {location: "assemble_text", message: error.message} )
return []
}
}
},
methods: {
article_link_click: function(item) {
this.$emit('article-click', item)
}
},
article_error: function(payload) {
this.$emit('error', payload)
},
roman_hgno: helpers.roman_hgno
}
}
</script>
......@@ -123,8 +165,16 @@ i {
font-style: normal;
}
.homograph {
vertical-align: sub;
.link_text {
text-decoration: underline;
}
.homograph, .def_order{
text-decoration: none !important;
color: black
}
q:before {
......
<template>
<li :class="['definition', 'level'+level]" :ref="'def' + body.id" :id="'def' + body.id">
<ul class="explanations" tabindex="0">
<li :class="['definition', 'level'+level]" :ref="level != 9 ? 'def' + body.id : ''" :id="level != 9? 'def' + body.id : ''">
<span v-if="level!=9"/>
<ul class="explanations">
<DefElement :body="explanation" :dictionary="dictionary" :has_article_ref=has_article_ref(explanation) v-for="(explanation, index) in explanations" :key="index" @article-click="article_link_click" />
</ul>
<div v-if="examples.length" tabindex="0">
<h4>{{example_header}}</h4>
<div v-if="examples.length">
<h5 :lang="lang_tag_locale" v-if="level < 3">{{$t('article.headings.examples', content_locale)}}</h5>
<ul class="examples">
<Example :body="example" :dictionary="dictionary" v-for="(example, index) in examples" :key="index" @article-click="article_link_click" />
</ul>
......@@ -12,8 +13,8 @@
<ul class="compound_lists">
<CompoundList :body="compound_list" :dictionary="dictionary" v-for="(compound_list, index) in compund_lists" :key="index" @article-click="article_link_click" />
</ul>
<div :is="level < 3 ? 'ol' : 'ul'" class="sub_definitions" v-if="subdefs.length" tabindex="0">
<Definition :level="level+1" :body="subdef" v-for="(subdef, index) in subdefs" :dictionary="dictionary" :key="index" @article-click="article_link_click" />
<div :is="level < 3 ? 'ol' : 'ul'" class="sub_definitions" v-if="subdefs.length">
<Definition :def_number='index+1' :level="level+1" :body="subdef" v-for="(subdef, index) in subdefs" :dictionary="dictionary" :key="index" @article-click="article_link_click" />
</div>
</li>
</template>
......@@ -28,7 +29,9 @@ var Definition = {
props: {
body: Object,
level: Number,
dictionary: String
dictionary: String,
def_number: Number
},
components: {
DefElement,
......@@ -38,26 +41,54 @@ var Definition = {
},
computed: {
explanations: function() {
try {
return this.body.elements.filter(el => el.type_ == 'explanation')
} catch (error) {
this.$emit('error', {location: "explanations", message: error.message})
return []
}
},
examples: function() {
try {
return this.body.elements.filter(el => el.type_ == 'example')
} catch (error) {
this.$emit('error', {location: "examples", message: error.message})
return []
}
},
compund_lists: function() {
try {
return this.body.elements.filter(el => el.type_ == 'compound_list')
},
example_header: function() {
return this.dictionary == 'bob' ? 'Eksempel' : 'Døme'
} catch (error) {
this.$emit('error', {location: "compound_lists", message: error.message})
return []
}
},
subdefs: function() {
try {
return this.body.elements.filter(el => el.type_ == 'definition').filter(def => def.elements.filter(el => el.type_ != 'sub_article').length > 0)
} catch (error) {
this.$emit('error', {location: "subdefs", message: error.message})
return []
}
// filtrerer bort definisjoner som bare inneholder underartikler
return this.body.elements.filter(el => el.type_ == 'definition').filter(def => def.elements.filter(el => el.type_ != 'sub_article').length > 0)
},
content_locale: function() {
return this.$parent.content_locale
},
lang_tag_locale: function() {
return this.$parent.lang_tag_locale
}
},
},
mounted: function() {
let ref = 'def' + this.body.id
if(location.hash.substring(1) == ref){
this.$refs[ref].scrollIntoView()
this.$refs[ref].scrollIntoView({block: 'center'})
this.$refs[ref].classList.add('highlighted')
}
},
......@@ -78,10 +109,12 @@ var Definition = {
watch:{
$route(to, from) {
let ref = 'def' + this.body.id
if(location.hash.substring(1) == ref){
this.$refs[ref].classList.add('highlighted')
}else{
this.$refs[ref].classList.remove('highlighted')
if (this.$refs[ref]) {
if(location.hash.substring(1) == ref){
this.$refs[ref].classList.add('highlighted')
}else {
this.$refs[ref].classList.remove('highlighted')
}
}
}
}
......@@ -94,18 +127,15 @@ q {
font-style: italic;
}
.highlighted {
.highlighted, mark {
background-color: var(--v-tertiary-darken1);
border-radius: 5px;
}
h4 {
color: var(--v-primary-base);
font-size: 14px;
padding-left: 12px;
padding-top: 6px;
mark {
font-weight: bold;
}
li[has_article_ref="true"] {
margin-top: 8px;
margin-left: -25px;
......
This diff is collapsed.
<template>
<span>
<v-btn v-if="$route.name!='about'" to="/om" small dark text>
<v-icon small left>info</v-icon>{{$t('menu.about')}}
</v-btn>
<v-btn v-if="$route.name=='about'" to="/" small dark text>
<v-icon small left>home</v-icon>{{$t('home')}}
</v-btn>
<v-dialog :fullscreen="$vuetify.breakpoint.smAndDown" max-width="800px" v-model="help_dialog">
<template v-slot:activator="{ on, attrs }">
<v-btn small dark text v-on="on" v-bind="attrs">
<v-icon small left>help</v-icon>{{$t('menu.help')}}
</v-btn>
</template>
<v-card>
<v-toolbar elevation="0" dark color="primary">
<v-toolbar-title>{{$t('menu.help')}}</v-toolbar-title><v-spacer></v-spacer>
<v-toolbar-items><v-btn @click.native="help_dialog=false" text>{{$t('close')}}<v-icon right>close</v-icon></v-btn></v-toolbar-items>
</v-toolbar>
<v-card-text class="text--primary">
<br>
<Help/>
</v-card-text>
</v-card>
</v-dialog>
<v-dialog :fullscreen="$vuetify.breakpoint.smAndDown" max-width="800px" v-model="settings_dialog">
<template v-slot:activator="{ on, attrs }">
<v-btn small dark text v-on="on" v-bind="attrs">
<v-icon small left>settings</v-icon><span>{{$t('settings.title')}}</span>
</v-btn>
</template>
<v-card>
<v-toolbar elevation="0" dark color="primary">
<v-toolbar-title><span role="heading" aria-level="1">{{$t('settings.title')}}</span></v-toolbar-title><v-spacer></v-spacer>
<v-toolbar-items><v-btn @click.native="settings_dialog=false" text>{{$t('close')}}<v-icon right>close</v-icon></v-btn></v-toolbar-items>
</v-toolbar>
<Settings/>
</v-card>
</v-dialog>
<v-dialog :fullscreen="$vuetify.breakpoint.smAndDown" max-width="800px" v-model="contact_dialog">
<template v-slot:activator="{ on, attrs }">
<v-btn small dark text v-on="on" v-bind="attrs">
<v-icon small left>mail</v-icon><span>{{$t('contact.title')}}</span>
</v-btn>
</template>
<v-card>
<v-toolbar elevation="0" dark color="primary">
<v-toolbar-title><span role="heading" aria-level="1">{{$t('contact.title')}}</span></v-toolbar-title><v-spacer></v-spacer>
<v-toolbar-items><v-btn @click.native="contact_dialog=false" text>{{$t('close')}}<v-icon right>close</v-icon></v-btn></v-toolbar-items>
</v-toolbar>
<Contact @close="contact_dialog = false"/>
</v-card>
</v-dialog>
</span>
</div>
</template>
<script>
import Help from './Help.vue'
import Contact from './Contact.vue'
import Settings from './Settings.vue'
export default {
name: "FooterMenu",
components: {
Help,
Contact,
Settings
},
data: function() {
return {
contact_dialog: false,
help_dialog: false,
settings_dialog: false
}
}
}
</script>
\ No newline at end of file
This diff is collapsed.
<template>
<span>
<span v-bind:class="{ 'lookup': $route.name=='lookup'}" v-for="(lemma_group, i) in lemma_groups" :key="i">
<h3>
<!--
--><span v-for="(lemma, index) in lemma_group.lemmas"
:key="index"><DefElement v-if="lemma.annotated_lemma" :body="lemma.annotated_lemma" tag="span"/><span v-else>{{lemma.lemma}}</span><!--
--><span v-if="lemma.hgno"
:aria-label="$t('accessibility.homograph') + parseInt(lemma.hgno)"
:title="$t('accessibility.homograph')+parseInt(lemma.hgno)"
class="hgno">{{" "+roman_hgno(lemma)}}</span><!--
--><span
class="title_comma"
v-if="lemma_group.lemmas[1] && index < lemma_group.lemmas.length-1">{{", "}}
</span>
</span>
</h3>
<h3 v-if="secondary_header_text">{{secondary_header_text}}</h3>
<span :lang="$parent.$parent.lang_tag_locale" v-if="lemma_group.description" class="subheader">
<span class="header_group_list">{{lemma_group.description}}</span>
{{lemma_group.pos_group}}
<span v-if="$store.state.showInflectionNo" class="inflection_classes">{{lemma_group.inflection_classes}}</span>
</span>
</span>
</span>
</template>
<script>
import helpers from '../utils/helpers.js'
import DefElement from './DefElement.vue'
export default {
name: 'HeaderTitle',
components: {
DefElement
},
props: {
lemma_groups: Array,
secondary_header_text: String
},
methods: {
roman_hgno: helpers.roman_hgno,
}
}
</script>