Newer
Older
<template>
<h1><a href="/">Ordbøkene <span class="beta">(BETA)</span></a></h1>
<p class="sub-title"><a href="/">Bokmålsordboka | Nynorskordboka – rett norsk</a></p>
<main :class="(article.error || article.lemmas.length || search_results.length || waiting) ? '' : 'welcome '">
<div class="search_container">
<Autocomplete @submit="select_result" :endpoint="api_pref">
<div class="lang_select_container">
<select class="lang_select" name="lang" v-model="lang">
<option value="bob,nob">Begge ordbøker </option>
<option value="bob">Bokmål</option>
<option value="nob">Nynorsk</option>
</select>
</div>
<div id="spinner">
<v-progress-circular indeterminate color="rgb(188, 71, 123)" size="120" v-show="waiting"></v-progress-circular>
</div>
<SearchResults :hits="search_results" :lang="lang" @article-click="article_link_click" v-show="! waiting" />
<div id="single_article_container">
<Article :key="article_key" :article="article" @article-click="article_link_click" />
</div>
<div class="welcome" v-show="! (article.error || article.lemmas.length || search_results.length || waiting)">
<div class="monthly">
<h2>Månedens ord</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
<div id="word-of-month-bm">
<Article :article="monthly_bm" @article-click="article_link_click" />
</div>
<div id="word-of-month-nn">
<Article :article="monthly_nn" @article-click="article_link_click" />
</div>
</div>
<img id="srlogo" src="./assets/Sprakradet_logo_neg.png" alt="">
<img id="uiblogo" src="./assets/uib-logo.svg" alt="">
<div>Bokmålsordboka og Nynorskordboka viser skrivemåte og bøying i tråd med norsk rettskriving. Språkrådet og Universitetet i Bergen står bak ordbøkene.</div>
import entities from './utils/entities.js'
import SearchResults from './components/SearchResults.vue'
import Autocomplete from './components/Autocomplete.vue'
var api_endpoint = 'https://beta.ordbok.uib.no/api/dict'
axios.interceptors.request.use(function (config) {
config.headers["x-api-key"] = "ZkYiyRVXxH86ijsvhx3cH4SY5Iik2ijI3BKVJGMm"
return config;
}, function (error) {
return Promise.reject(error);
});
window.onpopstate = function (event) {
if (event.state) {
app.__vue__._data.search_results = event.state.search_results
function navigate_to_article(self, source) {
axios.get(api_endpoint + '/' + self.$route.params.lang + '/article/' + self.$route.params.id)
.then(function(response){
})
.catch(function(error){
if (error.response && error.response.status == 404) {
self.article = {
lemmas: [],
error: "Vi har ingen artikkel med id " + article_id
}
} else {
self.article = {
lemmas: [],
error: "Noe gikk galt..."
}
console.log(error)
}
})
.then(function(response){
self.waiting_for_articles = false
history.replaceState({article: self.article, search_results: [], lang: self.lang}, '')
if (source) {
self.$plausible.trackEvent('internal link incoming', {props: {origin: source}})
}
})
}
function navigate_to_search(self, query) {
axios.get(self.api_pref + 'search?q=' + query)
.then(function(response){
self.search_results = response.data
if (! self.search_results.length) {
self.article = {
lemmas: [],
error: "Vi fant ingen resultater for ''" + query + "'. (Søkeforlag kommer i en senere oppatering av Ordbøkene)"
}
}
self.waiting_for_articles = false
history.replaceState({article: self.article, search_results: self.search_results, lang: self.lang}, '')
})
}
function navigate_to_word(self, word) {
axios.get(self.api_pref + 'suggest?q=' + word)
.then(function(response){
self.search_results = response.data.filter(result => result.match.length == word.length)
self.waiting_for_articles = false
history.replaceState({article: self.article, search_results: self.search_results, lang: self.lang}, '')
})
}
article_key: 0,
waiting_for_articles: true,
waiting_for_metadata: true,
article: {lemmas: [], body:{pronunciation: [], definitions: [], etymology: []}},
monthly_bm: {lemmas: [], body:{pronunciation: [], definitions: [], etymology: []}},
monthly_nn: {lemmas: [], body:{pronunciation: [], definitions: [], etymology: []}}
waiting: function() {
return (this.waiting_for_articles || this.waiting_for_metadata) && this.$route.name != 'root'
},
api_pref: function() {
return api_endpoint + '/' + this.lang + '/article/'
},
methods: {
select_result: function(event) {
this.$router.push('/' + this.lang + '/w/' + event.word)
this.search_results = event.articles
this.article = {lemmas: [], body:{pronunciation: [], definitions: [], etymology: []}}
history.replaceState({article: this.article, search_results: this.search_results, lang: this.lang}, '')
this.$plausible.trackEvent('dropdown selection', {props: {query: event.label, match: event.match}})
this.waiting_for_articles = true
this.article = {lemmas: [], body:{pronunciation: [], definitions: [], etymology: []}}
navigate_to_search(this, event.q)
this.$plausible.trackEvent('dropdown selection', {props: {query: event.label, match: '<fritekstsøk>'}})
if (this.article.article_id == item.article_id){
this.article_key++
history.replaceState({article: this.article, search_results: this.search_results, lang: this.lang}, '')
}else{
this.article = {lemmas: [], body:{pronunciation: [], definitions: [], etymology: []}}
this.waiting_for_articles = true
navigate_to_article(this, item.source)
}
let self = this
Promise.all([
axios.get(api_endpoint + '/bob').then(function(response){
let concepts = response.data.concepts
entities.bob = concepts
}),
axios.get(api_endpoint + '/nob').then(function(response){
let concepts = response.data.concepts
entities.nob = concepts
})
]).then(function(_) {
self.waiting_for_metadata = false
if(self.$route.name == 'word') {
navigate_to_word(self, self.$route.params.word)
}
else if(self.$route.name == 'lookup'){
navigate_to_article(self, self.$route.params.id)
}
self.lang = self.$route.params.lang
navigate_to_search(self, self.$route.params.query)
self.waiting_for_articles = false
history.replaceState({article: self.article, search_results: self.search_results, lang: self.lang}, '')
}
// words of the month
axios.get(api_endpoint + '/bob/article/5607').then(function(response){
self.monthly_bm = Object.assign(response.data, {dictionary: 'bob'})
})
axios.get(api_endpoint + '/nob/article/78569').then(function(response){
self.monthly_nn = Object.assign(response.data, {dictionary: 'nob'})
})
},
watch: {
$route() {
this.$plausible.trackEvent('language', {props: {code: this.$route.params.lang}})
}
@import url('https://fonts.googleapis.com/css2?family=Inria+Serif:ital,wght@0,400;0,700;1,400;1,700&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Inria+Serif:ital,wght@0,400;0,700;1,400;1,700&family=Noto+Sans:ital,wght@0,400;0,700;1,400;1,700&display=swap');
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: #2c3e50;
display: flex;
flex-direction: column;
height: 100%;
}
html, body {
height: 100%
h1 {
font-family: Inria Serif;
font-size: 36px;
color: #560027;
}
header > h1 {
color: #BC477B;
font-size: 40px;
margin: 0px;
}
p.about-link {
text-align: right;
margin: 0px;
header a {
color: inherit;
text-decoration: none;
}
span.beta {
color: #BBBBBB;
}
p.about-link > a{
text-decoration: none;
border-bottom: solid #BC477B 4px;
font-size: 12px;
color: #FDF4F5;
}
padding-bottom: 20px;
flex: 1 0 auto;
background-color: #FDF4F5;
}
main.welcome {
background-image: url('./assets/books.jpg');
background-repeat: no-repeat;
background-attachment: fixed;
}
header, #search_results, #spinner, #single_article_container, footer, div.welcome, div.search_container {
padding-left: calc((100vw - 1000px) / 2);
padding-right: calc((100vw - 1000px) / 2);
header {
padding-bottom: 20px;
}
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
div.monthly {
padding: 20px;
border-radius: 10px;
display: grid;
grid-template-columns: 50% 50%;
grid-template-rows: auto auto auto;
gap: 10px;
width: 100%;
background-color: rgba(256,256,256,0.5)
}
div.monthly > h2{
padding: 0px;
grid-row: 1;
grid-column: 1 / 3;
}
div.monthly > p {
grid-row: 2;
grid-column: 1 / 3;
}
div#monthly_bm {
grid-row: 3;
grid-column: 1;
}
div#monthly_nn {
grid-row: 3;
grid-column: 2;
.top {
color: #560027;
font-weight: bold;
font-size: smaller;
border-bottom: solid;
border-color: #BC477B;
}
.mission-statement {
font-size: 16px;
margin: 0px;
color: #FDF4F5;
.sub-title {
font-size: 20px;
margin: 0px;
color: #FDF4F5;
}
.show {
display: block;
}
.hide {
display: none;
}
border-bottom: solid #BC477B;
border-radius: 0px;
.autocomplete-input {
border-radius: 0px;
background-color: #FFFFFF;
.autocomplete-result-list {
max-height: 500px;
}
.lang-select-intro {
font-size: smaller;
font-weight: bold;
}
flex-direction: row;
background-color: #570B27;
color: #ffffff;
}
.search_container {
display: flex;
flex-direction: row;
}
li.suggestion {
font-weight: bold;
padding-top: 5px;
padding-bottom: 5px;
border: 0px;
footer > div {
display: table-cell;
vertical-align: middle;
padding: 10px;
}
#srlogo {
height: 20px;
}
#uiblogo {
height: 60px;
}
select.lang_select {
appearance: none;
border: none;
padding: 0 1em 0 0;
width: 100%;
height: 100%;
font-family: inherit;
font-size: inherit;
font-weight: bold;
cursor: inherit;
line-height: inherit;
background-image: url('./assets/down_arrow.png');
background-position: 98% center;
background-repeat: no-repeat;
background-size: 10%;
::selection {
background: rgb(188, 71, 123);
color: white;
}