copy_tuner_client 0.12.0 → 0.13.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.
@@ -0,0 +1,388 @@
1
+ var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
2
+ var FUNC_ERROR_TEXT = "Expected a function";
3
+ var NAN = 0 / 0;
4
+ var symbolTag = "[object Symbol]";
5
+ var reTrim = /^\s+|\s+$/g;
6
+ var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
7
+ var reIsBinary = /^0b[01]+$/i;
8
+ var reIsOctal = /^0o[0-7]+$/i;
9
+ var freeParseInt = parseInt;
10
+ var freeGlobal = typeof commonjsGlobal == "object" && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;
11
+ var freeSelf = typeof self == "object" && self && self.Object === Object && self;
12
+ var root = freeGlobal || freeSelf || Function("return this")();
13
+ var objectProto = Object.prototype;
14
+ var objectToString = objectProto.toString;
15
+ var nativeMax = Math.max, nativeMin = Math.min;
16
+ var now = function() {
17
+ return root.Date.now();
18
+ };
19
+ function debounce(func, wait, options) {
20
+ var lastArgs, lastThis, maxWait, result, timerId, lastCallTime, lastInvokeTime = 0, leading = false, maxing = false, trailing = true;
21
+ if (typeof func != "function") {
22
+ throw new TypeError(FUNC_ERROR_TEXT);
23
+ }
24
+ wait = toNumber(wait) || 0;
25
+ if (isObject(options)) {
26
+ leading = !!options.leading;
27
+ maxing = "maxWait" in options;
28
+ maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
29
+ trailing = "trailing" in options ? !!options.trailing : trailing;
30
+ }
31
+ function invokeFunc(time) {
32
+ var args = lastArgs, thisArg = lastThis;
33
+ lastArgs = lastThis = void 0;
34
+ lastInvokeTime = time;
35
+ result = func.apply(thisArg, args);
36
+ return result;
37
+ }
38
+ function leadingEdge(time) {
39
+ lastInvokeTime = time;
40
+ timerId = setTimeout(timerExpired, wait);
41
+ return leading ? invokeFunc(time) : result;
42
+ }
43
+ function remainingWait(time) {
44
+ var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime, result2 = wait - timeSinceLastCall;
45
+ return maxing ? nativeMin(result2, maxWait - timeSinceLastInvoke) : result2;
46
+ }
47
+ function shouldInvoke(time) {
48
+ var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime;
49
+ return lastCallTime === void 0 || timeSinceLastCall >= wait || timeSinceLastCall < 0 || maxing && timeSinceLastInvoke >= maxWait;
50
+ }
51
+ function timerExpired() {
52
+ var time = now();
53
+ if (shouldInvoke(time)) {
54
+ return trailingEdge(time);
55
+ }
56
+ timerId = setTimeout(timerExpired, remainingWait(time));
57
+ }
58
+ function trailingEdge(time) {
59
+ timerId = void 0;
60
+ if (trailing && lastArgs) {
61
+ return invokeFunc(time);
62
+ }
63
+ lastArgs = lastThis = void 0;
64
+ return result;
65
+ }
66
+ function cancel() {
67
+ if (timerId !== void 0) {
68
+ clearTimeout(timerId);
69
+ }
70
+ lastInvokeTime = 0;
71
+ lastArgs = lastCallTime = lastThis = timerId = void 0;
72
+ }
73
+ function flush() {
74
+ return timerId === void 0 ? result : trailingEdge(now());
75
+ }
76
+ function debounced() {
77
+ var time = now(), isInvoking = shouldInvoke(time);
78
+ lastArgs = arguments;
79
+ lastThis = this;
80
+ lastCallTime = time;
81
+ if (isInvoking) {
82
+ if (timerId === void 0) {
83
+ return leadingEdge(lastCallTime);
84
+ }
85
+ if (maxing) {
86
+ timerId = setTimeout(timerExpired, wait);
87
+ return invokeFunc(lastCallTime);
88
+ }
89
+ }
90
+ if (timerId === void 0) {
91
+ timerId = setTimeout(timerExpired, wait);
92
+ }
93
+ return result;
94
+ }
95
+ debounced.cancel = cancel;
96
+ debounced.flush = flush;
97
+ return debounced;
98
+ }
99
+ function isObject(value) {
100
+ var type = typeof value;
101
+ return !!value && (type == "object" || type == "function");
102
+ }
103
+ function isObjectLike(value) {
104
+ return !!value && typeof value == "object";
105
+ }
106
+ function isSymbol(value) {
107
+ return typeof value == "symbol" || isObjectLike(value) && objectToString.call(value) == symbolTag;
108
+ }
109
+ function toNumber(value) {
110
+ if (typeof value == "number") {
111
+ return value;
112
+ }
113
+ if (isSymbol(value)) {
114
+ return NAN;
115
+ }
116
+ if (isObject(value)) {
117
+ var other = typeof value.valueOf == "function" ? value.valueOf() : value;
118
+ value = isObject(other) ? other + "" : other;
119
+ }
120
+ if (typeof value != "string") {
121
+ return value === 0 ? value : +value;
122
+ }
123
+ value = value.replace(reTrim, "");
124
+ var isBinary = reIsBinary.test(value);
125
+ return isBinary || reIsOctal.test(value) ? freeParseInt(value.slice(2), isBinary ? 2 : 8) : reIsBadHex.test(value) ? NAN : +value;
126
+ }
127
+ var lodash_debounce = debounce;
128
+ const HIDDEN_CLASS = "copy-tuner-hidden";
129
+ class CopytunerBar {
130
+ constructor(element, data, callback) {
131
+ this.element = element;
132
+ this.data = data;
133
+ this.callback = callback;
134
+ this.searchBoxElement = element.querySelector(".js-copy-tuner-bar-search");
135
+ this.logMenuElement = this.makeLogMenu();
136
+ this.element.append(this.logMenuElement);
137
+ this.addHandler();
138
+ }
139
+ addHandler() {
140
+ const openLogButton = this.element.querySelector(".js-copy-tuner-bar-open-log");
141
+ openLogButton.addEventListener("click", (event) => {
142
+ event.preventDefault();
143
+ this.toggleLogMenu();
144
+ });
145
+ this.searchBoxElement.addEventListener("input", lodash_debounce(this.onKeyup.bind(this), 250));
146
+ }
147
+ show() {
148
+ this.element.classList.remove(HIDDEN_CLASS);
149
+ this.searchBoxElement.focus();
150
+ }
151
+ hide() {
152
+ this.element.classList.add(HIDDEN_CLASS);
153
+ }
154
+ showLogMenu() {
155
+ this.logMenuElement.classList.remove(HIDDEN_CLASS);
156
+ }
157
+ toggleLogMenu() {
158
+ this.logMenuElement.classList.toggle(HIDDEN_CLASS);
159
+ }
160
+ makeLogMenu() {
161
+ const div = document.createElement("div");
162
+ div.setAttribute("id", "copy-tuner-bar-log-menu");
163
+ div.classList.add(HIDDEN_CLASS);
164
+ const table = document.createElement("table");
165
+ const tbody = document.createElement("tbody");
166
+ tbody.classList.remove("is-not-initialized");
167
+ for (const key of Object.keys(this.data).sort()) {
168
+ const value = this.data[key];
169
+ if (value === "") {
170
+ continue;
171
+ }
172
+ const td1 = document.createElement("td");
173
+ td1.textContent = key;
174
+ const td2 = document.createElement("td");
175
+ td2.textContent = value;
176
+ const tr = document.createElement("tr");
177
+ tr.classList.add("copy-tuner-bar-log-menu__row");
178
+ tr.dataset.key = key;
179
+ tr.addEventListener("click", ({ currentTarget }) => {
180
+ this.callback(currentTarget.dataset.key);
181
+ });
182
+ tr.append(td1);
183
+ tr.append(td2);
184
+ tbody.append(tr);
185
+ }
186
+ table.append(tbody);
187
+ div.append(table);
188
+ return div;
189
+ }
190
+ onKeyup({ target }) {
191
+ const keyword = target.value.trim();
192
+ this.showLogMenu();
193
+ const rows = [...this.logMenuElement.querySelectorAll("tr")];
194
+ for (const row of rows) {
195
+ const isShow = keyword === "" || [...row.querySelectorAll("td")].some((td) => td.textContent.includes(keyword));
196
+ row.classList.toggle(HIDDEN_CLASS, !isShow);
197
+ }
198
+ }
199
+ }
200
+ const isMac = navigator.platform.toUpperCase().includes("MAC");
201
+ const isVisible = (element) => !!(element.offsetWidth || element.offsetHeight || element.getClientRects().length > 0);
202
+ const getOffset = (elment) => {
203
+ const box = elment.getBoundingClientRect();
204
+ return {
205
+ top: box.top + (window.pageYOffset - document.documentElement.clientTop),
206
+ left: box.left + (window.pageXOffset - document.documentElement.clientLeft)
207
+ };
208
+ };
209
+ const computeBoundingBox = (element) => {
210
+ if (!isVisible(element)) {
211
+ return null;
212
+ }
213
+ const boxFrame = getOffset(element);
214
+ boxFrame.right = boxFrame.left + element.offsetWidth;
215
+ boxFrame.bottom = boxFrame.top + element.offsetHeight;
216
+ return {
217
+ left: boxFrame.left,
218
+ top: boxFrame.top,
219
+ width: boxFrame.right - boxFrame.left,
220
+ height: boxFrame.bottom - boxFrame.top
221
+ };
222
+ };
223
+ const ZINDEX = 2e9;
224
+ class Specimen {
225
+ constructor(element, key, callback) {
226
+ this.element = element;
227
+ this.key = key;
228
+ this.callback = callback;
229
+ }
230
+ show() {
231
+ this.box = this.makeBox();
232
+ if (this.box === null)
233
+ return;
234
+ this.box.addEventListener("click", () => {
235
+ this.callback(this.key);
236
+ });
237
+ document.body.append(this.box);
238
+ }
239
+ remove() {
240
+ if (!this.box) {
241
+ return;
242
+ }
243
+ this.box.remove();
244
+ this.box = null;
245
+ }
246
+ makeBox() {
247
+ const box = document.createElement("div");
248
+ box.classList.add("copyray-specimen");
249
+ box.classList.add("Specimen");
250
+ const bounds = computeBoundingBox(this.element);
251
+ if (bounds === null)
252
+ return null;
253
+ for (const key of Object.keys(bounds)) {
254
+ const value = bounds[key];
255
+ box.style[key] = `${value}px`;
256
+ }
257
+ box.style.zIndex = ZINDEX;
258
+ const { position, top, left } = getComputedStyle(this.element);
259
+ if (position === "fixed") {
260
+ this.box.style.position = "fixed";
261
+ this.box.style.top = `${top}px`;
262
+ this.box.style.left = `${left}px`;
263
+ }
264
+ box.append(this.makeLabel());
265
+ return box;
266
+ }
267
+ makeLabel() {
268
+ const div = document.createElement("div");
269
+ div.classList.add("copyray-specimen-handle");
270
+ div.classList.add("Specimen");
271
+ div.textContent = this.key;
272
+ return div;
273
+ }
274
+ }
275
+ const findBlurbs = () => {
276
+ const filterNone = () => NodeFilter.FILTER_ACCEPT;
277
+ const iterator = document.createNodeIterator(document.body, NodeFilter.SHOW_COMMENT, filterNone, false);
278
+ const comments = [];
279
+ let curNode;
280
+ while (curNode = iterator.nextNode()) {
281
+ comments.push(curNode);
282
+ }
283
+ return comments.filter((comment) => comment.nodeValue.startsWith("COPYRAY")).map((comment) => {
284
+ const [, key] = comment.nodeValue.match(/^COPYRAY (\S*)$/);
285
+ const element = comment.parentNode;
286
+ return { key, element };
287
+ });
288
+ };
289
+ class Copyray {
290
+ constructor(baseUrl, data) {
291
+ this.baseUrl = baseUrl;
292
+ this.data = data;
293
+ this.isShowing = false;
294
+ this.specimens = [];
295
+ this.overlay = this.makeOverlay();
296
+ this.toggleButton = this.makeToggleButton();
297
+ this.boundOpen = this.open.bind(this);
298
+ this.copyTunerBar = new CopytunerBar(document.querySelector("#copy-tuner-bar"), this.data, this.boundOpen);
299
+ }
300
+ show() {
301
+ this.reset();
302
+ document.body.append(this.overlay);
303
+ this.makeSpecimens();
304
+ for (const specimen of this.specimens) {
305
+ specimen.show();
306
+ }
307
+ this.copyTunerBar.show();
308
+ this.isShowing = true;
309
+ }
310
+ hide() {
311
+ this.overlay.remove();
312
+ this.reset();
313
+ this.copyTunerBar.hide();
314
+ this.isShowing = false;
315
+ }
316
+ toggle() {
317
+ if (this.isShowing) {
318
+ this.hide();
319
+ } else {
320
+ this.show();
321
+ }
322
+ }
323
+ open(key) {
324
+ window.open(`${this.baseUrl}/blurbs/${key}/edit`);
325
+ }
326
+ makeSpecimens() {
327
+ for (const { element, key } of findBlurbs()) {
328
+ this.specimens.push(new Specimen(element, key, this.boundOpen));
329
+ }
330
+ }
331
+ makeToggleButton() {
332
+ const element = document.createElement("a");
333
+ element.addEventListener("click", () => {
334
+ this.show();
335
+ });
336
+ element.classList.add("copyray-toggle-button");
337
+ element.classList.add("hidden-on-mobile");
338
+ element.textContent = "Open CopyTuner";
339
+ document.body.append(element);
340
+ return element;
341
+ }
342
+ makeOverlay() {
343
+ const div = document.createElement("div");
344
+ div.setAttribute("id", "copyray-overlay");
345
+ div.addEventListener("click", () => this.hide());
346
+ return div;
347
+ }
348
+ reset() {
349
+ for (const specimen of this.specimens) {
350
+ specimen.remove();
351
+ }
352
+ }
353
+ }
354
+ var copyray = "";
355
+ const appendCopyTunerBar = (url) => {
356
+ const bar = document.createElement("div");
357
+ bar.id = "copy-tuner-bar";
358
+ bar.classList.add("copy-tuner-hidden");
359
+ bar.innerHTML = `
360
+ <a class="copy-tuner-bar-button" target="_blank" href="${url}">CopyTuner</a>
361
+ <a href="/copytuner" target="_blank" class="copy-tuner-bar-button">Sync</a>
362
+ <a href="javascript:void(0)" class="copy-tuner-bar-open-log copy-tuner-bar-button js-copy-tuner-bar-open-log">Translations in this page</a>
363
+ <input type="text" class="copy-tuner-bar__search js-copy-tuner-bar-search" placeholder="search">
364
+ `;
365
+ document.body.append(bar);
366
+ };
367
+ const start = () => {
368
+ const { url, data } = window.CopyTuner;
369
+ appendCopyTunerBar(url);
370
+ const copyray2 = new Copyray(url, data);
371
+ document.addEventListener("keydown", (event) => {
372
+ if (copyray2.isShowing && ["Escape", "Esc"].includes(event.key)) {
373
+ copyray2.hide();
374
+ return;
375
+ }
376
+ if ((isMac && event.metaKey || !isMac && event.ctrlKey) && event.shiftKey && event.key === "k") {
377
+ copyray2.toggle();
378
+ }
379
+ });
380
+ if (console) {
381
+ console.log(`Ready to Copyray. Press ${isMac ? "cmd+shift+k" : "ctrl+shift+k"} to scan your UI.`);
382
+ }
383
+ };
384
+ if (document.readyState === "complete" || document.readyState !== "loading") {
385
+ start();
386
+ } else {
387
+ document.addEventListener("DOMContentLoaded", () => start());
388
+ }
@@ -0,0 +1 @@
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;background:#fff;padding:0 3px;color:#333;font-size:10px}.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}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}}
@@ -3,7 +3,7 @@ $LOAD_PATH.push File.expand_path('../lib', __FILE__)
3
3
  require 'copy_tuner_client/version'
