Add feature: copy code to clipboard (#916)
* Add copy to clipboard code feature * Fix test * Fix electron-apps version at package.json and update copy button js, css * Remove .editorconfig * refactor clipboard copy code * localize clipboard button and tooltip labels * lint * test for meta tags
This commit is contained in:
Родитель
a23b309a97
Коммит
9a6960a57f
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -142,6 +142,11 @@ apps:
|
|||
something_missing: Something missing?
|
||||
edit_this_app: Edit this app.
|
||||
|
||||
clipboard:
|
||||
copy: Copy
|
||||
copy_to_clipboard: Copy to Clipboard
|
||||
copied: Copied
|
||||
|
||||
or: or
|
||||
|
||||
pages:
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -27,6 +27,7 @@
|
|||
"browser-date-formatter": "^2.1.1",
|
||||
"browser-sync": "^2.18.12",
|
||||
"browserify-middleware": "^8.0.0",
|
||||
"clipboard": "^1.7.1",
|
||||
"compression": "^1.7.1",
|
||||
"connect-browser-sync": "^2.1.0",
|
||||
"connect-slashes": "^1.3.1",
|
||||
|
@ -40,7 +41,7 @@
|
|||
"express-hbs": "^1.0.4",
|
||||
"express-request-language": "^1.1.15",
|
||||
"flat": "^4.0.0",
|
||||
"github": "^12.0.6",
|
||||
"github": "^12.1.0",
|
||||
"got": "^8.0.0",
|
||||
"helmet": "^3.9.0",
|
||||
"href-type": "^1.0.1",
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
const Clipboard = require('clipboard')
|
||||
const clipboard = new Clipboard('.btn-clipboard')
|
||||
|
||||
clipboard.on('success', (e) => {
|
||||
e.clearSelection()
|
||||
})
|
||||
|
||||
module.exports = function copyCodeToClipBoard () {
|
||||
document.querySelectorAll(`code.hljs`).forEach(code => {
|
||||
const id = `_${Math.random().toString(36).substr(5)}`
|
||||
code.id = id
|
||||
const button = document.createElement('button')
|
||||
button.classList.add('btn-clipboard', 'simptip-position-top')
|
||||
button.setAttribute('data-tooltip', window.localized.clipboard.copy_to_clipboard)
|
||||
button.setAttribute('data-clipboard-target', `#${id}`)
|
||||
button.innerHTML = window.localized.clipboard.copy
|
||||
code.parentElement.appendChild(button)
|
||||
})
|
||||
|
||||
document.querySelectorAll('.btn-clipboard').forEach(button => {
|
||||
button.addEventListener('mouseout', function (e) {
|
||||
e.target.setAttribute('data-tooltip', window.localized.clipboard.copy_to_clipboard)
|
||||
e.target.blur()
|
||||
})
|
||||
button.addEventListener('click', function (e) {
|
||||
e.target.setAttribute('data-tooltip', window.localized.clipboard.copied)
|
||||
})
|
||||
})
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
// Consume localized strings from meta tags like this one:
|
||||
//
|
||||
// <meta name="localized.clipboard.copy" content="{{localized.clipboard.copy}}" />
|
||||
//
|
||||
// Then assembled a deeply-keyed global object called `window.localized`
|
||||
|
||||
const setProp = require('lodash/set')
|
||||
|
||||
module.exports = function getLocalizedString () {
|
||||
window.localized = Array.from(document.querySelectorAll('meta[name^="localized"]'))
|
||||
.reduce((acc, el) => {
|
||||
const key = el.getAttribute('name').replace('localized.', '')
|
||||
const val = el.getAttribute('content')
|
||||
setProp(acc, key, val)
|
||||
return acc
|
||||
}, {})
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
document.addEventListener('DOMContentLoaded', () => {
|
||||
require('./get-localized-strings')()
|
||||
require('./create-filter-list')()
|
||||
require('./fix-platform-labels')()
|
||||
require('./update-demo-app-download-link')()
|
||||
|
@ -8,4 +9,5 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||
require('./remove-scheme-from-link-text')()
|
||||
require('./lazy-load-images')()
|
||||
require('browser-date-formatter')()
|
||||
require('./copy-code-to-clipboard')()
|
||||
})
|
||||
|
|
|
@ -1,4 +1,26 @@
|
|||
pre {
|
||||
overflow: visible;
|
||||
position: relative;
|
||||
.btn-clipboard {
|
||||
outline: 0;
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
right: 5px;
|
||||
padding: .25rem .5rem;
|
||||
font-size: 1.2em;
|
||||
border: 1px #e5e5e5 solid;
|
||||
background-color: #f8f8f8;
|
||||
border-radius: .25rem;
|
||||
&:hover {
|
||||
background-color: #eee;
|
||||
}
|
||||
&:active {
|
||||
background-color: #dfdfdf;
|
||||
}
|
||||
}
|
||||
}
|
||||
.hljs {
|
||||
position: relative;
|
||||
line-height: 1.6;
|
||||
font-size: 1.2em;
|
||||
padding: 10px;
|
||||
|
|
|
@ -16,7 +16,6 @@ $octicons-font-path: "../bower_components/octicons/octicons/";
|
|||
@import "../bower_components/basecoat/scss/mixins/clearfix";
|
||||
@import "../bower_components/basecoat/scss/mixins/grid-framework";
|
||||
|
||||
|
||||
// Basecoat
|
||||
@import "../bower_components/primer-css/scss/normalize";
|
||||
@import "../bower_components/primer-css/scss/base";
|
||||
|
@ -27,7 +26,6 @@ $octicons-font-path: "../bower_components/octicons/octicons/";
|
|||
@import "../bower_components/basecoat/scss/layout"; // Basecoat override
|
||||
@import "../bower_components/basecoat/scss/type"; // Basecoat override
|
||||
|
||||
|
||||
// Components
|
||||
// @import "../bower_components/primer-css/scss/alerts";
|
||||
// @import "../bower_components/primer-css/scss/avatars";
|
||||
|
@ -60,6 +58,9 @@ $octicons-font-path: "../bower_components/octicons/octicons/";
|
|||
@import "../bower_components/primer-css/scss/utilities/utilities";
|
||||
@import "../bower_components/basecoat/scss/utility"; // Basecoat override
|
||||
|
||||
// Tooltip
|
||||
@import "../bower_components/simptip.min.css";
|
||||
|
||||
// Electron -----------------------------------
|
||||
|
||||
@import "base";
|
||||
|
|
|
@ -211,6 +211,14 @@ describe('electronjs.org', () => {
|
|||
})
|
||||
})
|
||||
|
||||
describe('localized strings for client-side code', () => {
|
||||
it('sets meta tags for clipboard labels', async () => {
|
||||
const $ = await get('/')
|
||||
$('meta[name="localized.clipboard.copy"]').attr('content').should.eq('Copy')
|
||||
$('meta[name="localized.clipboard.copy_to_clipboard"]').attr('content').should.eq('Copy to Clipboard')
|
||||
})
|
||||
})
|
||||
|
||||
describe('devtron and spectron', async () => {
|
||||
test('Test existed landing pages', async () => {
|
||||
let $ = await get('/devtron')
|
||||
|
|
|
@ -30,6 +30,11 @@
|
|||
<meta name="twitter:card" content="summary">
|
||||
{{/if}}
|
||||
|
||||
<!-- consumed by scripts/get-localized-strings -->
|
||||
<meta name="localized.clipboard.copy" content="{{localized.clipboard.copy}}" />
|
||||
<meta name="localized.clipboard.copy_to_clipboard" content="{{localized.clipboard.copy_to_clipboard}}" />
|
||||
<meta name="localized.clipboard.copied" content="{{localized.clipboard.copied}}" />
|
||||
|
||||
<meta name="twitter:site" content="@ElectronJS" />
|
||||
<link rel='shortcut icon' href='/images/favicon.ico'/>
|
||||
<link rel='stylesheet' href='/styles/index.css'>
|
||||
|
|
Загрузка…
Ссылка в новой задаче