phraseapp-in-context-editor-ruby 2.0.0 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +18 -0
  3. data/.github/workflows/close_inactive_issues.yml +18 -0
  4. data/.github/workflows/release.yml +28 -0
  5. data/.github/workflows/test.yml +6 -3
  6. data/.gitignore +1 -0
  7. data/CHANGELOG.md +22 -87
  8. data/CODEOWNERS +1 -1
  9. data/Gemfile.lock +4 -1
  10. data/RELEASING.md +2 -9
  11. data/docs/CHANGELOG.md +116 -0
  12. data/examples/demo/.gitattributes +7 -0
  13. data/examples/demo/.gitignore +35 -0
  14. data/examples/demo/Gemfile +74 -0
  15. data/examples/demo/Gemfile.lock +268 -0
  16. data/examples/demo/README.md +5 -0
  17. data/examples/demo/Rakefile +6 -0
  18. data/examples/demo/app/assets/config/manifest.js +4 -0
  19. data/examples/demo/app/assets/images/.keep +0 -0
  20. data/examples/demo/app/assets/stylesheets/application.css +15 -0
  21. data/examples/demo/app/channels/application_cable/channel.rb +4 -0
  22. data/examples/demo/app/channels/application_cable/connection.rb +4 -0
  23. data/examples/demo/app/controllers/application_controller.rb +2 -0
  24. data/examples/demo/app/controllers/concerns/.keep +0 -0
  25. data/examples/demo/app/controllers/main_controller.rb +4 -0
  26. data/examples/demo/app/helpers/application_helper.rb +2 -0
  27. data/examples/demo/app/helpers/main_helper.rb +2 -0
  28. data/examples/demo/app/javascript/application.js +3 -0
  29. data/examples/demo/app/javascript/controllers/application.js +9 -0
  30. data/examples/demo/app/javascript/controllers/hello_controller.js +7 -0
  31. data/examples/demo/app/javascript/controllers/index.js +11 -0
  32. data/examples/demo/app/jobs/application_job.rb +7 -0
  33. data/examples/demo/app/mailers/application_mailer.rb +4 -0
  34. data/examples/demo/app/models/application_record.rb +3 -0
  35. data/examples/demo/app/models/concerns/.keep +0 -0
  36. data/examples/demo/app/views/layouts/application.html.erb +17 -0
  37. data/examples/demo/app/views/layouts/mailer.html.erb +13 -0
  38. data/examples/demo/app/views/layouts/mailer.text.erb +1 -0
  39. data/examples/demo/app/views/main/index.html.erb +8 -0
  40. data/examples/demo/bin/bundle +109 -0
  41. data/examples/demo/bin/importmap +4 -0
  42. data/examples/demo/bin/rails +4 -0
  43. data/examples/demo/bin/rake +4 -0
  44. data/examples/demo/bin/setup +33 -0
  45. data/examples/demo/config/application.rb +22 -0
  46. data/examples/demo/config/boot.rb +4 -0
  47. data/examples/demo/config/cable.yml +10 -0
  48. data/examples/demo/config/credentials.yml.enc +1 -0
  49. data/examples/demo/config/database.yml +25 -0
  50. data/examples/demo/config/environment.rb +5 -0
  51. data/examples/demo/config/environments/development.rb +70 -0
  52. data/examples/demo/config/environments/production.rb +93 -0
  53. data/examples/demo/config/environments/test.rb +60 -0
  54. data/examples/demo/config/importmap.rb +7 -0
  55. data/examples/demo/config/initializers/assets.rb +12 -0
  56. data/examples/demo/config/initializers/content_security_policy.rb +25 -0
  57. data/examples/demo/config/initializers/filter_parameter_logging.rb +8 -0
  58. data/examples/demo/config/initializers/inflections.rb +16 -0
  59. data/examples/demo/config/initializers/permissions_policy.rb +11 -0
  60. data/examples/demo/config/initializers/phraseapp_in_context_editor.rb +20 -0
  61. data/examples/demo/config/locales/en.yml +38 -0
  62. data/examples/demo/config/puma.rb +43 -0
  63. data/examples/demo/config/routes.rb +6 -0
  64. data/examples/demo/config/storage.yml +34 -0
  65. data/examples/demo/config.ru +6 -0
  66. data/examples/demo/db/seeds.rb +7 -0
  67. data/examples/demo/lib/assets/.keep +0 -0
  68. data/examples/demo/lib/tasks/.keep +0 -0
  69. data/examples/demo/log/.keep +0 -0
  70. data/examples/demo/public/404.html +67 -0
  71. data/examples/demo/public/422.html +67 -0
  72. data/examples/demo/public/500.html +66 -0
  73. data/examples/demo/public/apple-touch-icon-precomposed.png +0 -0
  74. data/examples/demo/public/apple-touch-icon.png +0 -0
  75. data/examples/demo/public/favicon.ico +0 -0
  76. data/examples/demo/public/robots.txt +1 -0
  77. data/examples/demo/storage/.keep +0 -0
  78. data/examples/demo/test/application_system_test_case.rb +5 -0
  79. data/examples/demo/test/channels/application_cable/connection_test.rb +11 -0
  80. data/examples/demo/test/controllers/.keep +0 -0
  81. data/examples/demo/test/controllers/main_controller_test.rb +8 -0
  82. data/examples/demo/test/fixtures/files/.keep +0 -0
  83. data/examples/demo/test/helpers/.keep +0 -0
  84. data/examples/demo/test/integration/.keep +0 -0
  85. data/examples/demo/test/mailers/.keep +0 -0
  86. data/examples/demo/test/models/.keep +0 -0
  87. data/examples/demo/test/system/.keep +0 -0
  88. data/examples/demo/test/test_helper.rb +13 -0
  89. data/examples/demo/tmp/.keep +0 -0
  90. data/examples/demo/tmp/pids/.keep +0 -0
  91. data/examples/demo/tmp/storage/.keep +0 -0
  92. data/examples/demo/vendor/.keep +0 -0
  93. data/examples/demo/vendor/javascript/.keep +0 -0
  94. data/lib/generators/phraseapp_in_context_editor/templates/phraseapp_in_context_editor.rb +4 -0
  95. data/lib/phraseapp-in-context-editor-ruby/adapters/i18n.rb +2 -2
  96. data/lib/phraseapp-in-context-editor-ruby/backend_service.rb +16 -31
  97. data/lib/phraseapp-in-context-editor-ruby/config.rb +3 -1
  98. data/lib/phraseapp-in-context-editor-ruby/delegate/i18n_delegate.rb +2 -2
  99. data/lib/phraseapp-in-context-editor-ruby/version.rb +3 -0
  100. data/lib/phraseapp-in-context-editor-ruby/view_helpers.rb +2 -1
  101. data/lib/phraseapp-in-context-editor-ruby.rb +8 -0
  102. data/package-lock.json +6576 -0
  103. data/package.json +13 -0
  104. data/phraseapp-in-context-editor-ruby.gemspec +4 -2
  105. data/release.config.js +10 -0
  106. metadata +97 -7
