Skip to content

Commit ed44f6e

Browse files
authored
Merge pull request #1590 from NatLibFi/issue1484-concept-page-copy-to-clipboard
Copy to clipboard functionality for concept page
2 parents 83fd8a1 + f5ee24c commit ed44f6e

File tree

9 files changed

+95
-24
lines changed

9 files changed

+95
-24
lines changed

resource/css/skosmos.css

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,6 @@ body {
8585
margin: 0 5px;
8686
}
8787

88-
#main-container.termpage .fa-copy {
89-
color: var(--vocab-text);
90-
font-size: 30px;
91-
position: relative;
92-
bottom: -3px;
93-
}
94-
9588
#main-container.searchpage .fa-arrow-right, #main-container.searchpage-multi-vocab .fa-arrow-right {
9689
color: var(--vocab-text);
9790
font-size: 12px;
@@ -105,11 +98,6 @@ body {
10598
text-align: center;
10699
}
107100

108-
#main-container.searchpage .fa-copy, #main-container.searchpage-multi-vocab .fa-copy {
109-
position: relative;
110-
bottom: 5px;
111-
}
112-
113101
.fa-magnifying-glass {
114102
color: var(--search-button-text);
115103
font-size: 22px;
@@ -703,16 +691,26 @@ body {
703691
}
704692

705693
#concept-label h1 {
706-
float: left;
694+
display: inline;
707695
}
708696

709-
.copy-clipboard {
710-
border: none;
711-
font-size: 20px;
697+
#copy-preflabel {
698+
color: var(--vocab-text);
699+
font-size: 30px;
700+
position: relative;
701+
bottom: 10px;
702+
left: 5px;
712703
}
713704

714-
.copy-clipboard:active, .copy-clipboard:focus, .copy-clipboard:active:focus {
715-
border: none;
705+
#copy-uri {
706+
color: var(--vocab-text);
707+
position: relative;
708+
bottom: 4px;
709+
}
710+
711+
.copy-clipboard:focus {
712+
border: 1px solid var(--vocab-text);
713+
border-radius: 3px;
716714
}
717715

