phraseapp-in-context-editor-ruby 2.0.0 → 3.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.
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