<template> <main id="app"> <header> <span class="top">EID AV UNIVERSITETET I BERGEN OG SPRÅKRÅDET</span> <p class="mission-statement">Bokmålsordboka og Nynorskordboka er dei einaste fritt tilgjengelege ordbøkene som gjer svar på korleis ord skal skrivast og bøyast i norsk i tråd med gjeldande rettskriving.</p> <autocomplete :debounceTime="100" :auto-select="true" :search="search" @submit="select_result" placeholder="søk..." ref="search"> <template #result="{result, props}"> <Preview v-bind="props" :searchHit="result"> </Preview> </template> </autocomplete> <span class="lang-select-intro">SØK PÅ</span> <input type="radio" id="radio_both" value="bob,nob" v-model="lang"> <label for="radio_both">Begge</label> <input type="radio" id="radio_bob" value="bob" v-model="lang"> <label for="radio_bob">Bokmål</label> <input type="radio" id="radio_nob" value="nob" v-model="lang"> <label for="radio_nob">Nynorsk</label> - <input type="radio" id="radio_norsk" value="norsk_ordbok" v-model="lang"> <label for="radio_norsk">Norsk Ordbok</label> </header> <img id="spinner" :class="waiting ? 'show' : 'hide'" src="./assets/spinner.gif" alt="Venter på innhold" /> <SearchResults :hits="search_results" :lang="lang" @search-hit-click="search_hit_click" /> <Article :key="article_key" :article="article" @article-click="article_link_click" /> <div class="welcome" v-show="! (article.lemmas.length || search_results.length)"> <p>Bør ordet <em>crew</em> inn i dei norske standardordbøkene? Korleis definerar vi <em>c-kjendis</em>, og korleis bøyar vi eigentleg <em>abaya</em> på nynorsk - er det fleire <em>abayaer</em> eller <em>abayaar</em>? Blir <em>en vegetar</em> framleis brukt som ein rettskrivingsvariant av <em>en vegetarianer</em> i bokmål? Og bør <em>tjuesesse</em> bli eit opplsagsord i Bokmålsordboka når ein tilsvarande ordartikklel allereie finst i Nynorskordboka? </p> <p>Slike spørsmål skal ei gruppe ordbokredaktørar ved UiB arbeide med i den mest omfattande innhaldsrevisjonen av Bokmålsordboka og Nynorskordboka på over 30 år.</p> </div> <footer> <div> <img id="uiblogo" src="./assets/uib-logo.svg" alt=""> <p>Ordbøkene eies av Universitetet i Bergen sammen med Språkrådet, under ledelse frå Språksamlingane</p> <p><strong>REDAKTØRANSVAR: HF-FAKULTETET VED UiB</strong></p> </div> <div> <img id="srlogo" src="./assets/Sprakradet_logo_neg.png" alt=""> <p> Språkrådet er statens fagorgan i språkspørsmål og følger opp den norske språkpolitikken på oppdrag fra Kulturdepartementet. Språkrådet forvalter rettskrivningen i nynorsk og bokmål.</p> </div> </footer> </main> </template> <script> import axios from "axios" import Article from './components/Article.vue' import Preview from './components/Preview.vue' import SearchResults from './components/SearchResults.vue' import Autocomplete from '@trevoreyre/autocomplete-vue' import '@trevoreyre/autocomplete-vue/dist/style.css' var api_endpoint = 'https://ordbok-dev.aws.uib.no/cache/article' window.onpopstate = function (event) { if (event.state) { app.__vue__._data.article = event.state.article app.__vue__._data.search_results = event.state.search_results app.__vue__._data.lang = event.state.lang } } export default { name: 'app', data: function() { return { article_key: 0, search_results: [], lang: 'bob,nob', waiting: true, article: {lemmas: [], body:{pronunciation: [], definitions: [], etymology: []}} } }, computed: { search: function() { let self = this return function(q) { return new Promise(resolve => { return axios.post(api_endpoint + '/' + self.lang + '/_search/', { "suggest": { "suggest" : { "prefix" : q, "completion" : { "field" : "suggest", "size": 10 } } } }).then(function(response) { let hits = q.length ? [{q: q}] : [] hits = hits.concat(response.data.suggest.suggest[0].options.sort((o1, o2) => o1.text.length - o2.text.length)) resolve(hits) }) }) } } }, components: { Article, Autocomplete, SearchResults, Preview }, methods: { select_result: function(event) { this.$refs.search.value = '' document.activeElement.blur() if(event._source){ this.$router.push('/' + event._index + '/' + event._id) this.search_results = [] this.article = event._source history.replaceState({article: this.article, search_results: this.search_results, lang: this.lang}, '') }else{ var self = this self.waiting = true self.article = {lemmas: [], body:{pronunciation: [], definitions: [], etymology: []}} axios.get(api_endpoint + '/' + self.lang + '/_search?q=' + event.q + ' ' + event.q + '*&size=20') .then(function(response){ self.$router.push('/' + `/search?q=${event.q}&lang=${self.lang}`) self.search_results = response.data.hits.hits self.waiting = false history.replaceState({article: self.article, search_results: self.search_results, lang: self.lang}, '') }) } }, article_link_click: function(item) { var self = this 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{ self.article = {lemmas: [], body:{pronunciation: [], definitions: [], etymology: []}} self.waiting = true axios.get(api_endpoint + '/' + self.lang + '/' + item.article_id) .then(function(response){ self.article = response.data._source self.waiting = false history.replaceState({article: self.article, search_results: self.search_results, lang: self.lang}, '') }) } }, search_hit_click: function(article){ this.search_results = [] this.article = article history.replaceState({article: article, search_results: [], lang: this.lang}, '') } }, mounted: function(){ this.lang = this.$route.params.lang || this.$route.query.lang || 'bob,nob' var self = this; if(this.$route.query.q) { axios.get(api_endpoint + '/' + self.lang + '/_search?q=' + self.$route.query.q + ' ' + self.$route.query.q + '*&size=20') .then(function(response){ self.search_results = response.data.hits.hits self.waiting = false history.replaceState({article: self.article, search_results: self.search_results, lang: self.lang}, '') }) } else if(this.$route.params.id){ axios.get(api_endpoint + '/' + self.lang + '/' + self.$route.params.id) .then(function(response){ self.article = response.data._source self.waiting = false history.replaceState({article: self.article, search_results: self.search_results, lang: self.lang}, '') }) } else { this.waiting = false } }, watch: { $route(to, from) { this.lang = this.$route.params.lang || this.$route.query.lang || 'bob,nob' } } } </script> <style> @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'); #app { font-family: 'Noto Sans', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; color: #2c3e50; } body { margin: 0px; } main { padding-top: 60px; padding-left: calc((100vw - 1000px) / 2); padding-right: calc((100vw - 1000px) / 2); background-color: #FDF4F5; background-image: url('./assets/beta.png'); background-repeat: no-repeat; background-attachment: fixed; } .top { color: #560027; font-weight: bold; font-size: smaller; border-bottom: solid; border-color: #BC477B; } .mission-statement { font-size: 24px; } .show { display: block; } .hide { display: none; } .autocomplete { width: 25em; border-bottom: solid #BC477B; border-radius: 0px; margin-bottom: 8px; } .autocomplete-result-list { max-height: 500px; } input[type=radio] { display: none; } input[type=radio]:checked + label { border: solid 1px #560027; box-shadow: inset 0 0 2px #000000; } label { margin: 4px 4px 4px 8px; border-radius: 4px; padding: 2px 8px 2px 8px; background-color: #DDDDDD } .lang-select-intro { font-size: smaller; font-weight: bold; } footer { font-size: smaller; display: flex; flex-direction: row; background-color: #570B27; color: #ffffff; padding-bottom: 20px; } footer p { padding-left: 20px; padding-right: 20px; margin: 0px; } #srlogo { height: 20px; padding-top: 50px; padding-left: 20px; } #uiblogo { height: 60px; padding: 10px; padding-left: 20px; } </style>