Something went wrong on our end
-
Henrik Askjer authoredHenrik Askjer authored
Article.vue 10.20 KiB
<template>
<article v-bind:class="{'v-sheet v-card rounded-xl': !articleLookup, dictionary, 'collapsable': collapsable, 'collapsed': collapsed}" v-if="article">
<Header :title_id="title_id" :lemmas="article.lemmas" :dictionary="dictionary" :article_id="article.article_id" @toggle-collapse = "toggle_collapse"/>
<InflectionButton :lemmas="article.lemmas" :dictionary="dictionary" :article_id="article.article_id"/>
<div class="article_content" :class="$vuetify.breakpoint.name" v-if="!collapsed">
<section v-if="article.body.pronunciation && article.body.pronunciation.length" class="pronunciation">
<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.body.etymology && article.body.etymology.length" class="etymology">
<h3>Opphav</h3>
<ul>
<DefElement v-for="(element, index) in article.body.etymology" :dictionary="dictionary" :key="index" :body='element' @article-click="article_link_click" />
</ul>
</section>
<section class="definitions" v-if="has_content">
<h3>{{def_label}}</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="sub_articles.length" class="expressions">
<h3>Faste uttrykk</h3>
<ul>
<SubArticle :body="subart" v-for="(subart, index) in sub_articles" :dictionary="dictionary" :key="index" @article-click="article_link_click" />
</ul>
</section>
</div>
<ArticleFooter v-if="!collapsed" :article="article"/>
</article>
</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 InflectionButton from './InflectionButton.vue'
import entities from '../utils/entities.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)
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)
return content_list
}
export default {
name: 'Article',
props: {
article: Object,
articleLookup: Boolean,
title_id: String
},
data: function() {
return {
is_collapsed: true
}
},
computed: {
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
}
if (collapsable == 'always') {
this.is_collapsed = 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.$store.state.collapseArticles == 'always' || this.$parent.$options.name == 'SearchResults' && (this.$parent.results_bm.length + this.$parent.results_nn.length > 2)//getters.collapsable(this.$parent.$options.name, this.$parent.results_bm.length + this.$parent.results_nn.length)
},
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.parse_definitions(this.article.body.definitions)
}
return null
},
link_to_self: function() {
try {
return {
ref: '/' + this.dictionary + '/' + this.article.article_id + '/' + encodeURIComponent(this.article.lemmas[0].lemma),
article: this.article
}
} catch(error) {
console.log("LINK TO SELF ERROR:",this.article)
console.error(error)
return {ref: "", article: this.article}
}
},
dictionary: function() {
return this.article.dictionary
},
def_label: function() {
return this.dictionary == 'bm' ? 'Betydning og bruk' : 'Tyding og bruk'
},
example_label: function() {
return this.dictionary == 'bm' ? 'Eksempel' : 'Døme'
},
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
},
},
components: {
DefElement,
Definition,
SubArticle,
Header,
ArticleFooter,
InflectionButton
},
mounted: function() {
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"})
}
else if (this.$parent.article) {
document.getElementById("return_link").focus()
}
},
methods: {
parse_definitions: function(node) {
let definitionTexts = []
try {
node.forEach((definition) => {
if (definition.elements) {
if (definition.elements[0].content) {
let new_string = ""
let old_parts = definition.elements[0].content.split(/(\$)/)
let linkIndex = 0
old_parts.forEach((item) => {
if (item == '$') {
let subitem = definition.elements[0].items[linkIndex]
if (subitem.id) {
new_string += entities[this.dictionary][definition.elements[0].items[linkIndex].id].expansion
}
else if (subitem.text) new_string += subitem.text
else {
if (definition.elements[0].items[linkIndex].lemmas) {
new_string += definition.elements[0].items[linkIndex].lemmas[0].lemma
}
}
if (!definition.elements[0].items[linkIndex].id) {
}
linkIndex += 1
}
else {
new_string += item
}
})
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(this.parse_definitions(definition.elements))
}
}
})
} catch(error) {
console.log(this.article)
console.error(error)
definitionTexts = []
}
let definitions = definitionTexts.join("\u00A0•\u00A0")
return definitions
},
toggle_collapse: function() {
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>
<style>
article {
position: relative;
padding: 24px;
margin-bottom: 20px;
margin-right: 10px;
margin-left: 10px;
background-color: #ffffff;
}
section.xs article, section.sm article {
margin-bottom: 10px !important;
}
.welcome .article_footer {
display: block;
}
#single_article_container article {
border: none;
margin-top: 10px;
}
section {
padding-top: 10px;
padding-bottom: 10px
}
h3 {
color: var(--v-primary-base);
font-variant: all-small-caps;
}
section.etymology > h3, section.pronunciation > h3 {
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 {
padding-bottom: 4px;
}
li.level1.definition {
list-style: upper-alpha;
}
li.level2.definition {
list-style: decimal;
}
li.level3.definition {
/* Norsk ordbok skal ha "lower.alpha" her */
list-style: disc;
}
li.sub_article > ul {
padding-left: 0px;
}
::marker {
font-weight: bold;
color: var(--v-primary-base);
}
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;
}
li:only-child.level1 > ol {
padding-left: 0px;
}
ul, ol {
padding-left: 12px !important;
}
ul li {
list-style:none;
}
ul li.definition {
list-style: disc;
}
.choose {
color: var(--v-primary-base) !important;
text-decoration: none;
}
.info-card {
padding: 12px;
}
.collapsable {
padding-bottom: 34px;
}
.collapsed .header{
display: -webkit-box;
width: 100%;
-webkit-line-clamp: 4;
-webkit-box-orient: vertical;
overflow-y: hidden;
overflow-x: auto;
}
.header {
border-radius: 0px !important;
}
</style>