@@ -0,0 +1,66 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>We're sorry, but something went wrong (500)</title>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <style>
7
+ .rails-default-error-page {
8
+ background-color: #EFEFEF;
9
+ color: #2E2F30;
10
+ text-align: center;
11
+ font-family: arial, sans-serif;
12
+ margin: 0;
13
+ }
14
+
15
+ .rails-default-error-page div.dialog {
16
+ width: 95%;
17
+ max-width: 33em;
18
+ margin: 4em auto 0;
19
+ }
20
+
21
+ .rails-default-error-page div.dialog > div {
22
+ border: 1px solid #CCC;
23
+ border-right-color: #999;
24
+ border-left-color: #999;
25
+ border-bottom-color: #BBB;
26
+ border-top: #B00100 solid 4px;
27
+ border-top-left-radius: 9px;
28
+ border-top-right-radius: 9px;
29
+ background-color: white;
30
+ padding: 7px 12% 0;
31
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
32
+ }
33
+
34
+ .rails-default-error-page h1 {
35
+ font-size: 100%;
36
+ color: #730E15;
37
+ line-height: 1.5em;
38
+ }
39
+
40
+ .rails-default-error-page div.dialog > p {
41
+ margin: 0 0 1em;
42
+ padding: 1em;
43
+ background-color: #F7F7F7;
44
+ border: 1px solid #CCC;
45
+ border-right-color: #999;
46
+ border-left-color: #999;
47
+ border-bottom-color: #999;
48
+ border-bottom-left-radius: 4px;
49
+ border-bottom-right-radius: 4px;
50
+ border-top-color: #DADADA;
51
+ color: #666;
52
+ box-shadow: 0 3px 8px rgba(50, 50, 50, 0.17);
53
+ }
54
+ </style>
55
+ </head>
56
+
57
+ <body class="rails-default-error-page">
58
+ <!-- This file lives in public/500.html -->
59
+ <div class="dialog">
60
+ <div>
61
+ <h1>We're sorry, but something went wrong.</h1>
62
+ </div>
63
+ <p>If you are the application owner check the logs for more information.</p>
64
+ </div>
65
+ </body>
66
+ </html>
File without changes
File without changes
@@ -0,0 +1 @@
1
+ # See https://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file
File without changes
@@ -0,0 +1,5 @@
1
+ require "test_helper"
2
+
3
+ class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
4
+ driven_by :selenium, using: :chrome, screen_size: [1400, 1400]
5
+ end
@@ -0,0 +1,11 @@
1
+ require "test_helper"
2
+
3
+ class ApplicationCable::ConnectionTest < ActionCable::Connection::TestCase
4
+ # test "connects with cookies" do
5
+ # cookies.signed[:user_id] = 42
6
+ #
7
+ # connect
8
+ #
9
+ # assert_equal connection.user_id, "42"
10
+ # end
11
+ end
File without changes
@@ -0,0 +1,8 @@
1
+ require "test_helper"
2
+
3
+ class MainControllerTest < ActionDispatch::IntegrationTest
4
+ test "should get index" do
5
+ get main_index_url
6
+ assert_response :success
7
+ end
8
+ end
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,13 @@
1
+ ENV["RAILS_ENV"] ||= "test"
2
+ require_relative "../config/environment"
3
+ require "rails/test_help"
4
+
5
+ class ActiveSupport::TestCase
6
+ # Run tests in parallel with specified workers
7
+ parallelize(workers: :number_of_processors)
8
+
9
+ # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
10
+ fixtures :all
11
+
12
+ # Add more helper methods to be used by all tests here...
13
+ end
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -9,6 +9,10 @@ PhraseApp::InContextEditor.configure do |config|
9
9
  config.account_id = "<%= options[:account_id] %>"
