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 5536 additions and 313 deletions
This diff is collapsed.
<template>
<article v-show="article.lemmas.length || article.error">
<Header :lemmas="article.lemmas" :dictionary="dictionary" />
<section v-if="! article.error && article.body.pronunciation && article.body.pronunciation.length">
<h3>Uttale</h3>
<ul>
<DefElement v-for="(element, index) in article.body.pronunciation" :dictionary="dictionary" :key="index" :body='element' @article-click="article_link_click" />
</ul>
</section>
<section v-if="! article.error && article.body.etymology && article.body.etymology.length">
<h3>Etymologi</h3>
<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">
<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" @error="article_error"/>
</ul>
</section>
<section v-if="article.body.etymology && article.body.etymology.length" class="etymology">
<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" @error="article_error"/>
</ul>
</section>
<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" @error="article_error"/>
</ol>
</section>
<section v-if="sub_articles.length" class="expressions">
<h4 :lang="lang_tag_locale">{{$t('article.headings.expressions', content_locale)}}</h4>
<ul>
<DefElement v-for="(element, index) in article.body.etymology" :dictionary="dictionary" :key="index" :body='element' @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>
<section v-if="! article.error">
<h3>Definisjoner</h3>
<ol>
<Definition v-for="definition in article.body.definitions" :dictionary="dictionary" :level="1" :key="definition.id" :body='definition' @article-click="article_link_click" />
</ol>
</section>
<section v-if="article.error">
<h1>Ooops...</h1>
<p>{{article.error}}</p>
</section>
</article>
</section>
</div>
<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>
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 = []
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
}
catch(error) {
console.log("find_sub_articles", this.article.article_id, this.dictionary, '"'+error.message+'"')
return []
}
}
export default {
name: 'Article',
props: {
article: Object
article: Object,
articleLookup: Boolean,
title_id: String,
queryPattern: String,
scope: String,
},
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 || this.$route.params.lang
return this.article.dictionary
},
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]
}
},
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() {
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: {
DefElement,
Definition,
Header
SubArticle,
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)
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style>
article {
margin-top: 30px;
.article {
position: relative;
padding: 24px;
padding-bottom: 12px;
margin-bottom: 20px;
margin-right: 10px;
margin-left: 10px;
background-color: #ffffff;
}
section.xs .article, section.sm .article {
margin-bottom: 10px !important;
}
h3 {
margin: 40px 0 0;
color: #560027;
section.md .article, section.lg .article, section.xl .article {
padding-top: 10px;
}
a {
color: #560027;
.welcome .article_footer {
display: block;
}
#single_article_container .article {
border: none;
margin-top: 10px;
}
section {
padding-top: 10px;
padding-bottom: 10px
}
section.etymology > h4, section.pronunciation > h4 {
display: inline;
}
section.etymology ul, section.pronunciation ul, section.etymology li, section.pronunciation li {
display: inline;
}
section.etymology li:not(:first-child):not(:last-child):before, section.pronunciation li:not(:first-child):not(:last-child):before {
content: ", ";
}
section.etymology li:not(:first-child):last-child:before, section.pronunciation li:not(:first-child):last-child:before {
content: "; ";
font-size: smaller;
}
li {
......@@ -82,23 +394,21 @@ li.level2.definition {
}
li.level3.definition {
list-style: lower-alpha;
/* Norsk ordbok skal ha "lower.alpha" her */
list-style: disc;
}
li.sub_article > ul {
padding-left: 0px;
}
li.definition.level1, li.definition.level2 {
padding-bottom: 2em;
}
::marker {
font-weight: bold;
color: #560027;
color: var(--v-primary-base);
}
ol > li:only-child.level1, li:only-child.level2, li:only-child.level3 {
ol > li:only-child.level1, li:only-child.level2 {
/* level3 a.k.a. underdefinisjoner skal vises med bullet selv om de står alene */
list-style: none;
}
......@@ -107,7 +417,7 @@ li:only-child.level1 > ol {
}
ul, ol {
padding-left: 20px;
padding-left: 12px !important;
}
ul li {
......@@ -118,4 +428,36 @@ ul li.definition {
list-style: disc;
}
.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;
}
</style>
<template>
<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>
<script>
export default {
name: 'ArticleFooter',
props: {
article: Object
},
computed: {
webShareApiSupported() {
return navigator.share
},
showLinkCopy() {
return (!navigator.share || this.$vuetify.breakpoint.mdAndUp) && navigator.clipboard
},
hasPointer() {
return window.matchMedia('(hover: hover) and (pointer: fine)').matches
},
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
})
},
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>
.v-icon {
color: var(--v-primary-base) !important;
}
.toolbar-button {
margin-right: 8px;
margin-top: 8px;
font-size: 12px;
}
.article_footer {
color: var(--v-primary-base);
padding-top: 24px;
}
#citation {
margin-top: 12px;
padding: 12px;
background-color: var(--v-button-base) !important;
margin-bottom: 6px;
}
</style>
......@@ -2,11 +2,13 @@
<li class="compound_list">
<ul>
<DefElement :body="body.intro" v-if="body.intro" :dictionary="dictionary" />
<li :key="index" v-for="(item, index) in body.elements">
<router-link :to="'/' + dictionary + '/' + item.article_id + (item.definition_id ? '#def'+item.definition_id : '')" @click.native="article_link_click(item)">
<span class="homograph" :key="index">{{item.lemmas[0].hgno ? String.fromCharCode(0x215f + item.lemmas[0].hgno) : ''}}</span>
{{item.lemmas[0].lemma}};
</router-link>
<li
:key="index"
v-for="(item, index) in body.elements"
>{{' '}}<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>
</li>
</ul>
</li>
......@@ -35,4 +37,12 @@ export default {
li.compound_list ul li {
display: inline;
}
li.compound_list li:not(:last-child):not(:first-child):after {
content: ",";
}
ul {
padding-left: 0px !important;
}
</style>
<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>
This diff is collapsed.
<template>
<li :class="['definition', 'level'+level]" :ref="'def' + body.id" :id="'def' + body.id">
<ul class="explanation">
<li :is="element_wrapper.template" :body="element_wrapper.element" :dictionary="element_wrapper.dictionary" v-for="(element_wrapper, index) in template_name_added" :key="index" @article-click="article_link_click">{{element_wrapper.element}}</li>
<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 :is="level < 3 ? 'ol' : 'ul'" class="sub_definitions" v-if="subdefs.length">
<Definition :level="level+1" :body="subdef" v-for="(subdef, index) in subdefs" :dictionary="dictionary" :key="index" @article-click="article_link_click" />
<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>
</div>
<ul class="sub_articles" v-if="subArticles.length">
<SubArticle :body="subart" v-for="(subart, index) in subArticles" :dictionary="dictionary" :key="index" @article-click="article_link_click" />
<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">
<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>
<script>
import DefElement from './DefElement.vue'
import Example from './Example.vue'
import SubArticle from './SubArticle.vue'
import CompoundList from './CompoundList.vue'
var Definition = {
......@@ -23,57 +29,92 @@ var Definition = {
props: {
body: Object,
level: Number,
dictionary: String
dictionary: String,
def_number: Number
},
components: {
DefElement,
Definition,
Example,
SubArticle,
CompoundList
},
computed: {
template_name_added: function(){
let dictionary = this.dictionary
return this.body.elements.filter(el => ! ['definition', 'sub_article'].includes(el.type_)).map(
function(element){
return {
'template': {
'explanation': 'DefElement',
'example': 'Example',
'compound_list': 'CompoundList'
}[element.type_] || 'li',
'element': element,
'dictionary': dictionary
}
})
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')
} catch (error) {
this.$emit('error', {location: "compound_lists", message: error.message})
return []
}
},
subdefs: function() {
return this.body.elements.filter(el => el.type_ == 'definition')
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
},
content_locale: function() {
return this.$parent.content_locale
},
subArticles: function() {
return this.body.elements.filter(el => el.type_ == 'sub_article')
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')
}
},
methods: {
article_link_click: function(item) {
this.$emit('article-click', item)
}
},
has_article_ref: function(item){
if(item.items.length && item.items[0].type_ == "article_ref" && item.items[0].definition_id === undefined)
{
return "true";
}
else{
return "false";
}
}
},
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')
}
}
}
}
......@@ -86,8 +127,18 @@ q {
font-style: italic;
}
.highlighted {
background-color: #FDF4F5;
border-radius: 5px;
.highlighted, mark {
background-color: var(--v-tertiary-darken1);
}
mark {
font-weight: bold;
}
li[has_article_ref="true"] {
margin-top: 8px;
margin-left: -25px;
}
</style>
This diff is collapsed.
<template>
<li class="example">
<DefElement tag="q" :body="body.quote" @article-click="article_link_click" :dictionary="dictionary" /><span v-if="body.explanation && body.explanation.content.length"> - </span>
<DefElement tag="q" :body="body.quote" @article-click="article_link_click" :dictionary="dictionary" /><span v-if="body.explanation && body.explanation.content.length"> </span>
<DefElement tag="span" :body="body.explanation" v-if="body.explanation && body.explanation.content.length" @article-click="article_link_click" :dictionary="dictionary" />
</li>
</template>
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.