4
4
 
5
5
  Gem::Specification.new do |s|
6
- s.required_ruby_version = '>= 2.5.0'
6
+ s.required_ruby_version = '>= 2.7.0'
7
7
  s.add_dependency 'i18n', '>= 0.5.0'
8
8
  s.add_dependency 'json'
9
9
  s.add_dependency 'nokogiri'
@@ -1,5 +1,5 @@
1
1
  source "http://rubygems.org"
2
2
 
3
- gem "rails", "~> 5.2"
3
+ gem "rails", "~> 7.0"
4
4
 
5
5
  gemspec :path => "../"
data/index.html ADDED
@@ -0,0 +1,34 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8" />
6
+ <link rel="icon" type="image/svg+xml" href="/src/favicon.svg" />
7
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
8
+ <title>Vite App</title>
9
+ </head>
10
+
11
+ <body>
12
+ <div id="app">
13
+ <ul>
14
+ <li>
15
+ <!--COPYRAY projects.index.locales-->言語
16
+ </li>
17
+ <li>
18
+ <!--COPYRAY projects.index.blurbs-->翻訳キー
19
+ </li>
20
+ <li>
21
+ <!--COPYRAY projects.index.members-->メンバー数
22
+ </li>
23
+ </ul>
24
+ </div>
25
+ <script>
26
+ window.CopyTuner = {
27
+ url: 'https://copy-tuner.herokuapp.com/projects/xxx',
28
+ data: {},
29
+ }
30
+ </script>
31
+ <script type="module" src="/src/main.ts"></script>
32
+ </body>
33
+
34
+ </html>
@@ -12,8 +12,6 @@ module CopyTunerClient
12
12
  if html_headers?(status, headers) && body = response_body(response)