10
10
  config.datacenter = "eu"
11
11
 
12
+ # Configure an array of key names that should not be handled
13
+ # by the In-Context-Editor.
14
+ # config.ignored_keys = ["number.*", "foo.bar"]
15
+
12
16
  # Phrase uses decorators to generate a unique identification key
13
17
  # in context of your document. However, this might result in conflicts
14
18
  # with other libraries (e.g. client-side template engines) that use a similar syntax.
@@ -1,8 +1,8 @@
1
1
  if defined?(I18n)
2
2
  module I18n
3
3
  class << self
4
- def translate_with_phraseapp(*args)
5
- PhraseApp::InContextEditor.backend.translate(*args)
4
+ def translate_with_phraseapp(...)
5
+ PhraseApp::InContextEditor.backend.translate(...)
6
6
  end
7
7
  alias_method :translate_without_phraseapp, :translate
8
8
  alias_method :translate, :translate_with_phraseapp
@@ -3,47 +3,32 @@ require_relative "delegate/i18n_delegate"
3
3
  module PhraseApp
4
4
  module InContextEditor
5
5
  class BackendService
6
- attr_accessor :blacklisted_keys
7
-
8
6
  def initialize(args = {})
9
7
  self
10
8
  end
11
9
 
12
- def translate(*args)
13
- if to_be_translated_without_phraseapp?(args)
14
- # *Ruby 2.7+ keyword arguments warning*
15
- #
16
- # This method uses keyword arguments.
17
- # There is a breaking change in ruby that produces warning with ruby 2.7 and won't work as expected with ruby 3.0
18
- # The "hash" parameter must be passed as keyword argument.
19
- #
20
- # Good:
21
- # I18n.t(:salutation, :gender => 'w', :name => 'Smith')
22
- # I18n.t(:salutation, **{ :gender => 'w', :name => 'Smith' })
23
- # I18n.t(:salutation, **any_hash)
24
- #
25
- # Bad:
26
- # I18n.t(:salutation, { :gender => 'w', :name => 'Smith' })
27
- # I18n.t(:salutation, any_hash)
28
- #
29
- kw_args = args[1]
30
- if kw_args.present?
31
- I18n.translate_without_phraseapp(args[0], **kw_args)
32
- else
33
- I18n.translate_without_phraseapp(args[0])
34
- end
10
+ def translate(...)
11
+ if to_be_translated_without_phraseapp?(...)
12
+ I18n.translate_without_phraseapp(...)
35
13
  else
