copy_tuner_client 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CLAUDE.md +4 -1
- data/README.md +6 -2
- data/app/assets/javascripts/copytuner.js +162 -255
- data/biome.json +39 -0
- data/index.html +9 -11
- data/lib/copy_tuner_client/copyray_middleware.rb +0 -6
- data/lib/copy_tuner_client/engine.rb +1 -1
- data/lib/copy_tuner_client/version.rb +1 -1
- data/mise.toml +3 -0
- data/package.json +9 -13
- data/pnpm-lock.yaml +600 -0
- data/spec/copy_tuner_client/copyray_middleware_spec.rb +1 -2
- data/src/copyray-overlay.ts +125 -0
- data/src/copytuner-bar.ts +153 -0
- data/src/main.ts +29 -25
- data/src/{copyray.css → styles.ts} +104 -139
- data/src/util.ts +9 -1
- data/tsconfig.json +5 -10
- data/vite.config.ts +0 -1
- metadata +7 -8
- data/.eslintrc.js +0 -12
- data/app/assets/stylesheets/copytuner.css +0 -1
- data/src/copyray.ts +0 -111
- data/src/copytuner_bar.ts +0 -129
- data/src/specimen.ts +0 -94
- data/yarn.lock +0 -2540
data/vite.config.ts
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: copy_tuner_client
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- SonicGarden
|
|
@@ -183,7 +183,6 @@ extensions: []
|
|
|
183
183
|
extra_rdoc_files: []
|
|
184
184
|
files:
|
|
185
185
|
- ".babelrc"
|
|
186
|
-
- ".eslintrc.js"
|
|
187
186
|
- ".gitattributes"
|
|
188
187
|
- ".github/dependabot.yml"
|
|
189
188
|
- ".github/workflows/rspec.yml"
|
|
@@ -200,7 +199,7 @@ files:
|
|
|
200
199
|
- Rakefile
|
|
201
200
|
- UPGRADING.md
|
|
202
201
|
- app/assets/javascripts/copytuner.js
|
|
203
|
-
-
|
|
202
|
+
- biome.json
|
|
204
203
|
- copy_tuner_client.gemspec
|
|
205
204
|
- gemfiles/8.0.gemfile
|
|
206
205
|
- gemfiles/8.1.gemfile
|
|
@@ -230,7 +229,9 @@ files:
|
|
|
230
229
|
- lib/copy_tuner_client/translation_log.rb
|
|
231
230
|
- lib/copy_tuner_client/version.rb
|
|
232
231
|
- lib/tasks/copy_tuner_client_tasks.rake
|
|
232
|
+
- mise.toml
|
|
233
233
|
- package.json
|
|
234
|
+
- pnpm-lock.yaml
|
|
234
235
|
- skills/copy-tuner-to-locales-cleanup/SKILL.md
|
|
235
236
|
- skills/copy-tuner-to-locales-cleanup/references/example-touchpoints.md
|
|
236
237
|
- skills/copy-tuner-to-locales-cleanup/references/verification-final.md
|
|
@@ -270,18 +271,16 @@ files:
|
|
|
270
271
|
- spec/support/fake_unicorn.rb
|
|
271
272
|
- spec/support/middleware_stack.rb
|
|
272
273
|
- spec/support/writing_cache.rb
|
|
273
|
-
- src/copyray.
|
|
274
|
-
- src/
|
|
275
|
-
- src/copytuner_bar.ts
|
|
274
|
+
- src/copyray-overlay.ts
|
|
275
|
+
- src/copytuner-bar.ts
|
|
276
276
|
- src/main.ts
|
|
277
|
-
- src/
|
|
277
|
+
- src/styles.ts
|
|
278
278
|
- src/util.ts
|
|
279
279
|
- src/vite-env.d.ts
|
|
280
280
|
- tsconfig.json
|
|
281
281
|
- ui/views/copytuner/index.html.erb
|
|
282
282
|
- ui/views/layouts/copytuner_default.html.erb
|
|
283
283
|
- vite.config.ts
|
|
284
|
-
- yarn.lock
|
|
285
284
|
homepage: https://github.com/SonicGarden/copy-tuner-ruby-client
|
|
286
285
|
licenses: []
|
|
287
286
|
metadata:
|
data/.eslintrc.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
module.exports = {
|
|
2
|
-
plugins: ['@sonicgarden'],
|
|
3
|
-
extends: [
|
|
4
|
-
'plugin:@sonicgarden/browser',
|
|
5
|
-
'plugin:@sonicgarden/recommended',
|
|
6
|
-
'plugin:@sonicgarden/typescript',
|
|
7
|
-
'plugin:@sonicgarden/prettier',
|
|
8
|
-
],
|
|
9
|
-
settings: {
|
|
10
|
-
'import/internal-regex': '^@/',
|
|
11
|
-
},
|
|
12
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
@charset "UTF-8";#copyray-overlay,#copyray-overlay *,#copyray-overlay a:hover,#copyray-overlay a:visited,#copyray-overlay a:active{background:none;border:none;bottom:auto;clear:none;cursor:default;float:none;font-family:Arial,Helvetica,sans-serif;font-size:medium;font-style:normal;font-weight:400;height:auto;left:auto;letter-spacing:normal;line-height:normal;max-height:none;max-width:none;min-height:0;min-width:0;overflow:visible;position:static;right:auto;text-align:left;text-decoration:none;text-indent:0;text-transform:none;top:auto;visibility:visible;white-space:normal;width:auto;z-index:auto}#copyray-overlay{position:fixed;left:0;top:0;bottom:0;right:0;background-image:radial-gradient(ellipse farthest-corner at center,rgba(0,0,0,.4) 10%,rgba(0,0,0,.8) 100%);z-index:9000}.copyray-specimen{position:absolute;background:rgba(255,255,255,.15);outline:1px solid rgba(255,255,255,.8);outline-offset:-1px;color:#666;font-family:Helvetica Neue,sans-serif;font-size:13px;box-shadow:0 1px 3px #000000b3}.copyray-specimen:hover{cursor:pointer;background:rgba(255,255,255,.4)}.copyray-specimen.Specimen{outline:1px solid rgba(255,50,50,.8);background:rgba(255,50,50,.1)}.copyray-specimen.Specimen:hover{background:rgba(255,50,50,.4)}.copyray-specimen-handle{float:left;margin:0 2px 2px 0;background:#fff;padding:0 3px;color:#333;font-size:10px;cursor:pointer}.copyray-specimen-handle.Specimen{background:rgba(255,50,50,.8);color:#fff}a.copyray-toggle-button{display:block;position:fixed;left:0;bottom:0;color:#fff;background:black;padding:12px 16px;border-radius:0 10px 0 0;opacity:0;transition:opacity .6s ease-in-out;z-index:10000;font-size:12px;cursor:pointer}a.copyray-toggle-button:hover{opacity:1}#copy-tuner-bar{position:fixed;left:0;right:0;bottom:0;height:40px;padding:0 8px;background:#222;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;font-weight:200;color:#fff;z-index:2147483647;box-shadow:0 -1px #ffffff1a,inset 0 2px 6px #000c;background-image:linear-gradient(rgba(0,0,0,0),rgba(0,0,0,.3))}#copy-tuner-bar-log-menu{position:fixed;left:0;right:0;bottom:40px;max-height:calc(100vh - 40px);background:#222;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;color:#fff;z-index:2147483647;overflow-y:auto}#copy-tuner-bar-log-menu tbody td{padding:2px 8px}#copy-tuner-bar-log-menu tbody tr{cursor:pointer}#copy-tuner-bar-log-menu tbody tr:hover{background:#444}#copy-tuner-bar-log-menu tbody a{color:#fff}#copy-tuner-bar-log-menu tbody a:hover,#copy-tuner-bar-log-menu tbody a:focus{color:#fff;text-decoration:underline}.copy-tuner-bar-button{position:relative;display:inline-block;color:#fff;margin:8px 1px;height:24px;line-height:24px;padding:0 8px;font-size:14px;cursor:pointer;vertical-align:middle;background-color:#444;background-image:linear-gradient(rgba(0,0,0,0),rgba(0,0,0,.2));border-radius:2px;box-shadow:1px 1px 1px #00000080,inset 0 1px #fff3,inset 0 0 2px #fff3;text-shadow:0 -1px 0 rgba(0,0,0,.4)}.copy-tuner-bar-button:hover,.copy-tuner-bar-button:focus{color:#fff;text-decoration:none;background-color:#555}.copy-tuner-bar__notice{display:inline-block;margin:8px;font-size:13px;line-height:24px;vertical-align:middle;color:#ffd24d}input[type=text].copy-tuner-bar__search{-webkit-appearance:none;-moz-appearance:none;appearance:none;border:none;border-radius:2px;background-image:linear-gradient(rgba(0,0,0,.2),rgba(0,0,0,0));box-shadow:inset 0 1px #0003,inset 0 0 2px #0003;padding:2px 8px;margin:0;line-height:20px;vertical-align:middle;color:#000;width:auto;height:auto;font-size:14px}.copy-tuner-hidden{display:none!important}@media screen and (max-width: 480px){.hidden-on-mobile{display:none!important}}
|
data/src/copyray.ts
DELETED
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
import CopyTunerBar from './copytuner_bar'
|
|
2
|
-
import Specimen from './specimen'
|
|
3
|
-
|
|
4
|
-
const findBlurbs = () =>
|
|
5
|
-
Array.from(document.querySelectorAll('[data-copyray-key]')).map((element) => ({
|
|
6
|
-
// 1 要素に複数キーがカンマ区切りで入りうる(同一テキストノードに複数訳文が連結された場合)
|
|
7
|
-
keys: (element.getAttribute('data-copyray-key') ?? '').split(',').filter(Boolean),
|
|
8
|
-
element,
|
|
9
|
-
}))
|
|
10
|
-
|
|
11
|
-
export default class Copyray {
|
|
12
|
-
// @ts-expect-error TS7006
|
|
13
|
-
constructor(baseUrl, data, keysSkipped = false) {
|
|
14
|
-
// @ts-expect-error TS2339
|
|
15
|
-
this.baseUrl = baseUrl
|
|
16
|
-
// @ts-expect-error TS2339
|
|
17
|
-
this.data = data
|
|
18
|
-
// @ts-expect-error TS2339
|
|
19
|
-
this.isShowing = false
|
|
20
|
-
// @ts-expect-error TS2339
|
|
21
|
-
this.specimens = []
|
|
22
|
-
// @ts-expect-error TS2339
|
|
23
|
-
this.overlay = this.makeOverlay()
|
|
24
|
-
// @ts-expect-error TS2339
|
|
25
|
-
this.toggleButton = this.makeToggleButton()
|
|
26
|
-
// @ts-expect-error TS2339
|
|
27
|
-
this.boundOpen = this.open.bind(this)
|
|
28
|
-
|
|
29
|
-
// @ts-expect-error TS2339
|
|
30
|
-
this.copyTunerBar = new CopyTunerBar(document.querySelector('#copy-tuner-bar'), this.data, this.boundOpen, keysSkipped)
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
show() {
|
|
34
|
-
this.reset()
|
|
35
|
-
|
|
36
|
-
// @ts-expect-error TS2339
|
|
37
|
-
document.body.append(this.overlay)
|
|
38
|
-
this.makeSpecimens()
|
|
39
|
-
|
|
40
|
-
// @ts-expect-error TS2339
|
|
41
|
-
for (const specimen of this.specimens) {
|
|
42
|
-
specimen.show()
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// @ts-expect-error TS2339
|
|
46
|
-
this.copyTunerBar.show()
|
|
47
|
-
// @ts-expect-error TS2339
|
|
48
|
-
this.isShowing = true
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
hide() {
|
|
52
|
-
// @ts-expect-error TS2339
|
|
53
|
-
this.overlay.remove()
|
|
54
|
-
this.reset()
|
|
55
|
-
// @ts-expect-error TS2339
|
|
56
|
-
this.copyTunerBar.hide()
|
|
57
|
-
// @ts-expect-error TS2339
|
|
58
|
-
this.isShowing = false
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
toggle() {
|
|
62
|
-
// @ts-expect-error TS2339
|
|
63
|
-
if (this.isShowing) {
|
|
64
|
-
this.hide()
|
|
65
|
-
} else {
|
|
66
|
-
this.show()
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// @ts-expect-error TS7006
|
|
71
|
-
open(key) {
|
|
72
|
-
// @ts-expect-error TS2339
|
|
73
|
-
window.open(`${this.baseUrl}/blurbs/${key}/edit`)
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
makeSpecimens() {
|
|
77
|
-
for (const { element, keys } of findBlurbs()) {
|
|
78
|
-
// @ts-expect-error TS2339
|
|
79
|
-
this.specimens.push(new Specimen(element, keys, this.boundOpen))
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
makeToggleButton() {
|
|
84
|
-
const element = document.createElement('a')
|
|
85
|
-
|
|
86
|
-
element.addEventListener('click', () => {
|
|
87
|
-
this.show()
|
|
88
|
-
})
|
|
89
|
-
|
|
90
|
-
element.classList.add('copyray-toggle-button')
|
|
91
|
-
element.classList.add('hidden-on-mobile')
|
|
92
|
-
element.textContent = 'Open CopyTuner'
|
|
93
|
-
document.body.append(element)
|
|
94
|
-
|
|
95
|
-
return element
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
makeOverlay() {
|
|
99
|
-
const div = document.createElement('div')
|
|
100
|
-
div.setAttribute('id', 'copyray-overlay')
|
|
101
|
-
div.addEventListener('click', () => this.hide())
|
|
102
|
-
return div
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
reset() {
|
|
106
|
-
// @ts-expect-error TS2339
|
|
107
|
-
for (const specimen of this.specimens) {
|
|
108
|
-
specimen.remove()
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
}
|
data/src/copytuner_bar.ts
DELETED
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
// @ts-expect-error TS7016
|
|
2
|
-
import debounce from 'lodash.debounce'
|
|
3
|
-
|
|
4
|
-
const HIDDEN_CLASS = 'copy-tuner-hidden'
|
|
5
|
-
|
|
6
|
-
export default class CopytunerBar {
|
|
7
|
-
// @ts-expect-error TS7006
|
|
8
|
-
constructor(element, data, callback, keysSkipped = false) {
|
|
9
|
-
// @ts-expect-error TS2339
|
|
10
|
-
this.element = element
|
|
11
|
-
// @ts-expect-error TS2339
|
|
12
|
-
this.data = data
|
|
13
|
-
// @ts-expect-error TS2339
|
|
14
|
-
this.callback = callback
|
|
15
|
-
// @ts-expect-error TS2339
|
|
16
|
-
this.searchBoxElement = element.querySelector('.js-copy-tuner-bar-search')
|
|
17
|
-
// @ts-expect-error TS2339
|
|
18
|
-
this.logMenuElement = this.makeLogMenu()
|
|
19
|
-
// @ts-expect-error TS2339
|
|
20
|
-
this.element.append(this.logMenuElement)
|
|
21
|
-
|
|
22
|
-
// 巨大DOM/Nokogiri例外でキー付与がスキップされた場合は、オーバーレイが使えないので
|
|
23
|
-
// ツールバー(Translations in this page)から編集する旨を案内する。
|
|
24
|
-
if (keysSkipped) {
|
|
25
|
-
this.appendSkippedNotice()
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
this.addHandler()
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
appendSkippedNotice() {
|
|
32
|
-
const notice = document.createElement('span')
|
|
33
|
-
notice.classList.add('copy-tuner-bar__notice')
|
|
34
|
-
notice.textContent = '⚠ This page is too large for the overlay. Use "Translations in this page" to edit.'
|
|
35
|
-
// @ts-expect-error TS2339
|
|
36
|
-
this.element.append(notice)
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
addHandler() {
|
|
40
|
-
// @ts-expect-error TS2339
|
|
41
|
-
const openLogButton = this.element.querySelector('.js-copy-tuner-bar-open-log')
|
|
42
|
-
// @ts-expect-error TS7006
|
|
43
|
-
openLogButton.addEventListener('click', (event) => {
|
|
44
|
-
event.preventDefault()
|
|
45
|
-
this.toggleLogMenu()
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
// @ts-expect-error TS2339
|
|
49
|
-
this.searchBoxElement.addEventListener('input', debounce(this.onKeyup.bind(this), 250))
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
show() {
|
|
53
|
-
// @ts-expect-error TS2339
|
|
54
|
-
this.element.classList.remove(HIDDEN_CLASS)
|
|
55
|
-
// @ts-expect-error TS2339
|
|
56
|
-
this.searchBoxElement.focus()
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
hide() {
|
|
60
|
-
// @ts-expect-error TS2339
|
|
61
|
-
this.element.classList.add(HIDDEN_CLASS)
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
showLogMenu() {
|
|
65
|
-
// @ts-expect-error TS2339
|
|
66
|
-
this.logMenuElement.classList.remove(HIDDEN_CLASS)
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
toggleLogMenu() {
|
|
70
|
-
// @ts-expect-error TS2339
|
|
71
|
-
this.logMenuElement.classList.toggle(HIDDEN_CLASS)
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
makeLogMenu() {
|
|
75
|
-
const div = document.createElement('div')
|
|
76
|
-
div.setAttribute('id', 'copy-tuner-bar-log-menu')
|
|
77
|
-
div.classList.add(HIDDEN_CLASS)
|
|
78
|
-
|
|
79
|
-
const table = document.createElement('table')
|
|
80
|
-
const tbody = document.createElement('tbody')
|
|
81
|
-
tbody.classList.remove('is-not-initialized')
|
|
82
|
-
|
|
83
|
-
// @ts-expect-error TS2339
|
|
84
|
-
for (const key of Object.keys(this.data).sort()) {
|
|
85
|
-
// @ts-expect-error TS2339
|
|
86
|
-
const value = this.data[key]
|
|
87
|
-
|
|
88
|
-
if (value === '') {
|
|
89
|
-
continue
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
const td1 = document.createElement('td')
|
|
93
|
-
td1.textContent = key
|
|
94
|
-
const td2 = document.createElement('td')
|
|
95
|
-
td2.textContent = value
|
|
96
|
-
const tr = document.createElement('tr')
|
|
97
|
-
tr.classList.add('copy-tuner-bar-log-menu__row')
|
|
98
|
-
tr.dataset.key = key
|
|
99
|
-
|
|
100
|
-
tr.addEventListener('click', ({ currentTarget }) => {
|
|
101
|
-
// @ts-expect-error TS2339
|
|
102
|
-
this.callback(currentTarget.dataset.key)
|
|
103
|
-
})
|
|
104
|
-
|
|
105
|
-
tr.append(td1)
|
|
106
|
-
tr.append(td2)
|
|
107
|
-
tbody.append(tr)
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
table.append(tbody)
|
|
111
|
-
div.append(table)
|
|
112
|
-
|
|
113
|
-
return div
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// @ts-expect-error TS7031
|
|
117
|
-
onKeyup({ target }) {
|
|
118
|
-
const keyword = target.value.trim()
|
|
119
|
-
this.showLogMenu()
|
|
120
|
-
|
|
121
|
-
// @ts-expect-error TS2339
|
|
122
|
-
const rows = [...this.logMenuElement.querySelectorAll('tr')]
|
|
123
|
-
|
|
124
|
-
for (const row of rows) {
|
|
125
|
-
const isShow = keyword === '' || [...row.querySelectorAll('td')].some((td) => td.textContent.includes(keyword))
|
|
126
|
-
row.classList.toggle(HIDDEN_CLASS, !isShow)
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
}
|
data/src/specimen.ts
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import { computeBoundingBox } from './util'
|
|
2
|
-
|
|
3
|
-
const ZINDEX = 2_000_000_000
|
|
4
|
-
|
|
5
|
-
export default class Specimen {
|
|
6
|
-
// @ts-expect-error TS7006
|
|
7
|
-
constructor(element, keys, callback) {
|
|
8
|
-
// @ts-expect-error TS2339
|
|
9
|
-
this.element = element
|
|
10
|
-
// @ts-expect-error TS2339
|
|
11
|
-
this.keys = keys
|
|
12
|
-
// @ts-expect-error TS2339
|
|
13
|
-
this.callback = callback
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
show() {
|
|
17
|
-
// @ts-expect-error TS2339
|
|
18
|
-
this.box = this.makeBox()
|
|
19
|
-
// @ts-expect-error TS2339
|
|
20
|
-
if (this.box === null) return
|
|
21
|
-
|
|
22
|
-
// box 全体のクリックは先頭キーを開く(広いクリック領域を維持)。複数キー時は各ラベルから個別に開ける
|
|
23
|
-
// @ts-expect-error TS2339
|
|
24
|
-
this.box.addEventListener('click', () => {
|
|
25
|
-
// @ts-expect-error TS2339
|
|
26
|
-
this.callback(this.keys[0])
|
|
27
|
-
})
|
|
28
|
-
|
|
29
|
-
// @ts-expect-error TS2339
|
|
30
|
-
document.body.append(this.box)
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
remove() {
|
|
34
|
-
// @ts-expect-error TS2339
|
|
35
|
-
if (!this.box) {
|
|
36
|
-
return
|
|
37
|
-
}
|
|
38
|
-
// @ts-expect-error TS2339
|
|
39
|
-
this.box.remove()
|
|
40
|
-
// @ts-expect-error TS2339
|
|
41
|
-
this.box = null
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
makeBox() {
|
|
45
|
-
const box = document.createElement('div')
|
|
46
|
-
box.classList.add('copyray-specimen')
|
|
47
|
-
box.classList.add('Specimen')
|
|
48
|
-
|
|
49
|
-
// @ts-expect-error TS2339
|
|
50
|
-
const bounds = computeBoundingBox(this.element)
|
|
51
|
-
if (bounds === null) return null
|
|
52
|
-
|
|
53
|
-
for (const key of Object.keys(bounds)) {
|
|
54
|
-
// @ts-expect-error TS7053
|
|
55
|
-
const value = bounds[key]
|
|
56
|
-
// @ts-expect-error TS7015
|
|
57
|
-
box.style[key] = `${value}px`
|
|
58
|
-
}
|
|
59
|
-
// @ts-expect-error TS2322
|
|
60
|
-
box.style.zIndex = ZINDEX
|
|
61
|
-
|
|
62
|
-
// @ts-expect-error TS2339
|
|
63
|
-
const { position, top, left } = getComputedStyle(this.element)
|
|
64
|
-
if (position === 'fixed') {
|
|
65
|
-
// @ts-expect-error TS2339
|
|
66
|
-
this.box.style.position = 'fixed'
|
|
67
|
-
// @ts-expect-error TS2339
|
|
68
|
-
this.box.style.top = `${top}px`
|
|
69
|
-
// @ts-expect-error TS2339
|
|
70
|
-
this.box.style.left = `${left}px`
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// @ts-expect-error TS2339
|
|
74
|
-
for (const key of this.keys) {
|
|
75
|
-
box.append(this.makeLabel(key))
|
|
76
|
-
}
|
|
77
|
-
return box
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// @ts-expect-error TS7006
|
|
81
|
-
makeLabel(key) {
|
|
82
|
-
const div = document.createElement('div')
|
|
83
|
-
div.classList.add('copyray-specimen-handle')
|
|
84
|
-
div.classList.add('Specimen')
|
|
85
|
-
div.textContent = key
|
|
86
|
-
// ラベルのクリックはそのキーを開く。box への伝播を止めて先頭キーとの二重発火を防ぐ
|
|
87
|
-
div.addEventListener('click', (event) => {
|
|
88
|
-
event.stopPropagation()
|
|
89
|
-
// @ts-expect-error TS2339
|
|
90
|
-
this.callback(key)
|
|
91
|
-
})
|
|
92
|
-
return div
|
|
93
|
-
}
|
|
94
|
-
}
|