13
13
  body = append_css(body)
14
14
  body = append_js(body)
15
- body = append_translation_logs(body)
16
- body = inject_copy_tuner_bar(body)
17
15
  content_length = body.bytesize.to_s
18
16
  headers['Content-Length'] = content_length
19
17
  # maintains compatibility with other middlewares
@@ -33,41 +31,29 @@ module CopyTunerClient
33
31
  ActionController::Base.helpers
34
32
  end
35
33
 
36
- def append_translation_logs(html)
37
- if CopyTunerClient::TranslationLog.initialized?
38
- json = CopyTunerClient::TranslationLog.translations.to_json
39
- # Use block to avoid back reference \?
40
- append_to_html_body(html, "<div id='copy-tuner-data' data-copy-tuner-translation-log='#{ERB::Util.html_escape json}' data-copy-tuner-url='#{CopyTunerClient.configuration.project_url}'></div>")
41
- else
42
- html
43
- end
44
- end
45
-
46
- def inject_copy_tuner_bar(html)
47
- append_to_html_body(html, render_copy_tuner_bar)
48
- end
49
-
50
- def render_copy_tuner_bar
51
- if ApplicationController.respond_to?(:render)
52
- # Rails 5
53
- ApplicationController.render(:partial => "/copy_tuner_bar").html_safe
54
- else
55
- # Rails <= 4.2
56
- ac = ActionController::Base.new
57
- ac.render_to_string(:partial => '/copy_tuner_bar').html_safe
58
- end
59
- end
60
-
61
34
  def append_css(html)