36
- phraseapp_delegate_for(args)
14
+ phraseapp_delegate_for(...)
37
15
  end
38
16
  end
39
17
 
40
18
  protected
41
19
 
42
- def to_be_translated_without_phraseapp?(args)
43
- PhraseApp::InContextEditor.disabled? || has_been_forced_to_resolve_with_phraseapp?(args)
20
+ def to_be_translated_without_phraseapp?(...)
21
+ PhraseApp::InContextEditor.disabled? || ignored_key?(...) || has_been_forced_to_resolve_with_phraseapp?(...)
22
+ end
23
+
24
+ def ignored_key?(*args)
25
+ key = given_key_from_args(args)
26
+ PhraseApp::InContextEditor.ignored_keys.any? do |ignored_key|
27
+ key.to_s[/\A#{ignored_key.gsub("*", ".*")}\Z/]
28
+ end
44
29
  end
45
30
 
46
- def has_been_forced_to_resolve_with_phraseapp?(args)
31
+ def has_been_forced_to_resolve_with_phraseapp?(*args)
47
32
  (args.last.is_a?(Hash) && args.last[:resolve] == false)
48
33
  end
49
34
 
@@ -51,11 +36,11 @@ module PhraseApp
51
36
  extract_normalized_key_from_args(args)
52
37
  end
53
38
 
54
- def phraseapp_delegate_for(args)
39
+ def phraseapp_delegate_for(*args)
55
40
  key = given_key_from_args(args)
56
41
  return nil unless present?(key)
57
42
 
58
- options = args[1].nil? ? {} : args[1]
43
+ options = options_from_args(args)
59
44
  PhraseApp::InContextEditor::Delegate::I18nDelegate.new(key, options, args)
60
45
  end
61
46
 
@@ -8,7 +8,9 @@ module PhraseApp
8
8
  enabled: false,
9
9
  backend: PhraseApp::InContextEditor::BackendService.new,
10
10
  prefix: "{{__",
11
- suffix: "__}}"
11
+ suffix: "__}}",
12
+ origin: "in-context-editor-ruby",
13
+ ignored_keys: []
12
14
  }.freeze
13
15
 
14
16
  CONFIG_OPTIONS.each do |option, default_value|
@@ -4,7 +4,7 @@ module PhraseApp
4
4
  module InContextEditor
5
5
  module Delegate
6
6
  class I18nDelegate < Base
7
- attr_accessor :key, :display_key, :options, :api_client, :fallback_keys, :original_args
7
+ attr_accessor :key, :display_key
8
8
 
9
9
  def initialize(key, options = {}, original_args = nil)
10
10
  @key = key
@@ -24,7 +24,7 @@ module PhraseApp
24
24
  data.send(*args, &block)
25
25
  else
26
26
  self.class.log "You tried to execute the missing method ##{args.first} on key #{@key} which is not supported. Please make sure you treat your translations as strings only."
27
- original_translation = ::I18n.translate_without_phraseapp(*@original_args)
27
+ original_translation = ::I18n.translate_without_phraseapp(*@original_args, **@options)
28
28
  original_translation.send(*args, &block)
29
29
  end
30
30
  end
@@ -0,0 +1,3 @@
1
+ module PhraseappInContextEditor
2
+ VERSION = "3.1.0"
3
+ end
@@ -17,7 +17,8 @@ module PhraseApp
17
17
  "accountId" => PhraseApp::InContextEditor.account_id,
18
18
  "datacenter" => PhraseApp::InContextEditor.datacenter,
19
19
  "prefix" => PhraseApp::InContextEditor.prefix,
20
- "suffix" => PhraseApp::InContextEditor.suffix
20
+ "suffix" => PhraseApp::InContextEditor.suffix,
21
+ "origin" => PhraseApp::InContextEditor.origin
21
22
  }.merge(opts)
22
23
 
23
24
  snippet = <<-EOS
@@ -37,6 +37,10 @@ module PhraseApp
37
37
  config.datacenter
38
38
  end
39
39
 
40
+ def ignored_keys
41
+ config.ignored_keys
42
+ end
43
+
40
44
  def enabled=(value)
41
45
  config.enabled = value
42
46
  end
@@ -48,6 +52,10 @@ module PhraseApp
48
52
  def disabled?
49
53
  !config.enabled
50
54
  end
55
+
56
+ def origin
57
+ config.origin
58
+ end
51
59
  end
52
60
 
53
61
  def self.configure