718716
.property ul, .property li {

resource/js/copy-to-clipboard.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// function for copying the content from a specific element (by id) to the clipboard
2+
function copyToClipboard (id) {
3+
const copyElem = document.getElementById(id)
4+
const sel = window.getSelection()
5+
const range = document.createRange()
6+
range.selectNodeContents(copyElem)
7+
sel.removeAllRanges()
8+
sel.addRange(range)
9+
10+
navigator.clipboard.writeText(copyElem.innerText).catch((err) =>
11+
console.error('Failed to copy text to clipboard: ', err))
12+
}
13+
14+
function registerCopyToClipboardEvents () {
15+
const copyPrefElem = document.getElementById('copy-preflabel')
16+
if (copyPrefElem) {
17+
copyPrefElem.addEventListener('click', () => copyToClipboard('concept-preflabel'))
18+
}
19+
20+
const copyUriElem = document.getElementById('copy-uri')
21+
if (copyUriElem) {
22+
copyUriElem.addEventListener('click', () => copyToClipboard('concept-uri'))
23+
}
24+
}
25+
26+
// register the copyToClipboard function as event an handler for the copy buttons
27+
registerCopyToClipboardEvents()
28+
29+
// re-register the event handlers after partial page loads
30+
document.addEventListener('loadConceptPage', registerCopyToClipboardEvents)

resource/translations/skosmos_en.po

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -879,3 +879,6 @@ msgstr "Information"
879879

880880
msgid "Breadcrumbs"
881881
msgstr "Breadcrumbs"
882+
883+
msgid "Copy to clipboard"
884+
msgstr "Copy to clipboard"

resource/translations/skosmos_fi.po

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -888,3 +888,6 @@ msgstr "Tietoja"
888888

889889
msgid "Breadcrumbs"
890890
msgstr "Murupolut"
891+
892+
msgid "Copy to clipboard"
893+
msgstr "Kopioi leikepöydälle"

resource/translations/skosmos_sv.po

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -887,3 +887,6 @@ msgstr "Information"
887887

888888
msgid "Breadcrumbs"
889889
msgstr "Brödsmulor"
890+
891+
msgid "Copy to clipboard"
892+
msgstr "Kopiera till urklipp"

src/view/concept-card.inc

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,11 @@
3030
<div class="row" id="concept-heading">
3131
<div class="col-sm-4 px-0" id="concept-property-label">{{ "skos:prefLabel" | trans }}</div>
3232
<div class="col-sm-8" id="concept-label">
33-
<h1 class="mb-0">{{ concept.label }}</h1>
34-
<button class="btn btn-default copy-clipboard" type="button"
33+
<h1 id="concept-preflabel"
34+
class="mb-0 user-select-all">{{ concept.label }}</h1><button
35+
class="btn btn-default copy-clipboard px-1" type="button" id="copy-preflabel"
3536
data-bs-toggle="tooltip" data-bs-placement="button" title="{{ 'Copy to clipboard' | trans }}">
36-
<i class="fa-regular fa-copy"></i>
37+
<i class="fa-regular fa-copy"></i>
3738
</button>
3839
</div>
3940
</div>
@@ -87,7 +88,14 @@
8788
{% endif %}
8889
<div class="row property prop-uri">
8990
<div class="col-sm-4 px-0 property-label"><h2>URI</h2></div>
90-
<div class="col-sm-8" id="concept-uri"><a href="#">{{ concept.uri }}</a></div>
91+
<div class="col-sm-8">
92+
<span id="concept-uri"
93+
class="user-select-all">{{ concept.uri }}</span><button
94+
class="btn btn-default copy-clipboard px-1" type="button" id="copy-uri"
95+
data-bs-toggle="tooltip" data-bs-placement="button" title="{{ 'Copy to clipboard' | trans }}">
96+
<i class="fa-regular fa-copy"></i>
97+
</button>
98+
</div>
9199
</div>
92100
<div class="row property prop-download">
93101
<div class="col-sm-4 px-0 property-label">

src/view/scripts.inc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const SKOSMOS = {
2424
{%- if request.plugins.callbacks ~%}
2525
"pluginCallbacks": [{% for function in request.plugins.callbacks %}{% if not loop.first %}, {% endif %}"{{ function }}"{% endfor %}],
2626
{%- endif ~%}
27-
"language_strings" :{ "fi": { "fi": "suomi",
27+
"language_strings": { "fi": { "fi": "suomi",
2828
"en": "englanti",
2929
"se": "pohjoissaame",
3030
"sv": "ruotsi",
@@ -73,3 +73,6 @@ const SKOSMOS = {
7373
<script src="resource/js/tab-alpha.js"></script>
7474
<script src="resource/js/tab-hierarchy.js"></script>
7575
<script src="resource/js/vocab-search.js"></script>
76+
77+
<!-- Other (non-Vue) JS functionality -->
78+
<script src="resource/js/copy-to-clipboard.js"></script>

src/view/search-results.inc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@
103103
<li class="list-group-item px-0 py-1">
104104
<span class="uri-icon">URI</span>
105105
<span class="search-result-uri">{{ concept.uri }}</span>
106-
<i class="fa-regular fa-copy"></i> <!-- no copy to clipboard functionality yet -->
107106
</li>
108107
{%~ endif ~%}
109108
</ul>

tests/cypress/template/concept.cy.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,18 @@ describe('Concept page', () => {
9595
// check the concept prefLabel
9696
cy.get('#concept-heading h1').invoke('text').should('equal', 'music research')
9797
})
98+
it('concept preflabel can be copied to clipboard', () => {
99+
cy.visit('/yso/en/page/p21685') // go to "music research" concept page
100+
101+
// click the copy to clipboard button next to the prefLabel
102+
cy.get('#copy-preflabel').click()
103+
104+
// check that the clipboard now contains "music research"
105+
// NOTE: This test may fail when running Cypress interactively in a browser.
106+
// The reason is browser security policies for accessing the clipboard.
107+
// If that happens, make sure the browser window has focus and re-run the test.
108+
cy.window().its('navigator.clipboard').invoke('readText').then((result) => {}).should('equal', 'music research');
109+
})
98110
it('contains concept type', () => {
99111
cy.visit('/yso/en/page/p21685') // go to "music research" concept page
100112

@@ -219,6 +231,18 @@ describe('Concept page', () => {
219231
// check the broader concept
220232
cy.get('#concept-uri').invoke('text').should('equal', 'http://www.yso.fi/onto/yso/p21685')
221233
})
234+
it('concept URI can be copied to clipboard', () => {
235+
cy.visit('/yso/en/page/p21685') // go to "music research" concept page
236+
237+
// click the copy to clipboard button next to the URI
238+
cy.get('#copy-uri').click()
239+
240+
// check that the clipboard now contains "http://www.yso.fi/onto/yso/p21685"
241+
// NOTE: This test may fail when running Cypress interactively in a browser.
242+
// The reason is browser security policies for accessing the clipboard.
243+
// If that happens, make sure the browser window has focus and re-run the test.
244+
cy.window().its('navigator.clipboard').invoke('readText').then((result) => {}).should('equal', 'http://www.yso.fi/onto/yso/p21685');
245+
})
222246
it('contains created & modified times (English)', () => {
223247
cy.visit('/yso/en/page/p21685') // go to "music research" concept page (English)
224248

0 commit comments

Comments
 (0)