62
35
  append_to_html_body(html, css_tag)
63
36
  end
64
37
 
65
38
  def append_js(html)
66
- append_to_html_body(html, helpers.javascript_include_tag(:copyray))
39
+ json =
40
+ if CopyTunerClient::TranslationLog.initialized?
41
+ CopyTunerClient::TranslationLog.translations.to_json
42
+ else
43
+ '{}'
44
+ end
45
+
46
+ append_to_html_body(html, helpers.javascript_tag(<<~SCRIPT))
47
+ window.CopyTuner = {
48
+ url: '#{CopyTunerClient.configuration.project_url}',
49
+ data: #{json},
50
+ }
51
+ SCRIPT
52
+ append_to_html_body(html, helpers.javascript_include_tag(:main))
67
53
  end
68
54
 
69
55
  def css_tag
70
- helpers.stylesheet_link_tag :copyray, media: :all
56
+ helpers.stylesheet_link_tag :style, media: :screen
71
57
  end
72
58
 
73
59
  def append_to_html_body(html, content)
@@ -12,7 +12,7 @@ module CopyTunerClient
12
12
  initializer :initialize_copy_tuner_hook_methods, :after => :load_config_initializers do |app|
13
13
  ActiveSupport.on_load(:action_view) do
14
14
  CopyTunerClient::HelperExtension.hook_translation_helper(
15
- ActionView::Helpers::TranslationHelper,
15
+ ActionView::Helpers::TranslationHelper,
16
16
  middleware_enabled: CopyTunerClient.configuration.enable_middleware?
17
17
  )
