Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

日報・DOCs・Q&Aページに「現在のページURLをコピーするボタン」を追加 #8219

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions app/javascript/copy-url.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
function copyUrl() {
const url = window.location.href
navigator.clipboard
.writeText(url)
.then(() => {
const button = document.querySelector('.a-copy-button')
button.classList.add('is-active')
setTimeout(() => {
button.classList.remove('is-active')
}, 4000)
})
.catch((err) => {
console.error(err)
})
}

window.copyUrl = copyUrl
1 change: 1 addition & 0 deletions app/javascript/packs/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ import '../product-checker.js'
import '../user-follow.js'
import '../sort-faq.js'
import '../sort-faq-category.js'
import '../copy-url.js'

import VueMounter from '../VueMounter.js'
import Questions from '../components/questions.vue'
Expand Down
1 change: 1 addition & 0 deletions app/javascript/stylesheets/_common-imports.sass
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@
@import "atoms/a-icon-label"
@import "atoms/a-side-nav"
@import "atoms/a-notice-block"
@import "atoms/temp"

////////////
// layouts
Expand Down
27 changes: 27 additions & 0 deletions app/javascript/stylesheets/atoms/_temp.sass
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
.a-copy-button.is-muted
color: var(--semi-muted-text)
background-color: var(--background-semi-shade)

.a-copy-button
position: relative
color: var(--semi-muted-text)
background-color: var(--background-semi-shade)
border: none

.a-copy-button.is-active
background-color: hsl(242, 51%, 51%)
color: white

.a-copy-button.is-active::after
content: "Copied!"
display: block
background-color: rgba(0, 0, 0, 0.4)
border-radius: 0.125rem
padding: 0.25rem
font-size: 0.625rem
line-height: 1
color: white
color: var(--reversal-text)
position: absolute
left: 0
top: 100%
2 changes: 2 additions & 0 deletions app/views/application/_url_copy_button.html.slim
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.page-content-header-actions__action
button.a-copy-button.a-button.is-sm.is-block.is-inactive.is-muted onclick="copyUrl()" URLコピー
1 change: 1 addition & 0 deletions app/views/pages/_doc_header.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ header.page-content-header
div(data-vue="WatchToggle" data-vue-watchable-id:number="#{page.id}" data-vue-watchable-type='Page')
.page-content-header-actions__action
= react_component('BookmarkButton', bookmarkableId: page.id, bookmarkableType: 'Page')
= render 'application/url_copy_button'

.page-content-header__row
.page-content-header__tags
Expand Down
1 change: 1 addition & 0 deletions app/views/questions/_question_header.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ header.page-content-header
div(data-vue='WatchToggle' data-vue-watchable-id:number="#{question.id}" data-vue-watchable-type='Question')
.page-content-header-actions__action
= react_component('BookmarkButton', bookmarkableId: question.id, bookmarkableType: 'Question')
= render 'application/url_copy_button'
.page-content-header-actions__end
.page-content-header-actions__action
= link_to question_path(question, format: :md), class: 'a-button is-sm is-secondary is-block', target: '_blank', rel: 'noopener' do
Expand Down
2 changes: 2 additions & 0 deletions app/views/reports/_report_header.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ header.page-content-header
div(data-vue="WatchToggle" data-vue-watchable-id:number="#{report.id}" data-vue-watchable-type='Report')
.page-content-header-actions__action
= react_component('BookmarkButton', bookmarkableId: report.id, bookmarkableType: 'Report')
= render 'application/url_copy_button'

.page-content-header-actions__end
- if report.user_id == current_user.id
.page-content-header-actions__action
Expand Down
20 changes: 20 additions & 0 deletions test/system/reports_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -769,4 +769,24 @@ def wait_for_watch_change
visit_with_auth report_path(report), 'komagata'
assert_selector '.a-page-notice.is-muted.is-only-mentor', text: 'このユーザーは退会しています。'
end

test 'URL copy button copies the current URL to the clipboard' do
report = reports(:report10)
visit_with_auth "/reports/#{report.id}", 'hajime'
cdp_permission_write = {
origin: page.server_url,
permission: { name: 'clipboard-write' },
setting: 'granted'
}
page.driver.browser.execute_cdp('Browser.setPermission', **cdp_permission_write)
cdp_permission_read = {
origin: page.server_url,
permission: { name: 'clipboard-read' },
setting: 'granted'
}
page.driver.browser.execute_cdp('Browser.setPermission', **cdp_permission_read)
click_button 'URLコピー'
clip_text = page.evaluate_async_script('navigator.clipboard.readText().then(arguments[0])')
assert_equal current_url, clip_text
end
end