We are currently migrating all git repositories to new storage. In the unlikely event that you attempt to write to your git repo at the exact time it is being moved, you will receive a message about your repository being write protected.

Commit ed247c9f authored by Henrik.Askjer's avatar Henrik.Askjer
Browse files

Merge branch 'dev' into 'prod'

Dev

See merge request spraksamlingane/beta.ordbok.uib.no!97
parents ce831d1f ef8ec3f4
......@@ -8,20 +8,15 @@
"name": "ordbok_vue",
"version": "0.1.0",
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^1.2.35",
"@fortawesome/free-brands-svg-icons": "^5.15.3",
"@fortawesome/free-solid-svg-icons": "^5.15.3",
"@fortawesome/vue-fontawesome": "^2.0.2",
"axios": "^0.21.1",
"axios-cache-adapter": "^2.7.3",
"core-js": "~3.6.5",
"debounce": "^1.2.1",
"inflection-table": "https://git.app.uib.no/api/v4/projects/16442/jobs/artifacts/0.2.31/raw/module.tar.gz?job=publish",
"inflection-table": "https://git.app.uib.no/api/v4/projects/16442/jobs/artifacts/0.2.40/raw/module.tar.gz?job=publish",
"vue": "^2.6.12",
"vue-material-design-icons": "^4.11.0",
"vue-plausible": "^1.1.4",
"vue-router": "^3.5.1",
"vue-social-sharing": "^3.0.8",
"vuetify": "^2.5.8"
},
"devDependencies": {
......@@ -1700,60 +1695,6 @@
"node": ">=6.9.0"
}
},
"node_modules/@fortawesome/fontawesome-common-types": {
"version": "0.2.35",
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.35.tgz",
"integrity": "sha512-IHUfxSEDS9dDGqYwIW7wTN6tn/O8E0n5PcAHz9cAaBoZw6UpG20IG/YM3NNLaGPwPqgjBAFjIURzqoQs3rrtuw==",
"hasInstallScript": true,
"engines": {
"node": ">=6"
}
},
"node_modules/@fortawesome/fontawesome-svg-core": {
"version": "1.2.35",
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.35.tgz",
"integrity": "sha512-uLEXifXIL7hnh2sNZQrIJWNol7cTVIzwI+4qcBIq9QWaZqUblm0IDrtSqbNg+3SQf8SMGHkiSigD++rHmCHjBg==",
"hasInstallScript": true,
"dependencies": {
"@fortawesome/fontawesome-common-types": "^0.2.35"
},
"engines": {
"node": ">=6"
}
},
"node_modules/@fortawesome/free-brands-svg-icons": {
"version": "5.15.3",
"resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-5.15.3.tgz",
"integrity": "sha512-1hirPcbjj72ZJtFvdnXGPbAbpn3Ox6mH3g5STbANFp3vGSiE5u5ingAKV06mK6ZVqNYxUPlh4DlTnaIvLtF2kw==",
"hasInstallScript": true,
"dependencies": {
"@fortawesome/fontawesome-common-types": "^0.2.35"
},
"engines": {
"node": ">=6"
}
},
"node_modules/@fortawesome/free-solid-svg-icons": {
"version": "5.15.3",
"resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.15.3.tgz",
"integrity": "sha512-XPeeu1IlGYqz4VWGRAT5ukNMd4VHUEEJ7ysZ7pSSgaEtNvSo+FLurybGJVmiqkQdK50OkSja2bfZXOeyMGRD8Q==",
"hasInstallScript": true,
"dependencies": {
"@fortawesome/fontawesome-common-types": "^0.2.35"
},
"engines": {
"node": ">=6"
}
},
"node_modules/@fortawesome/vue-fontawesome": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@fortawesome/vue-fontawesome/-/vue-fontawesome-2.0.2.tgz",
"integrity": "sha512-ecpKSBUWXsxRJVi/dbOds4tkKwEcBQ1JSDZFzE2jTFpF8xIh3OgTX8POIor6bOltjibr3cdEyvnDjecMwUmxhQ==",
"peerDependencies": {
"@fortawesome/fontawesome-svg-core": ">= 1.2.0 < 1.3",
"vue": "~2"
}
},
"node_modules/@hapi/address": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz",
......@@ -8655,9 +8596,9 @@
"dev": true
},
"node_modules/inflection-table": {
"version": "0.2.31",
"resolved": "https://git.app.uib.no/api/v4/projects/16442/jobs/artifacts/0.2.31/raw/module.tar.gz?job=publish",
"integrity": "sha512-wB9qG4VFILPhpo3a0YcZWGhGUTtNdcVhw76LJAUNorRlunaAqADznEXDaFoY5qxjuJkRJGxGe1lQZAioX47a1g==",
"version": "0.2.40",
"resolved": "https://git.app.uib.no/api/v4/projects/16442/jobs/artifacts/0.2.40/raw/module.tar.gz?job=publish",
"integrity": "sha512-MOM71YWLmGPerc7ViWSouhWujHuNBaFb9ahnu82TJOSsWQK4qpDAtr791Y85PZgxVQjyneGAaBnQ5UVc+bI2xw==",
"dependencies": {
"core-js": "~3.6.5",
"jquery": "^3.5.1",
......@@ -15011,14 +14952,6 @@
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.5.2.tgz",
"integrity": "sha512-807gn82hTnjCYGrnF3eNmIw/dk7/GE4B5h69BlyCK9KHASwSloD1Sjcn06zg9fVG4fYH2DrsNBZkpLtb25WtaQ=="
},
"node_modules/vue-social-sharing": {
"version": "3.0.8",
"resolved": "https://registry.npmjs.org/vue-social-sharing/-/vue-social-sharing-3.0.8.tgz",
"integrity": "sha512-56gOES9fq7kyzuW7+lVAKtoG9Wi4MGjIfMqXAFZv1QSwW00EN0X5zJDSQjZn1Y2cIU6DUG+1KfJB7r7nTuiISA==",
"peerDependencies": {
"vue": "^2.6.10"
}
},
"node_modules/vue-style-loader": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.3.tgz",
......@@ -17209,41 +17142,6 @@
"to-fast-properties": "^2.0.0"
}
},
"@fortawesome/fontawesome-common-types": {
"version": "0.2.35",
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.35.tgz",
"integrity": "sha512-IHUfxSEDS9dDGqYwIW7wTN6tn/O8E0n5PcAHz9cAaBoZw6UpG20IG/YM3NNLaGPwPqgjBAFjIURzqoQs3rrtuw=="
},
"@fortawesome/fontawesome-svg-core": {
"version": "1.2.35",
"resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.35.tgz",
"integrity": "sha512-uLEXifXIL7hnh2sNZQrIJWNol7cTVIzwI+4qcBIq9QWaZqUblm0IDrtSqbNg+3SQf8SMGHkiSigD++rHmCHjBg==",
"requires": {
"@fortawesome/fontawesome-common-types": "^0.2.35"
}
},
"@fortawesome/free-brands-svg-icons": {
"version": "5.15.3",
"resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-5.15.3.tgz",
"integrity": "sha512-1hirPcbjj72ZJtFvdnXGPbAbpn3Ox6mH3g5STbANFp3vGSiE5u5ingAKV06mK6ZVqNYxUPlh4DlTnaIvLtF2kw==",
"requires": {
"@fortawesome/fontawesome-common-types": "^0.2.35"
}
},
"@fortawesome/free-solid-svg-icons": {
"version": "5.15.3",
"resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.15.3.tgz",
"integrity": "sha512-XPeeu1IlGYqz4VWGRAT5ukNMd4VHUEEJ7ysZ7pSSgaEtNvSo+FLurybGJVmiqkQdK50OkSja2bfZXOeyMGRD8Q==",
"requires": {
"@fortawesome/fontawesome-common-types": "^0.2.35"
}
},
"@fortawesome/vue-fontawesome": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@fortawesome/vue-fontawesome/-/vue-fontawesome-2.0.2.tgz",
"integrity": "sha512-ecpKSBUWXsxRJVi/dbOds4tkKwEcBQ1JSDZFzE2jTFpF8xIh3OgTX8POIor6bOltjibr3cdEyvnDjecMwUmxhQ==",
"requires": {}
},
"@hapi/address": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz",
......@@ -22851,8 +22749,8 @@
"dev": true
},
"inflection-table": {
"version": "https://git.app.uib.no/api/v4/projects/16442/jobs/artifacts/0.2.31/raw/module.tar.gz?job=publish",
"integrity": "sha512-wB9qG4VFILPhpo3a0YcZWGhGUTtNdcVhw76LJAUNorRlunaAqADznEXDaFoY5qxjuJkRJGxGe1lQZAioX47a1g==",
"version": "https://git.app.uib.no/api/v4/projects/16442/jobs/artifacts/0.2.40/raw/module.tar.gz?job=publish",
"integrity": "sha512-MOM71YWLmGPerc7ViWSouhWujHuNBaFb9ahnu82TJOSsWQK4qpDAtr791Y85PZgxVQjyneGAaBnQ5UVc+bI2xw==",
"requires": {
"core-js": "~3.6.5",
"jquery": "^3.5.1",
......@@ -28006,12 +27904,6 @@
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.5.2.tgz",
"integrity": "sha512-807gn82hTnjCYGrnF3eNmIw/dk7/GE4B5h69BlyCK9KHASwSloD1Sjcn06zg9fVG4fYH2DrsNBZkpLtb25WtaQ=="
},
"vue-social-sharing": {
"version": "3.0.8",
"resolved": "https://registry.npmjs.org/vue-social-sharing/-/vue-social-sharing-3.0.8.tgz",
"integrity": "sha512-56gOES9fq7kyzuW7+lVAKtoG9Wi4MGjIfMqXAFZv1QSwW00EN0X5zJDSQjZn1Y2cIU6DUG+1KfJB7r7nTuiISA==",
"requires": {}
},
"vue-style-loader": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.3.tgz",
......@@ -127,8 +127,16 @@ article {
background-color: #ffffff;
}
.xs .article_footer, .sm .article_footer {
display: none;
}
.welcome .article_footer {
display: block;
}
#single_article_container article {
border: solid 2px var(--v-primary-base);
border: solid 1px var(--v-primary-base);
}
.fade {
......@@ -219,5 +227,9 @@ ul li.definition {
text-decoration: none;
}
.info-card {
padding: 12px;
}
</style>
<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>
<v-btn v-if="!webShareApiSupported" x-small depressed class="toolbar-button" rounded tabindex="0" @click="copy_link">
<v-icon small>link</v-icon> <span class = "button-text">Kopier lenke</span>
</v-btn>
<v-btn v-if="webShareApiSupported" depressed x-small class="toolbar-button" rounded tabindex="0" @click="shareViaWebShare">
<v-icon x-small>share</v-icon><span class = "button-text">Del ordet</span>
</v-btn>
<v-dialog max-width="600px" rounded="0" v-model="citation_dialog">
<template v-slot:activator="{ on, attrs }">
<v-btn depressed x-small class="toolbar-button" rounded tabindex="0" v-on="on" v-bind="attrs">
<v-icon x-small>format_quote</v-icon> <span class = "button-text">Siter</span>
</v-btn>
</template>
<v-card rounded="0" class="info-card">
{{{"nn": "Ønskjer du å sitere denne artikkelen i Nynorskordboka, rår vi deg til å gje opp når artikkelen vart henta (lesen), t.d. slik:",
"bm": "Ønsker du å sitere denne artikkelen i Bokmålsordboka, anbefaler vi å oppgi når artikkelen ble hentet (lest), f.eks. slik:"}[this.article.dictionary]}}<br/>
<div id = "citation" v-html="this.create_citation()"/>
<v-btn depressed x-small class="toolbar-button" rounded tabindex="0" @click="copy_citation"><br>
<v-icon x-small icon>content_copy</v-icon> <span class = "button-text">Kopier</span>
</v-btn>
<v-btn depressed x-small class="toolbar-button" rounded tabindex="0" @click="download_ris"><br>
<v-icon x-small icon>get_app</v-icon> <span class = "button-text">Last ned (RIS)</span>
</v-btn>
<v-btn depressed x-small class="toolbar-button" rounded tabindex="0" @click="close_citation_dialog"><br>
<v-icon x-small icon>close</v-icon> <span class = "button-text">Avbryt</span>
</v-btn>
</v-card>
</v-dialog>
</div>
</template>
<script>
const host = window.location.hostname === 'localhost'? 'https://dev.ordbok.uib.no/' : window.location.href
export default {
name: 'ArticleFooter',
props: {
article: Object
},
computed: {
dict_label: function() { // TODO: reuse code used in header
return {
'bm': 'Fra bokmålsordboka',
'nn': 'Frå nynorskordboka'
}[this.article.dictionary] + ': ' + this.article.lemmas[0].lemma || ''
},
webShareApiSupported() {
return navigator.share
},
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)
},
data: function() {
return {
citation_dialog: false
}
},
methods: {
shareViaWebShare() {
......@@ -60,26 +62,71 @@ export default {
text: "",
url: "/" + this.article.dictionary + '/' + this.article.article_id + '/' + encodeURIComponent(this.article.lemmas[0].lemma)
})
}
},
create_link() {
return host + this.article.dictionary + '/' + this.article.article_id + '/' + encodeURIComponent(this.article.lemmas[0].lemma)
},
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
return [lemma, dd, mm, yyyy, link]
},
create_citation() {
const [lemma, dd, mm, yyyy, link] = this.get_citation_info()
let citation = {"bm": ${lemma}». I: <em>Bokmålsordboka.</em> Språkrådet og Universitetet i Bergen. &lt;<a href='${link}'>${link}</a>&gt; (hentet ${dd}.${mm}.${yyyy}).`,
"nn":${lemma}». I: <em>Nynorskordboka.</em> Språkrådet og Universitetet i Bergen. &lt;<a href='${link}'>${link}</a>&gt; (henta ${dd}.${mm}.${yyyy}).`
}[this.article.dictionary]
return citation
},
copy_link() {
navigator.clipboard.writeText(this.create_link());
},
copy_citation() {
let citation = document.getElementById("citation").textContent;
navigator.clipboard.writeText(citation)
this.citation_dialog = false
},
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;
.button-text {
padding-left: 3px;
font-size: 12px;
color: var(--v-primary-base) !important;
}
.v-icon {
color: var(--v-primary-base) !important;
}
.share_button {
padding-right: 4px;
font-weight: bold;
font-size: 14px;
.toolbar-button {
margin-right: 6px;
margin-top: 6px;
font-size: 12px;
}
......@@ -88,11 +135,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>
......@@ -99,7 +99,7 @@
this.items.push({q: q, label: q, time: time, search: search})
}
let self = this
self.api.get('suggest?', {params: {q: q, dict: self.get_lang(), n: 80, scope: 'w', dform: 'int'}})
self.api.get('suggest?', {params: {q: q, dict: self.get_lang(), n: 80, scope: 'w', dform: 'int', meta: 'n'}})
.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]]}))
......
......@@ -165,7 +165,7 @@ function navigate_to_query(self, word) {
let query = self.event ? self.event : {q: word}
// Get article IDs
api.get('articles?', {params: {w: query.match || query.q, dict: self.lang, scope: "w"}}).then((response) => {
api.get('articles?', {params: {w: query.match || query.q, dict: self.lang, scope: "w", meta: 'n'}}).then((response) => {
let article_ids = response.data
let unwrapped = []
for (const d in article_ids) {
......
......@@ -19,13 +19,17 @@
</v-card>
</v-menu>)
</span>
<details :title="inflect_tooltip" @toggle="toggle()" v-if="inflected" :class="$vuetify.breakpoint.name">
<summary :class="dictionary" onclick="this.blur()" tabindex="0">bøying</summary>
<div class="inflection-canvas">
<div class="inflection-wrapper" v-if="inflected">
<v-btn class="show-inflection" width="160px" rounded depressed small @click.native="toggle" :class="$vuetify.breakpoint.name">
<span>{{inflection_button_text}}</span><span class = "inflection-arrow">{{inflection_arrow}}</span>
</v-btn>
<div class="inflection-canvas" v-if="inflection_expanded">
<inflectionTable :lemmaList="lemmas_with_word_class_and_lang" :mq="$vuetify.breakpoint.name" />
</div>
</details>
</div>
</div>
</template>
......@@ -67,6 +71,15 @@ export default {
'nn': 'nynorskordboka'
}[this.dictionary] || ''
},
inflection_button_text: function() {
return {
"bm": {false: "Se bøyning", true: "Skjul bøyning"},
"nn": {false: "Sjå bøying", true: "Skjul bøying"}
}[this.dictionary][this.inflection_expanded]
},
inflection_arrow: function() {
return this.inflection_expanded? "" : ""
},
group_list: function() {
return helpers.group_list(this.lemmas, this.dictionary)
},
......@@ -100,15 +113,18 @@ export default {
data: function() {
return {
inflect_reported: false,
menu: false
menu: false,
inflection_expanded: false
}
},
methods: {
toggle: function() {
this.inflection_expanded = !this.inflection_expanded
if (! this.inflect_reported) {
this.$plausible.trackEvent('open inflection', {props: {article: `/${this.dictionary}/${this.article_id}/${this.lemmas[0].lemma}`}})
}
this.inflect_reported = true
}
}
}
......@@ -118,11 +134,6 @@ export default {
<style>
summary {
width: 30em;
text-align: center;
}
article h2 {
padding-top: 4px;
padding-bottom: 0px;
......@@ -142,10 +153,6 @@ article h2.secondary_header {
width: 10px;
}
.info-card {
padding: 12px;
}
.word-classification {
text-decoration: underline dashed;
}
......@@ -160,56 +167,18 @@ article h2.secondary_header {
font-variant-caps: all-small-caps;
}
.header details {
margin-top: 10px;
position: relative;
}
.header summary {
position: relative;
max-width: 130px;
list-style: none;
border: solid 2px var(--v-primary-base);
border-radius: 30px;
padding-top: 6px;
padding-bottom: 6px;
padding-right: 10px;
color: var(--v-primary-base);
cursor: pointer;
}
.header details[open] > summary {
box-shadow: 2px 2px 0px var(--v-primary-base)
}
.header details > summary:after {
content: "⌄";
font-weight: bold;
position: absolute;
right: 0;
top: 1px;
margin-right: 3px;
}
.header details > summary.bm:before {
content: "Se ";
}
.header details > summary.nn:before {
content: "Sjå ";
.show-inflection {
color: var(--v-primary-base) !important;
font-weight: bold !important;
}
.header details[open] > summary.bm:before, details[open] > summary.nn:before {
content: "Skjul ";
}
.header details[open] > summary:after {
content: "⌃";
font-weight: bold;
.inflection-arrow {
position: absolute;
right: 0;
top: 8px;
margin-right: 3px;
right: -4px;
margin-left: 3px;
font-size: 10px;
}
@keyframes open {
......@@ -221,10 +190,6 @@ article h2.secondary_header {
}
}
.header details[open] summary ~ * {
animation: open 0.3s ease-in-out;
}
.inflection-canvas {
overflow-x: auto;
/*position: absolute;*/
......@@ -234,14 +199,17 @@ article h2.secondary_header {
padding-top: 10px;
}
.header details > summary::-webkit-details-marker {
display: none;
}
.infl-wrapper {
color: var(--v-primary-base);
.inflection-wrapper {
color: var(--v-text-base);
width: min-content;
font-size: 14px;
overflow-x: auto;
margin-top: 10px;
}
#search_results .xs .inflection-wrapper, #search_results .sm .inflection-wrapper {
display: none;
}
.context {
......@@ -264,8 +232,8 @@ th, td {
}
th {
background-color: var(--v-tertiary-darken1);
color: var(--v-primary-darken1);
background-color: var(--v-button-base);
color: var(--v-primary-darken1)
}
.infl-label {
......
......@@ -7,9 +7,6 @@ import VueRouter from 'vue-router'
import { VuePlausible } from 'vue-plausible'
import vuetify from './plugins/vuetify'