18
18
  end
@@ -25,7 +25,7 @@ module CopyTunerClient
25
25
  end
26
26
 
27
27
  initializer "copy_tuner.assets.precompile", group: :all do |app|
28
- app.config.assets.precompile += ["copyray.js", "copyray.css"]
28
+ app.config.assets.precompile += ['main.js', 'style.css']
29
29
  end
30
30
  end
31
31
  end
@@ -1,6 +1,6 @@
1
1
  module CopyTunerClient
2
2
  # Client version
3
- VERSION = '0.12.0'.freeze
3
+ VERSION = '0.13.0'.freeze
4
4
 
5
5
  # API version being used to communicate with the server
6
6
  API_VERSION = '2.0'.freeze
data/package.json CHANGED
@@ -5,26 +5,25 @@
5
5
  "author": "SonicGarden",
6
6
  "license": "MIT",
7
7
  "engines": {
8
- "node": "8.x"
8
+ "node": "16.x"
9
9
  },
10
10
  "scripts": {
11
- "build": "rollup -c",
12
- "watch": "rollup -c -w"
11
+ "dev": "vite",
12
+ "build": "tsc && vite build",
13
+ "preview": "vite preview"
13
14
  },
14
15
  "dependencies": {},
15
16
  "devDependencies": {
16
- "babel-core": "^6.26.3",
17
- "babel-plugin-external-helpers": "^6.22.0",
18
- "babel-preset-env": "^1.7.0",
19
- "eslint": "^4.19.1",
20
- "eslint-config-airbnb-base": "^13.0.0",
21
- "eslint-plugin-import": "^2.13.0",
22
- "keycode-js": "^1.0.0",
17
+ "@sonicgarden/eslint-plugin": "^0.4.11",
18
+ "@sonicgarden/prettier-config": "^0.0.1",
19
+ "eslint": "^8.16.0",
23
20
  "lodash.debounce": "^4.0.8",
24
- "rollup": "^0.62.0",
25
- "rollup-plugin-babel": "^3.0.7",
26
- "rollup-plugin-commonjs": "^9.1.3",
27
- "rollup-plugin-node-resolve": "^3.3.0",
28
- "rollup-watch": "^4.3.1"
21
+ "typescript": "^4.7.2",
22
+ "vite": "^2.9.9"
23
+ },
24
+ "prettier": "@sonicgarden/prettier-config",
25
+ "volta": {
26
+ "node": "16.15.0",
27
+ "yarn": "1.22.18"
29
28
  }
30
29
  }
@@ -39,7 +39,9 @@ describe CopyTunerClient::I18nBackend do
39
39
  end
40
40
 
41
41
  it "finds available locales from locale files and cache" do
42
+ # TODO: ruby@2.7サポート終わったらこっちは不要
42
43
  allow(YAML).to receive(:load_file).and_return({ 'es' => { 'key' => 'value' } })
44
+ allow(YAML).to receive(:unsafe_load_file).and_return({ 'es' => { 'key' => 'value' } })
43
45
  allow(I18n).to receive(:load_path).and_return(["test.yml"])
44
46
 
45
47
  cache['en.key'] = ''
File without changes