copy_tuner_client 0.12.0 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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