tr8n 3.1.8 → 3.2.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 (209) hide show
  1. data/.gitignore +2 -1
  2. data/.rspec +1 -0
  3. data/.rvmrc +1 -1
  4. data/.watchr +18 -0
  5. data/Gemfile.lock +16 -10
  6. data/app/assets/images/tr8n/minus_node.png +0 -0
  7. data/app/assets/images/tr8n/pixel.gif +0 -0
  8. data/app/assets/images/tr8n/plus_node.png +0 -0
  9. data/app/assets/javascripts/tr8n/tr8n.js +1 -0
  10. data/app/assets/javascripts/tr8n/tr8n_client_sdk.js +581 -425
  11. data/app/assets/stylesheets/tr8n/layout.css.scss +1 -1
  12. data/app/assets/stylesheets/tr8n/tr8n.css.scss +20 -0
  13. data/app/controllers/tr8n/admin/base_controller.rb +4 -1
  14. data/app/controllers/tr8n/admin/clientsdk_controller.rb +1 -1
  15. data/app/controllers/tr8n/admin/metrics_controller.rb +30 -0
  16. data/app/controllers/tr8n/api/v1/base_controller.rb +12 -0
  17. data/app/controllers/tr8n/api/v1/language_controller.rb +7 -5
  18. data/app/controllers/tr8n/awards_controller.rb +1 -1
  19. data/app/controllers/tr8n/base_controller.rb +12 -6
  20. data/app/controllers/tr8n/dashboard_controller.rb +1 -1
  21. data/app/controllers/tr8n/forum_controller.rb +1 -1
  22. data/app/controllers/tr8n/glossary_controller.rb +1 -1
  23. data/app/controllers/tr8n/help_controller.rb +1 -1
  24. data/app/controllers/tr8n/phrases_controller.rb +1 -1
  25. data/app/controllers/tr8n/translator_controller.rb +8 -0
  26. data/app/helpers/tr8n/admin/base_helper.rb +1 -1
  27. data/app/helpers/tr8n/base_helper.rb +1 -1
  28. data/app/helpers/tr8n/dashboard_helper.rb +1 -1
  29. data/app/models/tr8n/base_filter.rb +1 -1
  30. data/app/models/tr8n/daily_language_metric.rb +1 -1
  31. data/app/models/tr8n/date_rule.rb +1 -1
  32. data/app/models/tr8n/gender_list_rule.rb +1 -1
  33. data/app/models/tr8n/gender_rule.rb +1 -1
  34. data/app/models/tr8n/glossary.rb +1 -1
  35. data/app/models/tr8n/glossary_filter.rb +1 -1
  36. data/app/models/tr8n/integration/ru/russian_gender_list_rule.rb +1 -1
  37. data/app/models/tr8n/integration/ru/russian_numeric_rule.rb +1 -1
  38. data/app/models/tr8n/ip_location.rb +1 -1
  39. data/app/models/tr8n/ip_location_filter.rb +1 -1
  40. data/app/models/tr8n/language.rb +19 -7
  41. data/app/models/tr8n/language_case.rb +1 -1
  42. data/app/models/tr8n/language_case_filter.rb +1 -1
  43. data/app/models/tr8n/language_case_rule.rb +1 -1
  44. data/app/models/tr8n/language_case_rule_filter.rb +1 -1
  45. data/app/models/tr8n/language_case_value_map.rb +1 -1
  46. data/app/models/tr8n/language_case_value_map_filter.rb +1 -1
  47. data/app/models/tr8n/language_filter.rb +1 -1
  48. data/app/models/tr8n/language_forum_abuse_report.rb +1 -1
  49. data/app/models/tr8n/language_forum_abuse_report_filter.rb +1 -1
  50. data/app/models/tr8n/language_forum_message.rb +1 -1
  51. data/app/models/tr8n/language_forum_message_filter.rb +1 -1
  52. data/app/models/tr8n/language_forum_topic.rb +1 -1
  53. data/app/models/tr8n/language_forum_topic_filter.rb +1 -1
  54. data/app/models/tr8n/language_metric.rb +1 -1
  55. data/app/models/tr8n/language_metric_filter.rb +1 -1
  56. data/app/models/tr8n/language_rule.rb +1 -1
  57. data/app/models/tr8n/language_rule_filter.rb +1 -1
  58. data/app/models/tr8n/language_user.rb +1 -1
  59. data/app/models/tr8n/language_user_filter.rb +1 -1
  60. data/app/models/tr8n/list_rule.rb +1 -1
  61. data/app/models/tr8n/monthly_language_metric.rb +1 -1
  62. data/app/models/tr8n/numeric_rule.rb +35 -28
  63. data/app/models/tr8n/sync_log.rb +1 -1
  64. data/app/models/tr8n/sync_log_filter.rb +1 -1
  65. data/app/models/tr8n/total_language_metric.rb +1 -1
  66. data/app/models/tr8n/translation.rb +4 -3
  67. data/app/models/tr8n/translation_domain.rb +11 -3
  68. data/app/models/tr8n/translation_domain_filter.rb +1 -1
  69. data/app/models/tr8n/translation_filter.rb +1 -1
  70. data/app/models/tr8n/translation_key.rb +73 -36
  71. data/app/models/tr8n/translation_key_comment.rb +1 -1
  72. data/app/models/tr8n/translation_key_comment_filter.rb +1 -1
  73. data/app/models/tr8n/translation_key_filter.rb +1 -1
  74. data/app/models/tr8n/translation_key_lock.rb +1 -1
  75. data/app/models/tr8n/translation_key_lock_filter.rb +1 -1
  76. data/app/models/tr8n/translation_key_source.rb +16 -5
  77. data/app/models/tr8n/translation_key_source_filter.rb +1 -1
  78. data/app/models/tr8n/translation_source.rb +12 -4
  79. data/app/models/tr8n/translation_source_filter.rb +1 -1
  80. data/app/models/tr8n/translation_source_language.rb +1 -1
  81. data/app/models/tr8n/translation_vote.rb +1 -1
  82. data/app/models/tr8n/translation_vote_filter.rb +1 -1
  83. data/app/models/tr8n/translator.rb +21 -5
  84. data/app/models/tr8n/translator_filter.rb +1 -1
  85. data/app/models/tr8n/translator_following.rb +1 -1
  86. data/app/models/tr8n/translator_following_filter.rb +1 -1
  87. data/app/models/tr8n/translator_log.rb +3 -3
  88. data/app/models/tr8n/translator_log_filter.rb +1 -1
  89. data/app/models/tr8n/translator_metric.rb +1 -1
  90. data/app/models/tr8n/translator_metric_filter.rb +1 -1
  91. data/app/models/tr8n/translator_report.rb +1 -1
  92. data/app/models/tr8n/translator_report_filter.rb +1 -1
  93. data/app/models/tr8n/value_rule.rb +1 -1
  94. data/app/views/tr8n/admin/clientsdk/index.html.erb +29 -29
  95. data/app/views/tr8n/admin/clientsdk/lb_samples.html.erb +1 -1
  96. data/app/views/tr8n/admin/metrics/_tabs.html.erb +22 -0
  97. data/app/views/tr8n/admin/metrics/index.html.erb +60 -0
  98. data/app/views/tr8n/common/_header.html.erb +3 -1
  99. data/app/views/tr8n/common/_language_selector.html.erb +4 -2
  100. data/app/views/tr8n/common/_scripts.html.erb +5 -0
  101. data/app/views/tr8n/common/_terms_of_service.html.erb +53 -0
  102. data/app/views/tr8n/help/credits.html.erb +4 -0
  103. data/app/views/tr8n/language/_select.html.erb +5 -1
  104. data/app/views/tr8n/translator/registration.html.erb +21 -0
  105. data/config/routes.rb +3 -1
  106. data/doc/classes.graffle +356 -7194
  107. data/lib/generators/tr8n/templates/config/tr8n/config.yml +9 -1
  108. data/lib/generators/tr8n/templates/config/tr8n/site/shortcuts.yml +1 -1
  109. data/lib/generators/tr8n/templates/config/tr8n/tokens/decorations.yml +4 -1
  110. data/lib/generators/tr8n/tr8n_generator.rb +1 -1
  111. data/lib/tasks/tr8n.rake +1 -1
  112. data/lib/tr8n.rb +23 -0
  113. data/lib/tr8n/active_dumper.rb +1 -1
  114. data/lib/tr8n/cache.rb +1 -8
  115. data/lib/tr8n/cache_adapters/memcached.rb +1 -1
  116. data/lib/tr8n/config.rb +37 -1
  117. data/lib/tr8n/dictionary.rb +1 -1
  118. data/lib/tr8n/engine.rb +4 -1
  119. data/lib/tr8n/exception.rb +1 -1
  120. data/lib/tr8n/extender.rb +1 -1
  121. data/lib/tr8n/extensions/action_controller_extension.rb +5 -4
  122. data/lib/tr8n/extensions/action_view_extension.rb +71 -20
  123. data/lib/tr8n/extensions/array_extension.rb +14 -1
  124. data/lib/tr8n/extensions/date_extension.rb +1 -1
  125. data/lib/tr8n/extensions/fixnum_extension.rb +1 -1
  126. data/lib/tr8n/extensions/hash_extension.rb +1 -1
  127. data/lib/tr8n/extensions/string_extension.rb +1 -1
  128. data/lib/tr8n/extensions/time_extension.rb +1 -1
  129. data/lib/tr8n/ip_address.rb +1 -1
  130. data/lib/tr8n/key_registration_exception.rb +1 -1
  131. data/lib/tr8n/keyboard_mapping.rb +1 -1
  132. data/lib/tr8n/logger.rb +1 -1
  133. data/lib/tr8n/railtie.rb +1 -1
  134. data/lib/tr8n/site_map.rb +1 -1
  135. data/lib/tr8n/site_map_section.rb +1 -1
  136. data/lib/tr8n/token.rb +1 -1
  137. data/lib/tr8n/token_exception.rb +1 -1
  138. data/lib/tr8n/tokenized_label.rb +2 -12
  139. data/lib/tr8n/tokens/data_token.rb +1 -1
  140. data/lib/tr8n/tokens/decoration_token.rb +1 -1
  141. data/lib/tr8n/tokens/hidden_token.rb +1 -1
  142. data/lib/tr8n/tokens/method_token.rb +1 -1
  143. data/lib/tr8n/tokens/transform_token.rb +1 -1
  144. data/lib/tr8n/version.rb +25 -1
  145. data/local/tr8n_server/app/models/user.rb +1 -0
  146. data/local/tr8n_server/config/environments/test.rb +1 -1
  147. data/local/tr8n_server/config/tr8n/config.yml +45 -39
  148. data/local/tr8n_server/config/tr8n/site/shortcuts.yml +1 -1
  149. data/local/tr8n_server/db/schema.rb +2 -0
  150. data/spec/controllers/awards_controller_spec.rb +22 -0
  151. data/spec/controllers/base_controller_spec.rb +6 -0
  152. data/spec/controllers/dashboard_controller_spec.rb +23 -0
  153. data/spec/controllers/forum_controller_spec.rb +23 -0
  154. data/spec/controllers/glossary_controller_spec.rb +22 -0
  155. data/spec/controllers/help_controller_spec.rb +22 -0
  156. data/spec/controllers/language_cases_controller_spec.rb +13 -0
  157. data/spec/controllers/language_controller_spec.rb +10 -0
  158. data/spec/controllers/phrases_controller_spec.rb +22 -0
  159. data/spec/controllers/translations_controller_spec.rb +23 -0
  160. data/spec/controllers/translator_controller_spec.rb +22 -0
  161. data/spec/lib/tokenized_label_spec.rb +42 -0
  162. data/spec/lib/tokens/data_token_spec.rb +49 -0
  163. data/spec/lib/tokens/decoration_token_spec.rb +49 -0
  164. data/spec/lib/tokens/hidden_token_spec.rb +53 -0
  165. data/spec/lib/tokens/method_token_spec.rb +61 -0
  166. data/spec/lib/tokens/transform_token_spec.rb +51 -0
  167. data/spec/models/tr8n/daily_language_metric_spec.rb +5 -0
  168. data/spec/models/tr8n/date_rule_spec.rb +5 -0
  169. data/spec/models/tr8n/gender_list_rule_spec.rb +5 -0
  170. data/spec/models/tr8n/gender_rule_spec.rb +141 -0
  171. data/spec/models/tr8n/glossary_spec.rb +5 -0
  172. data/spec/models/tr8n/ip_location_spec.rb +5 -0
  173. data/spec/models/tr8n/language_case_rule_spec.rb +5 -0
  174. data/spec/models/tr8n/language_case_spec.rb +5 -0
  175. data/spec/models/tr8n/language_case_value_map_spec.rb +5 -0
  176. data/spec/models/tr8n/language_forum_abuse_report_spec.rb +5 -0
  177. data/spec/models/tr8n/language_forum_message_spec.rb +5 -0
  178. data/spec/models/tr8n/language_forum_topic_spec.rb +5 -0
  179. data/spec/models/tr8n/language_metric_spec.rb +5 -0
  180. data/spec/models/tr8n/language_rule_spec.rb +5 -0
  181. data/spec/models/tr8n/language_spec.rb +79 -0
  182. data/spec/models/tr8n/language_user_spec.rb +5 -0
  183. data/spec/models/tr8n/list_rule_spec.rb +5 -0
  184. data/spec/models/tr8n/monthly_language_metric_spec.rb +5 -0
  185. data/spec/models/tr8n/numeric_rule_spec.rb +162 -0
  186. data/spec/models/tr8n/sync_log_spec.rb +5 -0
  187. data/spec/models/tr8n/total_language_metric_spec.rb +5 -0
  188. data/spec/models/tr8n/translation_domain_spec.rb +5 -0
  189. data/spec/models/tr8n/translation_key_comment_spec.rb +5 -0
  190. data/spec/models/tr8n/translation_key_lock_spec.rb +5 -0
  191. data/spec/models/tr8n/translation_key_source_spec.rb +5 -0
  192. data/spec/models/tr8n/translation_key_spec.rb +118 -0
  193. data/spec/models/tr8n/translation_source_language_spec.rb +5 -0
  194. data/spec/models/tr8n/translation_source_spec.rb +5 -0
  195. data/spec/models/tr8n/translation_spec.rb +5 -0
  196. data/spec/models/tr8n/translation_vote_spec.rb +5 -0
  197. data/spec/models/tr8n/translator_following_spec.rb +5 -0
  198. data/spec/models/tr8n/translator_log_spec.rb +5 -0
  199. data/spec/models/tr8n/translator_metric_spec.rb +5 -0
  200. data/spec/models/tr8n/translator_report_spec.rb +5 -0
  201. data/spec/models/tr8n/translator_spec.rb +140 -0
  202. data/spec/spec_helper.rb +26 -27
  203. data/tr8n.gemspec +3 -1
  204. metadata +173 -50
  205. data/local/tr8n_server/db/migrate/20110930041150_create_tr8n_tables.rb +0 -372
  206. data/spec/fake_app.rb +0 -50
  207. data/spec/lib/data_token_spec.rb +0 -26
  208. data/spec/lib/transform_token_spec.rb +0 -22
  209. data/spec/models/translation_key_spec.rb +0 -63
data/.gitignore CHANGED
@@ -15,6 +15,7 @@ Thumbs.db
15
15
  .tmp*
16
16
  tmp/
17
17
  local/tr8n_server/db/*.sqlite3
18
+ local/tr8n_server/db/test.sqlite3
18
19
  local/tr8n_server/log/*.log
19
20
  local/tr8n_server/tmp/
20
- local/tr8n_server/.sass-cache/
21
+ local/tr8n_server/.sass-cache/
data/.rspec CHANGED
@@ -1,2 +1,3 @@
1
1
  --color
2
2
  --format=d
3
+ --drb
data/.rvmrc CHANGED
@@ -1 +1 @@
1
- rvm 1.9.2@tr8n --create
1
+ rvm use 1.9.2@tr8n --create
data/.watchr ADDED
@@ -0,0 +1,18 @@
1
+ def run_spec(file)
2
+ unless File.exist?(file)
3
+ puts "#{file} does not exist"
4
+ return
5
+ end
6
+
7
+ puts "Running #{file}"
8
+ system "bundle exec rspec #{file}"
9
+ puts
10
+ end
11
+
12
+ watch("spec/.*/*_spec.rb") do |match|
13
+ run_spec match[0]
14
+ end
15
+
16
+ watch("app/(.*/.*).rb") do |match|
17
+ run_spec %{spec/#{match[1]}_spec.rb}
18
+ end
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- tr8n (3.1.8)
4
+ tr8n (3.2.0)
5
5
  coffee-script
6
6
  kaminari
7
7
  rails (>= 3.1.0)
@@ -40,7 +40,7 @@ GEM
40
40
  activesupport (= 3.1.0)
41
41
  activesupport (3.1.0)
42
42
  multi_json (~> 1.0)
43
- arel (2.2.1)
43
+ arel (2.2.3)
44
44
  bcrypt-ruby (3.0.1)
45
45
  builder (3.0.0)
46
46
  capybara (1.1.1)
@@ -56,11 +56,11 @@ GEM
56
56
  coffee-script (2.2.0)
57
57
  coffee-script-source
58
58
  execjs
59
- coffee-script-source (1.1.3)
59
+ coffee-script-source (1.2.0)
60
60
  database_cleaner (0.6.7)
61
61
  diff-lcs (1.1.3)
62
62
  erubis (2.7.0)
63
- execjs (1.2.9)
63
+ execjs (1.3.0)
64
64
  multi_json (~> 1.0)
65
65
  factory_girl (2.1.2)
66
66
  activesupport
@@ -68,9 +68,11 @@ GEM
68
68
  hike (1.2.1)
69
69
  i18n (0.6.0)
70
70
  json_pure (1.6.1)
71
- kaminari (0.12.4)
72
- rails (>= 3.0.0)
73
- mail (2.3.0)
71
+ kaminari (0.13.0)
72
+ actionpack (>= 3.0.0)
73
+ activesupport (>= 3.0.0)
74
+ railties (>= 3.0.0)
75
+ mail (2.3.3)
74
76
  i18n (>= 0.4.0)
75
77
  mime-types (~> 1.16)
76
78
  treetop (~> 1.4.8)
@@ -129,7 +131,7 @@ GEM
129
131
  ruby_parser (2.0.6)
130
132
  sexp_processor (~> 3.0)
131
133
  rubyzip (0.9.4)
132
- sass (3.1.10)
134
+ sass (3.1.15)
133
135
  selenium-webdriver (2.7.0)
134
136
  childprocess (>= 0.2.1)
135
137
  ffi (>= 1.0.7)
@@ -137,6 +139,7 @@ GEM
137
139
  rubyzip
138
140
  sexp_processor (3.0.7)
139
141
  slop (2.1.0)
142
+ spork (0.9.0)
140
143
  sprockets (2.0.1)
141
144
  hike (~> 1.2)
142
145
  rack (~> 1.0)
@@ -150,7 +153,8 @@ GEM
150
153
  treetop (1.4.10)
151
154
  polyglot
152
155
  polyglot (>= 0.3.1)
153
- tzinfo (0.3.31)
156
+ tzinfo (0.3.32)
157
+ watchr (0.7)
154
158
  will_filter (3.1.3)
155
159
  coffee-script
156
160
  kaminari
@@ -171,7 +175,9 @@ DEPENDENCIES
171
175
  pry
172
176
  rr
173
177
  rspec
174
- rspec-rails
178
+ rspec-rails (>= 2.1.0)
179
+ spork
175
180
  sqlite3
176
181
  steak
177
182
  tr8n!
183
+ watchr
@@ -735,6 +735,7 @@ Tr8n.Utils = {
735
735
  }
736
736
 
737
737
  request.open(options.method, url, true);
738
+ request.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
738
739
  request.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
739
740
  request.setRequestHeader('Accept', 'text/javascript, text/html, application/xml, text/xml, */*');
740
741
  request.send(options.parameters);
@@ -1,5 +1,5 @@
1
1
  /****************************************************************************
2
- Copyright (c) 2010-2011 Michael Berkovich
2
+ Copyright (c) 2010-2012 Michael Berkovich
3
3
 
4
4
  Permission is hereby granted, free of charge, to any person obtaining
5
5
  a copy of this software and associated documentation files (the
@@ -45,33 +45,47 @@ var Tr8n = Tr8n || {
45
45
  ****************************************************************************/
46
46
 
47
47
  Tr8n.Proxy = function(options) {
48
- var self = this;
48
+ var self = this;
49
49
  this.options = options;
50
- this.options['url'] = this.options['url'] || '/tr8n/api/v1/language/translate';
50
+ this.options['url'] = this.options['url'] || '/tr8n/api/v1/language/translate';
51
51
  this.options['scheduler_interval'] = this.options['scheduler_interval'] || 20000;
52
- this.logger_enabled = true;
53
- this.missing_translations_locked = false;
54
- this.inline_translations_enabled = this.options['enable_inline_translations'];
55
- this.logger = new Tr8n.Proxy.Logger({
52
+ this.logger_enabled = false;
53
+ this.missing_translations_locked = false;
54
+ this.inline_translations_enabled = this.options['enable_inline_translations'];
55
+ this.logger = new Tr8n.Proxy.Logger({
56
56
  'proxy': self,
57
- 'element_id': options['debugger_element_id']
58
- });
57
+ 'element_id': options['logger_element_id'] || 'tr8n_debugger'
58
+ });
59
59
 
60
60
  this.language = new Tr8n.Proxy.Language({
61
61
  'proxy': self
62
- });
63
-
64
- this.initTranslations();
65
- this.runScheduledTasks();
62
+ });
63
+
64
+ this.initTranslations();
65
+ this.runScheduledTasks();
66
66
  }
67
67
 
68
68
  Tr8n.Proxy.prototype = {
69
69
  log: function(msg) {
70
70
  this.logger.debug(msg);
71
71
  },
72
- disableLogger: function() {
73
- this.logger_enabled = false;
74
- },
72
+ logSettings: function() {
73
+ this.logger.clear();
74
+ this.logger.logObject(this.options);
75
+ },
76
+ logTranslations: function() {
77
+ this.logger.clear();
78
+ this.translations = this.translations || {};
79
+ this.logger.logObject(this.translations);
80
+ },
81
+ logMissingTranslations: function() {
82
+ this.logger.clear();
83
+ this.missing_translation_keys = this.missing_translation_keys || {};
84
+ this.logger.logObject(this.missing_translation_keys);
85
+ },
86
+ disableLogger: function() {
87
+ this.logger_enabled = false;
88
+ },
75
89
  enableLogger: function() {
76
90
  this.logger_enabled = true;
77
91
  },
@@ -81,75 +95,95 @@ Tr8n.Proxy.prototype = {
81
95
  error: function(msg) {
82
96
  this.logger.error(msg);
83
97
  },
84
- translate: function(label, description, tokens, options) {
98
+ translate: function(label, description, tokens, options) {
99
+ if (!label) return "";
100
+ description = description || "";
101
+ tokens = tokens || {};
102
+ options = options || {};
85
103
  return this.language.translate(label, description, tokens, options);
86
- },
87
- tr: function(label, description, tokens, options) {
88
- return this.translate(label, description, tokens, options);
89
- },
104
+ },
105
+ tr: function(label, description, tokens, options) {
106
+ return this.translate(label, description, tokens, options);
107
+ },
108
+ trl: function(label, description, tokens, options) {
109
+ options = options || {};
110
+ options['skip_decorations'] = true;
111
+ return this.translate(label, description, tokens, options);
112
+ },
90
113
  getTranslations: function() {
91
- if (!this.translations) return {};
92
- return this.translations;
93
- },
94
- getDecorationFor: function(decoration_name) {
95
- if (!this.options['default_decorations'])
96
- return null;
97
- return this.options['default_decorations'][decoration_name];
98
- },
99
- getLanguageRuleForType: function(rule_type) {
100
- // modify this section to add more rules
101
- if (rule_type == 'number') return 'Tr8n.Proxy.NumericRule';
114
+ this.translations = this.translations || {};
115
+ return this.translations;
116
+ },
117
+ getDecorationFor: function(decoration_name) {
118
+ if (!this.options['default_decorations'])
119
+ return null;
120
+ return this.options['default_decorations'][decoration_name];
121
+ },
122
+ getLanguageRuleForType: function(rule_type) {
123
+ // modify this section to add more rules
124
+ if (rule_type == 'number') return 'Tr8n.Proxy.NumericRule';
102
125
  if (rule_type == 'gender') return 'Tr8n.Proxy.GenderRule';
103
126
  if (rule_type == 'date') return 'Tr8n.Proxy.DateRule';
104
127
  if (rule_type == 'list') return 'Tr8n.Proxy.ListRule';
105
128
  if (rule_type == 'gender_list') return 'Tr8n.Proxy.GenderListRule';
106
- return null;
107
- },
129
+ return null;
130
+ },
108
131
  getLanguageRuleForTokenSuffix: function(token_suffix) {
109
- if (!this.options['rules']) return null;
110
-
111
- for (rule_type in this.options['rules']) {
112
- var suffixes = this.options['rules'][rule_type]['token_suffixes'];
113
- if (!suffixes) continue;
114
-
132
+ if (!this.options['rules']) return null;
133
+
134
+ for (rule_type in this.options['rules']) {
135
+ var suffixes = this.options['rules'][rule_type]['token_suffixes'];
136
+ if (!suffixes) continue;
137
+
115
138
  if (Tr8n.Proxy.Utils.indexOf(suffixes, token_suffix) != -1 )
116
- return this.getLanguageRuleForType(rule_type);
117
- }
139
+ return this.getLanguageRuleForType(rule_type);
140
+ }
118
141
  return null;
119
142
  },
120
-
121
- registerTranslationKeys: function(translations) {
143
+
144
+ registerTranslationKeys: function(translations) {
122
145
  this.log("Found " + translations.length + " registered phrases");
123
146
  for (i = 0; i < translations.length; i++) {
124
- var translation_key = translations[i];
147
+ var translation_key = translations[i];
125
148
  this.log("Registering " + translation_key['key']);
126
149
  this.translations[translation_key['key']] = translation_key;
127
150
  }
128
- },
151
+ },
152
+
129
153
  initTranslations: function(forced) {
130
154
  if (!forced && this.translations) return;
155
+
156
+ this.translations = {};
157
+
158
+ // Check for page variable to load translations from, if variable was provided
159
+ if (this.options['translations_cache_id']) {
160
+ this.log("Registering page translations from translations cache...");
161
+ this.updateTranslations(eval(this.options['translations_cache_id']));
162
+ }
131
163
 
132
164
  var self = this;
133
- self.translations = {};
134
165
 
135
- if (this.options['translations_element_id']) {
136
- self.log("Registering page translations...");
137
- this.registerTranslationKeys(eval(this.options['translations_element_id']));
138
- return;
166
+ // Optionally, fetch translations from the server
167
+ if (this.options['fetch_translations_on_init']) {
168
+ this.log("Fetching translations from the server...");
169
+ Tr8n.Proxy.Utils.ajax(this.options['url'], {
170
+ method: 'get',
171
+ parameters: {'batch': true, 'source': self.options['default_source']},
172
+ onSuccess: function(response) {
173
+ self.log("Received response from the server");
174
+ self.log(response.responseText);
175
+ self.updateTranslations(eval("[" + response.responseText + "]")[0]['phrases']);
176
+ }
177
+ });
139
178
  }
179
+ },
140
180
 
141
- self.log("Fetching translations from the server...");
142
- Tr8n.Proxy.Utils.ajax(this.options['url'], {
143
- method: 'get',
144
- parameters: {'batch': true, 'source': self.options['default_source']},
145
- onSuccess: function(response) {
146
- self.log("Received response from the server");
147
- self.log(response.responseText);
148
- self.registerTranslationKeys(eval("[" + response.responseText + "]")[0]['phrases']);
149
- }
150
- });
181
+ updateTranslations: function(new_translations) {
182
+ this.translations = this.translations || {};
183
+ this.log("Updating page translations...");
184
+ this.registerTranslationKeys(new_translations);
151
185
  },
152
-
186
+
153
187
  registerMissingTranslationKey: function(translation_key, token_values, options) {
154
188
  this.missing_translation_keys = this.missing_translation_keys || {};
155
189
  if (!this.missing_translation_keys[translation_key.key]) {
@@ -158,30 +192,30 @@ Tr8n.Proxy.prototype = {
158
192
  }
159
193
  },
160
194
  submitMissingTranslationKeys: function() {
161
- if (this.missing_translations_locked) {
162
- this.log('Missing translations are being processed, postponding registration task.');
163
- return;
164
- }
165
-
195
+ if (this.missing_translations_locked) {
196
+ this.log('Missing translations are being processed, postponding registration task.');
197
+ return;
198
+ }
199
+
166
200
  this.missing_translation_keys = this.missing_translation_keys || {};
167
-
168
- var phrases = "[";
169
- for (var key in this.missing_translation_keys) {
170
- var translation_key = this.missing_translation_keys[key].translation_key;
171
- if (translation_key == null) continue;
172
- if (phrases!="[") phrases = phrases + ",";
201
+
202
+ var phrases = "[";
203
+ for (var key in this.missing_translation_keys) {
204
+ var translation_key = this.missing_translation_keys[key].translation_key;
205
+ if (translation_key == null) continue;
206
+ if (phrases!="[") phrases = phrases + ",";
173
207
  phrases = phrases + "{";
174
- phrases = phrases + '"label":"' + translation_key.label + '", ';
208
+ phrases = phrases + '"label":"' + translation_key.label + '", ';
175
209
  phrases = phrases + '"description":"' + translation_key.description + '"';
176
210
  phrases = phrases + "}";
177
- }
178
- phrases = phrases + "]";
179
-
211
+ }
212
+ phrases = phrases + "]";
213
+
180
214
  if (phrases == '[]') {
181
215
  // this.log('No missing translation keys to submit...');
182
216
  return;
183
217
  }
184
-
218
+
185
219
  var self = this;
186
220
  this.debug('Submitting missing translation keys: ' + phrases);
187
221
  Tr8n.Proxy.Utils.ajax(this.options['url'], {
@@ -190,42 +224,42 @@ Tr8n.Proxy.prototype = {
190
224
  onSuccess: function(response) {
191
225
  self.log("Received response from the server");
192
226
  self.log(response.responseText);
193
- self.updateMissingTranslationKeys(eval("[" + response.responseText + "]")[0]['phrases']);
227
+ self.updateMissingTranslationKeys(eval("[" + response.responseText + "]")[0]['phrases']);
194
228
  }
195
229
  });
196
230
  },
197
231
  updateMissingTranslationKeys: function(translations) {
198
- this.missing_translations_locked = true;
232
+ this.missing_translations_locked = true;
199
233
  this.log("Received " + translations.length + " registered phrases...");
200
234
  for (i = 0; i < translations.length; i++) {
201
235
  var translation_key_data = translations[i];
202
-
236
+
203
237
  this.log("Registering new key " + translation_key_data.key);
204
238
  this.translations[translation_key_data.key] = translation_key_data;
205
239
  var missing_key_data = this.missing_translation_keys[translation_key_data.key];
206
240
  var tr8nElement = Tr8n.element(translation_key_data.key);
207
241
 
208
242
  if (tr8nElement && missing_key_data.translation_key) {
209
- tr8nElement.innerHTML = missing_key_data.translation_key.translate(this.language, missing_key_data.token_values, {skip_decorations:true});
243
+ tr8nElement.innerHTML = missing_key_data.translation_key.translate(this.language, missing_key_data.token_values, {skip_decorations:true});
210
244
  tr8nElement.setAttribute('translation_key_id', translation_key_data['id']);
211
245
  if (this.inline_translations_enabled) {
212
- tr8nElement.className = 'tr8n_translatable tr8n_not_translated';
213
- }
246
+ tr8nElement.className = 'tr8n_translatable tr8n_not_translated';
247
+ }
214
248
  }
215
249
 
216
250
  delete this.missing_translation_keys[missing_key_data.translation_key.key];
217
251
  }
218
- this.missing_translations_locked = false;
219
- },
252
+ this.missing_translations_locked = false;
253
+ },
220
254
  runScheduledTasks: function() {
221
255
  var self = this;
222
-
256
+
223
257
  // this.log("Running scheduled tasks...");
224
- this.submitMissingTranslationKeys();
225
-
226
- window.setTimeout(function() {
227
- self.runScheduledTasks();
228
- }, this.options['scheduler_interval']);
258
+ this.submitMissingTranslationKeys();
259
+
260
+ window.setTimeout(function() {
261
+ self.runScheduledTasks();
262
+ }, this.options['scheduler_interval']);
229
263
  },
230
264
  }
231
265
 
@@ -241,11 +275,11 @@ Tr8n.Proxy.Language.prototype = {
241
275
  getProxy: function() {
242
276
  return this.options['proxy'];
243
277
  },
244
- getLogger: function() {
245
- return this.getProxy().logger;
246
- },
278
+ getLogger: function() {
279
+ return this.getProxy().logger;
280
+ },
247
281
  translate: function(label, description, tokens, options) {
248
- return (new Tr8n.Proxy.TranslationKey(label, description, {'proxy': this.getProxy()}).translate(this, tokens, options));
282
+ return (new Tr8n.Proxy.TranslationKey(label, description, {'proxy': this.getProxy()}).translate(this, tokens, options));
249
283
  }
250
284
  }
251
285
 
@@ -267,51 +301,51 @@ Tr8n.Proxy.TranslationKey.prototype = {
267
301
  getLogger: function() {
268
302
  return this.getProxy().logger;
269
303
  },
270
- findFirstAcceptableTranslation: function(translations, token_values) {
271
- // check for a single translation case - no context rules
304
+ findFirstAcceptableTranslation: function(translations, token_values) {
305
+ // check for a single translation case - no context rules
272
306
  if (translations['label']!=null) {
273
307
  this.getLogger().debug('Found a single translation: ' + translations['label']);
274
308
  return translations;
275
309
  }
276
310
 
277
- translations = translations['labels'];
278
- if (!translations) {
279
- this.getLogger().error("Translations are in a weird form...");
280
- return null;
281
- }
311
+ translations = translations['labels'];
312
+ if (!translations) {
313
+ this.getLogger().error("Translations are in a weird form...");
314
+ return null;
315
+ }
282
316
 
283
317
  this.getLogger().debug('Found translations: ' + translations.length);
284
- for (var i=0; i<translations.length; i++) {
285
- this.getLogger().debug("Checking context rules for:" + translations[i]['label']);
286
-
287
- if (!translations[i]['context']) {
318
+ for (var i=0; i<translations.length; i++) {
319
+ this.getLogger().debug("Checking context rules for:" + translations[i]['label']);
320
+
321
+ if (!translations[i]['context']) {
288
322
  this.getLogger().debug("Translation has no context, using it by default");
289
- return translations[i];
290
- }
291
- var valid_context = true;
292
-
293
- for (var token in translations[i]['context']) {
294
- if (!valid_context) continue;
295
- var token_context = translations[i]['context'][token];
296
- var rule_name = this.getProxy().getLanguageRuleForType(token_context['type']);
323
+ return translations[i];
324
+ }
325
+ var valid_context = true;
326
+
327
+ for (var token in translations[i]['context']) {
328
+ if (!valid_context) continue;
329
+ var token_context = translations[i]['context'][token];
330
+ var rule_name = this.getProxy().getLanguageRuleForType(token_context['type']);
297
331
  this.getLogger().debug("Evaluating rule: " + rule_name);
298
- var options = {'proxy': this.getProxy()};
299
- var rule = eval("new " + rule_name + "(token_context, options)");
300
- valid_context = valid_context && rule.evaluate(token, token_values);
301
- }
302
-
332
+ var options = {'proxy': this.getProxy()};
333
+ var rule = eval("new " + rule_name + "(token_context, options)");
334
+ valid_context = valid_context && rule.evaluate(token, token_values);
335
+ }
336
+
303
337
  if (valid_context) {
304
338
  this.getLogger().debug("Found valid translation: " + translations[i].label);
305
- return translations[i];
306
- } else {
339
+ return translations[i];
340
+ } else {
307
341
  this.getLogger().debug("The rules were not matched for: " + translations[i].label);
308
- }
309
- }
310
-
342
+ }
343
+ }
344
+
311
345
  this.getLogger().debug('No acceptable ranslations found');
312
- return null;
313
- },
314
-
346
+ return null;
347
+ },
348
+
315
349
  translate: function(language, token_values, options) {
316
350
  if (!this.label) {
317
351
  this.getLogger().error('Label must always be provided for the translate method');
@@ -320,95 +354,95 @@ Tr8n.Proxy.TranslationKey.prototype = {
320
354
 
321
355
  var translations = this.getProxy().getTranslations();
322
356
  var translation_key = translations[this.key];
323
-
357
+
324
358
  if (translation_key) {
325
359
  this.getLogger().debug("Found translations, evaluating rules...");
326
-
360
+
327
361
  this.id = translation_key.id;
328
- this.original = translation_key.original;
362
+ this.original = translation_key.original;
329
363
  var translation = this.findFirstAcceptableTranslation(translation_key, token_values);
330
364
 
331
365
  if (translation) {
332
366
  this.getLogger().debug("Found a valid match: " + translation.label);
333
- return this.substituteTokens(translation['label'], token_values, options);
334
- } else {
367
+ return this.substituteTokens(translation['label'], token_values, options);
368
+ } else {
335
369
  this.getLogger().debug("No valid match found, using default language");
336
- return this.substituteTokens(this.label, token_values, options);
337
- }
338
-
370
+ return this.substituteTokens(this.label, token_values, options);
371
+ }
372
+
339
373
  } else {
340
- this.getLogger().debug("Translation not found, using default language");
341
- }
374
+ this.getLogger().debug("Translation not found, using default language");
375
+ }
342
376
 
343
377
  this.getProxy().registerMissingTranslationKey(this, token_values, options);
344
378
  this.getLogger().debug('No translation found. Using default...');
345
379
  return this.substituteTokens(this.label, token_values, options);
346
380
  },
347
-
381
+
348
382
  generateKey: function() {
349
383
  this.key = this.label + ";;;";
350
- if (this.description) this.key = this.key + this.description;
351
-
384
+ if (this.description) this.key = this.key + this.description;
385
+
352
386
  this.getLogger().debug('Preparing label signature: ' + this.key);
353
387
  this.key = MD5(this.key);
354
388
  this.getLogger().debug('Label signature: ' + this.key);
355
- },
389
+ },
356
390
 
357
391
  registerDataTokens: function(label) {
358
392
  this.data_tokens = [];
359
- this.data_tokens = this.data_tokens.concat(Tr8n.Proxy.DataToken.parse(label, {'key': this, 'proxy':this.getProxy()}));
393
+ this.data_tokens = this.data_tokens.concat(Tr8n.Proxy.DataToken.parse(label, {'key': this, 'proxy':this.getProxy()}));
360
394
  this.data_tokens = this.data_tokens.concat(Tr8n.Proxy.TransformToken.parse(label, {'key': this, 'proxy':this.getProxy()}));
361
395
  },
362
396
 
363
- registerDecorationTokens: function(label) {
397
+ registerDecorationTokens: function(label) {
364
398
  this.decoration_tokens = [];
365
399
  this.decoration_tokens = this.decoration_tokens.concat(Tr8n.Proxy.DecorationToken.parse(label, {'key': this, 'proxy':this.getProxy()}));
366
400
  },
367
401
 
368
402
  substituteTokens: function(label, token_values, options) {
369
403
  this.registerDataTokens(label);
370
- if (!this.data_tokens) return this.decorateLabel(label, options);
404
+ if (!this.data_tokens) return this.decorateLabel(label, options);
371
405
  for (var i = 0; i < this.data_tokens.length; i++) {
372
- label = this.data_tokens[i].substitute(label, token_values || {});
373
- }
406
+ label = this.data_tokens[i].substitute(label, token_values || {});
407
+ }
374
408
 
375
409
  this.registerDecorationTokens(label);
376
410
  if (!this.decoration_tokens) return label;
377
411
  for (var i = 0; i < this.decoration_tokens.length; i++) {
378
412
  label = this.decoration_tokens[i].substitute(label, token_values || {});
379
413
  }
380
-
381
- return this.decorateLabel(label, options);
414
+
415
+ return this.decorateLabel(label, options);
382
416
  },
383
-
417
+
384
418
  decorateLabel: function(label, options){
385
- options = options || {};
386
- if (options['skip_decorations'])
419
+ options = options || {};
420
+ if (options['skip_decorations'])
387
421
  return label;
388
-
422
+
389
423
  html = [];
390
- html.push("<tr8n ");
391
-
392
- if (this.id)
393
- html.push(" translation_key_id='" + this.id + "' ");
394
-
424
+ html.push("<tr8n ");
425
+
426
+ if (this.id)
427
+ html.push(" translation_key_id='" + this.id + "' ");
428
+
395
429
  if (this.key)
396
430
  html.push(" id='" + this.key + "' ");
397
-
398
- var klasses = ['tr8n_translatable'];
399
-
400
- if (this.original)
401
- klasses.push('tr8n_not_translated');
402
- else
431
+
432
+ var klasses = ['tr8n_translatable'];
433
+
434
+ if (this.original)
435
+ klasses.push('tr8n_not_translated');
436
+ else
403
437
  klasses.push('tr8n_translated');
404
438
 
405
- if (this.getProxy().inline_translations_enabled && this.id)
439
+ if (this.getProxy().inline_translations_enabled && this.id)
406
440
  html.push(" class='" + klasses.join(' ') + "'");
407
-
441
+
408
442
  html.push(">");
409
- html.push(label);
410
- html.push("</tr8n>");
411
- return html.join("");
443
+ html.push(label);
444
+ html.push("</tr8n>");
445
+ return html.join("");
412
446
  }
413
447
  }
414
448
 
@@ -425,27 +459,27 @@ Tr8n.Proxy.LanguageRule.prototype = {
425
459
  getLogger: function() {
426
460
  return this.getProxy().logger;
427
461
  },
428
- getTokenValue: function(token_name, token_values) {
429
- var object = token_values[token_name];
430
- if (object == null) {
462
+ getTokenValue: function(token_name, token_values) {
463
+ var object = token_values[token_name];
464
+ if (object == null) {
431
465
  this.getLogger().error("Invalid token value for token: " + token_name);
432
- }
433
-
434
- return object;
435
- },
436
- getDefinitionDescription: function() {
466
+ }
467
+
468
+ return object;
469
+ },
470
+ getDefinitionDescription: function() {
437
471
  var result = [];
438
472
  for (var key in this.definition)
439
473
  result.push(key + ": '" + this.definition[key] + "'");
440
- return "{" + result.join(", ") + "}";
441
- },
474
+ return "{" + result.join(", ") + "}";
475
+ },
442
476
  sanitizeArrayValue: function(value) {
443
477
  var results = [];
444
478
  var arr = value.split(',');
445
- for (var index = 0; index < arr.length; index++) {
446
- results.push(Tr8n.Proxy.Utils.trim(arr[index]));
447
- }
448
- return results;
479
+ for (var index = 0; index < arr.length; index++) {
480
+ results.push(Tr8n.Proxy.Utils.trim(arr[index]));
481
+ }
482
+ return results;
449
483
  }
450
484
  }
451
485
 
@@ -454,7 +488,7 @@ Tr8n.Proxy.LanguageRule.prototype = {
454
488
  ****************************************************************************/
455
489
 
456
490
  Tr8n.Proxy.NumericRule = function(definition, options) {
457
- this.definition = definition;
491
+ this.definition = definition;
458
492
  this.options = options;
459
493
  }
460
494
 
@@ -465,36 +499,36 @@ Tr8n.Proxy.NumericRule.prototype = new Tr8n.Proxy.LanguageRule();
465
499
  // {count | message, messages}
466
500
  // {count | person, people}
467
501
  Tr8n.Proxy.NumericRule.transform = function(count, values) {
468
- if (count == 1) return values[0];
469
- return values[1];
502
+ if (count == 1) return values[0];
503
+ return values[1];
470
504
  }
471
505
 
472
506
  Tr8n.Proxy.NumericRule.prototype.evaluate = function(token_name, token_values){
473
- // "count":{"value1":"2,3,4","operator":"and","type":"number","multipart":true,"part2":"does_not_end_in","value2":"12,13,14","part1":"ends_in"}
474
-
475
- var object = this.getTokenValue(token_name, token_values);
476
- if (object == null) return false;
507
+ // "count":{"value1":"2,3,4","operator":"and","type":"number","multipart":true,"part2":"does_not_end_in","value2":"12,13,14","part1":"ends_in"}
508
+
509
+ var object = this.getTokenValue(token_name, token_values);
510
+ if (object == null) return false;
477
511
 
478
- var token_value = null;
512
+ var token_value = null;
479
513
  if (typeof object == 'string' || typeof object == 'number') {
480
514
  token_value = "" + object;
481
- } else if (typeof object == 'object' && object['subject']) {
515
+ } else if (typeof object == 'object' && object['subject']) {
482
516
  token_value = "" + object['subject'];
483
- } else {
517
+ } else {
484
518
  this.getLogger().error("Invalid token value for numeric token: " + token_name);
485
- return false;
486
- }
487
-
519
+ return false;
520
+ }
521
+
488
522
  this.getLogger().debug("Rule value: '" + token_value + "' for definition: " + this.getDefinitionDescription());
489
-
523
+
490
524
  var result1 = this.evaluatePartialRule(token_value, this.definition['part1'], this.sanitizeArrayValue(this.definition['value1']));
491
- if (this.definition['multipart'] == 'false' || this.definition['multipart'] == false || this.definition['multipart'] == null) return result1;
525
+ if (this.definition['multipart'] == 'false' || this.definition['multipart'] == false || this.definition['multipart'] == null) return result1;
492
526
  this.getLogger().debug("Part 1: " + result1 + " Processing part 2...");
493
527
 
494
528
  var result2 = this.evaluatePartialRule(token_value, this.definition['part2'], this.sanitizeArrayValue(this.definition['value2']));
495
529
  this.getLogger().debug("Part 2: " + result2 + " Completing evaluation...");
496
-
497
- if (this.definition['operator'] == "or") return (result1 || result2);
530
+
531
+ if (this.definition['operator'] == "or") return (result1 || result2);
498
532
  return (result1 && result2);
499
533
  }
500
534
 
@@ -509,9 +543,9 @@ Tr8n.Proxy.NumericRule.prototype.evaluatePartialRule = function(token_value, nam
509
543
  return false;
510
544
  }
511
545
  if (name == 'ends_in') {
512
- for(var i=0; i<values.length; i++) {
513
- if (token_value.match(values[i] + "$")) return true;
514
- }
546
+ for(var i=0; i<values.length; i++) {
547
+ if (token_value.match(values[i] + "$")) return true;
548
+ }
515
549
  return false;
516
550
  }
517
551
  if (name == 'does_not_end_in') {
@@ -520,7 +554,7 @@ Tr8n.Proxy.NumericRule.prototype.evaluatePartialRule = function(token_value, nam
520
554
  }
521
555
  return true;
522
556
  }
523
- return false;
557
+ return false;
524
558
  }
525
559
 
526
560
 
@@ -541,7 +575,7 @@ Tr8n.Proxy.GenderRule.prototype = new Tr8n.Proxy.LanguageRule();
541
575
  // {user | he, she, he/she}
542
576
  Tr8n.Proxy.GenderRule.transform = function(object, values) {
543
577
  if (values.length == 1) return values[0];
544
-
578
+
545
579
  if (typeof object == 'string') {
546
580
  if (object == 'male') return values[0];
547
581
  if (object == 'female') return values[1];
@@ -559,37 +593,37 @@ Tr8n.Proxy.GenderRule.prototype.evaluate = function(token_name, token_values) {
559
593
  var object = this.getTokenValue(token_name, token_values);
560
594
  if (!object) return false;
561
595
 
562
- var gender = "";
563
-
596
+ var gender = "";
597
+
564
598
  if (typeof object != 'object') {
565
599
  this.getLogger().error("Invalid token value for gender based token: " + token_name + ". Token value must be an object.");
566
- return false;
600
+ return false;
567
601
  }
568
602
 
569
- if (!object['subject']) {
570
- this.getLogger().error("Invalid token subject for gender based token: " + token_name + ". Token value must contain a subject. Subject can be a string or an object with a gender.");
571
- return false;
572
- }
573
-
603
+ if (!object['subject']) {
604
+ this.getLogger().error("Invalid token subject for gender based token: " + token_name + ". Token value must contain a subject. Subject can be a string or an object with a gender.");
605
+ return false;
606
+ }
607
+
574
608
  if (typeof object['subject'] == 'string') {
575
- gender = object['subject'];
609
+ gender = object['subject'];
576
610
  } else if (typeof object['subject'] == 'object') {
577
611
  gender = object['subject']['gender'];
578
- if (!gender) {
579
- this.getLogger().error("Cannot determine gender for token subject: " + token_name);
580
- return false;
581
- }
582
- } else {
612
+ if (!gender) {
613
+ this.getLogger().error("Cannot determine gender for token subject: " + token_name);
614
+ return false;
615
+ }
616
+ } else {
583
617
  this.getLogger().error("Invalid token subject for gender based token: " + token_name + ". Subject does not have a gender.");
584
- return false;
585
- }
586
-
618
+ return false;
619
+ }
620
+
587
621
  if (this.definition['operator'] == "is") {
588
- return (gender == this.definition['value']);
589
- } else if (this.definition['operator'] == "is_not") {
622
+ return (gender == this.definition['value']);
623
+ } else if (this.definition['operator'] == "is_not") {
590
624
  return (gender != this.definition['value']);
591
- }
592
-
625
+ }
626
+
593
627
  return false;
594
628
  }
595
629
 
@@ -624,7 +658,7 @@ Tr8n.Proxy.GenderListRule = function(definition, options) {
624
658
  Tr8n.Proxy.GenderListRule.prototype = new Tr8n.Proxy.LanguageRule();
625
659
 
626
660
  Tr8n.Proxy.GenderListRule.transform = function(object, values) {
627
- return "";
661
+ return "";
628
662
  }
629
663
 
630
664
  Tr8n.Proxy.GenderListRule.prototype.evaluate = function(token, token_values) {
@@ -663,94 +697,94 @@ Tr8n.Proxy.Token.prototype = {
663
697
  getLogger: function() {
664
698
  return this.getProxy().logger;
665
699
  },
666
- getExpression: function() {
667
- // must be implemented by the extending class
668
- return null;
669
- },
700
+ getExpression: function() {
701
+ // must be implemented by the extending class
702
+ return null;
703
+ },
670
704
  register: function(label, options) {
671
- if (this.getExpression() == null)
672
- alert("Token expression must be provided");
673
-
674
- var tokens = label.match(this.getExpression());
675
- if (!tokens) return [];
676
-
677
- var objects = [];
678
- var uniq = {};
679
- for(i=0; i<tokens.length; i++) {
680
- if (uniq[tokens[i]]) continue;
705
+ if (this.getExpression() == null)
706
+ alert("Token expression must be provided");
707
+
708
+ var tokens = label.match(this.getExpression());
709
+ if (!tokens) return [];
710
+
711
+ var objects = [];
712
+ var uniq = {};
713
+ for(i=0; i<tokens.length; i++) {
714
+ if (uniq[tokens[i]]) continue;
681
715
  options['proxy'].debug("Registering data token: " + tokens[i]);
682
- objects.push(new Tr8n.Proxy.TransformToken(label, tokens[i], options));
683
- uniq[tokens[i]] = true;
684
- }
685
- return objects;
686
- },
716
+ objects.push(new Tr8n.Proxy.TransformToken(label, tokens[i], options));
717
+ uniq[tokens[i]] = true;
718
+ }
719
+ return objects;
720
+ },
687
721
  getFullName: function() {
688
- return this.full_name;
689
- },
690
- getDeclaredName: function() {
691
- if (!this.declared_name) {
692
- this.declared_name = this.getFullName().replace(/[{}\[\]]/g, '');
693
- }
694
- return this.declared_name;
695
- },
696
- getName: function() {
697
- if (!this.name) {
698
- this.name = Tr8n.Proxy.Utils.trim(this.getDeclaredName().split(':')[0]);
699
- }
700
- return this.name;
701
- },
722
+ return this.full_name;
723
+ },
724
+ getDeclaredName: function() {
725
+ if (!this.declared_name) {
726
+ this.declared_name = this.getFullName().replace(/[{}\[\]]/g, '');
727
+ }
728
+ return this.declared_name;
729
+ },
730
+ getName: function() {
731
+ if (!this.name) {
732
+ this.name = Tr8n.Proxy.Utils.trim(this.getDeclaredName().split(':')[0]);
733
+ }
734
+ return this.name;
735
+ },
702
736
  getLanguageRule: function() {
703
-
704
- return null;
737
+
738
+ return null;
705
739
  },
706
740
  substitute: function(label, token_values) {
707
- var value = token_values[this.getName()];
708
-
709
- if (value == null) {
710
- this.getLogger().error("Value for token: " + this.getFullName() + " was not provided");
711
- return label;
712
- }
741
+ var value = token_values[this.getName()];
742
+
743
+ if (value == null) {
744
+ this.getLogger().error("Value for token: " + this.getFullName() + " was not provided");
745
+ return label;
746
+ }
713
747
 
714
748
  return Tr8n.Proxy.Utils.replaceAll(label, this.getFullName(), this.getTokenValue(value));
715
749
  },
716
- getTokenValue: function(token_value) {
717
- if (typeof token_value == 'string') return token_value;
750
+ getTokenValue: function(token_value) {
751
+ if (typeof token_value == 'string') return token_value;
718
752
  if (typeof token_value == 'number') return token_value;
719
753
  return token_value['value'];
720
- },
754
+ },
721
755
  getTokenObject: function(token_value) {
722
756
  if (typeof token_value == 'string') return token_value;
723
757
  if (typeof token_value == 'number') return token_value;
724
758
  return token_value['subject'];
725
- },
726
- getType: function() {
759
+ },
760
+ getType: function() {
727
761
  if (this.getDeclaredName().indexOf(':') == -1)
728
- return null;
729
-
730
- if (!this.type) {
731
- this.type = this.getDeclaredName().split('|')[0].split(':');
732
- this.type = this.type[this.type.length - 1];
733
- }
734
-
735
- return this.type;
736
- },
737
- getSuffix: function() {
738
- if (!this.suffix) {
739
- this.suffix = this.getName().split('_');
740
- this.suffix = this.suffix[this.suffix.length - 1];
741
- }
762
+ return null;
763
+
764
+ if (!this.type) {
765
+ this.type = this.getDeclaredName().split('|')[0].split(':');
766
+ this.type = this.type[this.type.length - 1];
767
+ }
768
+
769
+ return this.type;
770
+ },
771
+ getSuffix: function() {
772
+ if (!this.suffix) {
773
+ this.suffix = this.getName().split('_');
774
+ this.suffix = this.suffix[this.suffix.length - 1];
775
+ }
742
776
  return this.suffix;
743
- },
744
- getLanguageRule: function() {
745
- if (!this.language_rule) {
746
- if (this.getType()) {
747
- this.language_rule = this.getProxy().getLanguageRuleForType(this.getType());
748
- } else {
749
- this.language_rule = this.getProxy().getLanguageRuleForTokenSuffix(this.getSuffix());
750
- }
751
- }
752
- return this.language_rule;
753
- }
777
+ },
778
+ getLanguageRule: function() {
779
+ if (!this.language_rule) {
780
+ if (this.getType()) {
781
+ this.language_rule = this.getProxy().getLanguageRuleForType(this.getType());
782
+ } else {
783
+ this.language_rule = this.getProxy().getLanguageRuleForTokenSuffix(this.getSuffix());
784
+ }
785
+ }
786
+ return this.language_rule;
787
+ }
754
788
  }
755
789
 
756
790
  /****************************************************************************
@@ -766,18 +800,18 @@ Tr8n.Proxy.DataToken = function(label, token, options) {
766
800
  Tr8n.Proxy.DataToken.prototype = new Tr8n.Proxy.Token();
767
801
 
768
802
  Tr8n.Proxy.DataToken.parse = function(label, options) {
769
- var tokens = label.match(/(\{[^_][\w]+(:[\w]+)?\})/g);
770
- if (!tokens) return [];
771
-
772
- var objects = [];
773
- var uniq = {};
774
- for(i=0; i<tokens.length; i++) {
775
- if (uniq[tokens[i]]) continue;
803
+ var tokens = label.match(/(\{[^_][\w]+(:[\w]+)?\})/g);
804
+ if (!tokens) return [];
805
+
806
+ var objects = [];
807
+ var uniq = {};
808
+ for(i=0; i<tokens.length; i++) {
809
+ if (uniq[tokens[i]]) continue;
776
810
  options['proxy'].debug("Registering data token: " + tokens[i]);
777
- objects.push(new Tr8n.Proxy.DataToken(label, tokens[i], options));
811
+ objects.push(new Tr8n.Proxy.DataToken(label, tokens[i], options));
778
812
  uniq[tokens[i]] = true;
779
- }
780
- return objects;
813
+ }
814
+ return objects;
781
815
  }
782
816
 
783
817
  /****************************************************************************
@@ -816,12 +850,12 @@ Tr8n.Proxy.TransformToken.prototype.getName = function() {
816
850
 
817
851
  Tr8n.Proxy.TransformToken.prototype.getPipedParams = function() {
818
852
  if (!this.piped_params) {
819
- var temp = this.getDeclaredName().split('|');
820
- temp = temp[temp.length - 1].split(",");
821
- this.piped_params = [];
822
- for (i=0; i<temp.length; i++) {
823
- this.piped_params.push(Tr8n.Proxy.Utils.trim(temp[i]));
824
- }
853
+ var temp = this.getDeclaredName().split('|');
854
+ temp = temp[temp.length - 1].split(",");
855
+ this.piped_params = [];
856
+ for (i=0; i<temp.length; i++) {
857
+ this.piped_params.push(Tr8n.Proxy.Utils.trim(temp[i]));
858
+ }
825
859
  }
826
860
  return this.piped_params;
827
861
  }
@@ -833,39 +867,39 @@ Tr8n.Proxy.TransformToken.prototype.substitute = function(label, token_values) {
833
867
  return label;
834
868
  }
835
869
 
836
- var token_object = this.getTokenObject(object);
870
+ var token_object = this.getTokenObject(object);
837
871
  this.getLogger().debug("Registered " + this.getPipedParams().length + " piped params");
838
-
839
- var lang_rule_name = this.getLanguageRule();
840
-
841
- if (!lang_rule_name) {
872
+
873
+ var lang_rule_name = this.getLanguageRule();
874
+
875
+ if (!lang_rule_name) {
842
876
  this.getLogger().error("Rule type cannot be determined for the transform token: " + this.getFullName());
843
877
  return label;
844
- } else {
878
+ } else {
845
879
  this.getLogger().debug("Transform token uses rule: " + lang_rule_name);
846
- }
880
+ }
847
881
 
848
882
  var transform_value = eval(lang_rule_name).transform(token_object, this.getPipedParams());
849
883
  this.getLogger().debug("Registered transform value: " + transform_value);
850
-
851
- // for double pipes - show the actual value as well
852
- if (this.isAllowedInTranslation()) {
884
+
885
+ // for double pipes - show the actual value as well
886
+ if (this.isAllowedInTranslation()) {
853
887
  var token_value = this.getTokenValue(object);
854
- transform_value = token_value + " " + transform_value;
855
- }
856
-
888
+ transform_value = token_value + " " + transform_value;
889
+ }
890
+
857
891
  return Tr8n.Proxy.Utils.replaceAll(label, this.getFullName(), transform_value);
858
892
  }
859
893
 
860
894
  Tr8n.Proxy.TransformToken.prototype.getPipedSeparator = function() {
861
- if (!this.piped_separator) {
862
- this.piped_separator = (this.getFullName().indexOf("||") != -1 ? "||" : "|");
863
- }
864
- return this.piped_separator;
895
+ if (!this.piped_separator) {
896
+ this.piped_separator = (this.getFullName().indexOf("||") != -1 ? "||" : "|");
897
+ }
898
+ return this.piped_separator;
865
899
  }
866
900
 
867
901
  Tr8n.Proxy.TransformToken.prototype.isAllowedInTranslation = function(){
868
- return this.getPipedSeparator() == "||";
902
+ return this.getPipedSeparator() == "||";
869
903
  }
870
904
 
871
905
  /****************************************************************************
@@ -897,17 +931,17 @@ Tr8n.Proxy.DecorationToken.parse = function(label, options) {
897
931
 
898
932
  Tr8n.Proxy.DecorationToken.prototype.getDecoratedValue = function() {
899
933
  if (!this.decorated_value) {
900
- var value = this.getFullName().replace(/[\]]/g, '');
901
- value = value.substring(value.indexOf(':') + 1, value.length);
934
+ var value = this.getFullName().replace(/[\]]/g, '');
935
+ value = value.substring(value.indexOf(':') + 1, value.length);
902
936
  this.decorated_value = Tr8n.Proxy.Utils.trim(value);
903
- }
937
+ }
904
938
  return this.decorated_value;
905
939
  }
906
940
 
907
941
  Tr8n.Proxy.DecorationToken.prototype.substitute = function(label, token_values) {
908
942
  var object = token_values[this.getName()];
909
- var decoration = object;
910
-
943
+ var decoration = object;
944
+
911
945
  if (!object || typeof object == 'object') {
912
946
  // look for the default decoration
913
947
  decoration = this.getProxy().getDecorationFor(this.getName());
@@ -917,18 +951,18 @@ Tr8n.Proxy.DecorationToken.prototype.substitute = function(label, token_values)
917
951
  }
918
952
 
919
953
  decoration = Tr8n.Proxy.Utils.replaceAll(decoration, '{$0}', this.getDecoratedValue());
920
- if (object) {
921
- for (var key in object) {
954
+ if (object) {
955
+ for (var key in object) {
922
956
  decoration = Tr8n.Proxy.Utils.replaceAll(decoration, '{$' + key + '}', object[key]);
923
- }
924
- }
957
+ }
958
+ }
925
959
  } else if (typeof object == 'string') {
926
- decoration = Tr8n.Proxy.Utils.replaceAll(decoration, '{$0}', this.getDecoratedValue());
927
- } else {
960
+ decoration = Tr8n.Proxy.Utils.replaceAll(decoration, '{$0}', this.getDecoratedValue());
961
+ } else {
928
962
  this.getLogger().error("Unknown type of decoration token " + this.getFullName());
929
963
  return label;
930
- }
931
-
964
+ }
965
+
932
966
  return Tr8n.Proxy.Utils.replaceAll(label, this.getFullName(), decoration);
933
967
  }
934
968
 
@@ -938,65 +972,227 @@ Tr8n.Proxy.DecorationToken.prototype.substitute = function(label, token_values)
938
972
 
939
973
  Tr8n.Proxy.Logger = function(options) {
940
974
  this.options = options;
975
+ this.object_keys = [];
941
976
  }
942
977
 
943
978
  Tr8n.Proxy.Logger.prototype = {
979
+ clear: function() {
980
+ if (!this.options['proxy'].logger_enabled) return;
981
+ if (!this.options['element_id']) return;
982
+ if (!Tr8n.Proxy.Utils.element(this.options['element_id'])) return;
983
+ Tr8n.element(this.options['element_id']).innerHTML = "";
984
+ },
985
+ append: function(msg) {
986
+ if (!this.options['proxy'].logger_enabled) return;
987
+ if (!this.options['element_id']) return;
988
+ if (!Tr8n.Proxy.Utils.element(this.options['element_id'])) return;
989
+
990
+ var str = msg + "<br>" + Tr8n.Proxy.Utils.element(this.options['element_id']).innerHTML;
991
+ Tr8n.element(this.options['element_id']).innerHTML = str;
992
+ },
944
993
  log: function(msg) {
945
- if (!this.options['proxy'].logger_enabled) return;
946
- if (!this.options['element_id']) return;
947
-
948
- var str = Tr8n.Proxy.Utils.element(this.options['element_id']).innerHTML;
949
- var now = new Date();
950
- str = "<span style='color:#ccc;'>" + (now.toLocaleDateString() + " " + now.toLocaleTimeString()) + "</span>: " + msg + "<br>" + str;
951
- Tr8n.Proxy.Utils.element(this.options['element_id']).innerHTML = str;
952
- },
994
+ if (!this.options['proxy'].logger_enabled) return;
995
+ var now = new Date();
996
+ var str = "<span style='color:#ccc;'>" + (now.toLocaleDateString() + " " + now.toLocaleTimeString()) + "</span>: " + msg;
997
+ this.append(str);
998
+ },
953
999
  debug: function(msg) {
954
1000
  this.log("<span style='color:grey'>" + msg + "</span>");
955
1001
  },
956
1002
  error: function(msg) {
957
- this.log("<span style='color:red'>" + msg + "</span>");
1003
+ this.log("<span style='color:red'>" + msg + "</span>");
1004
+ },
1005
+ S4: function() {
1006
+ return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
1007
+ },
1008
+ guid: function() {
1009
+ return (this.S4()+this.S4()+"-"+this.S4()+"-"+this.S4()+"-"+this.S4()+"-"+this.S4()+this.S4()+this.S4());
1010
+ },
1011
+ escapeHTML: function(str) {
1012
+ return( str.replace(/&/g,'&amp;').replace(/>/g,'&gt;').replace(/</g,'&lt;').replace(/"/g,'&quot;'));
1013
+ },
1014
+ showObject: function (obj_key, flag) {
1015
+ if (flag) {
1016
+ Tr8n.Proxy.Utils.hide("no_object_" + obj_key);
1017
+ Tr8n.Proxy.Utils.show("object_" + obj_key);
1018
+ Tr8n.element("expander_" + obj_key).innerHTML = "<img src='/assets/tr8n/minus_node.png'>";
1019
+ } else {
1020
+ Tr8n.Proxy.Utils.hide("object_" + obj_key);
1021
+ Tr8n.Proxy.Utils.show("no_object_" + obj_key);
1022
+ Tr8n.element("expander_" + obj_key).innerHTML = "<img src='/assets/tr8n/plus_node.png'>";
1023
+ }
1024
+ },
1025
+ toggleNode: function(obj_key) {
1026
+ this.showObject(obj_key, (Tr8n.element("object_" + obj_key).style.display == 'none'));
1027
+ },
1028
+ expandAllNodes: function() {
1029
+ for (var i=0; i<this.object_keys.length; i++) {
1030
+ this.showObject(this.object_keys[i], true);
1031
+ }
1032
+ },
1033
+ collapseAllNodes: function() {
1034
+ for (var i=0; i<this.object_keys.length; i++) {
1035
+ this.showObject(this.object_keys[i], false);
1036
+ }
1037
+ },
1038
+ logObject: function(data) {
1039
+ this.object_keys = [];
1040
+ html = []
1041
+ html.push("<div style='float:right;padding-right:10px;'>");
1042
+ html.push("<span style='padding:2px;' onClick=\"tr8nProxy.logger.expandAllNodes()\"><img src='/assets/tr8n/plus_node.png'></span>");
1043
+ html.push("<span style='padding:2px;' onClick=\"tr8nProxy.logger.collapseAllNodes()\"><img src='/assets/tr8n/minus_node.png'></span>");
1044
+ html.push("</div>");
1045
+
1046
+ var results = data;
1047
+ if (typeof results == 'string') {
1048
+ try {
1049
+ results = eval("[" + results + "]")[0];
1050
+ }
1051
+ catch (err) {
1052
+ this.push(results);
1053
+ return;
1054
+ }
1055
+ }
1056
+ if (typeof results == 'object') {
1057
+ html.push(this.formatObject(results, 1));
1058
+ } else {
1059
+ html.push(results);
1060
+ }
1061
+ this.append(html.join(""));
1062
+ },
1063
+ formatObject: function(obj, level) {
1064
+ if (obj == null) return "{<br>}";
1065
+
1066
+ var html = [];
1067
+ var obj_key = this.guid();
1068
+ html.push("<span class='tr8n_logger_expander' id='expander_" + obj_key + "' onClick=\"tr8nProxy.logger.toggleNode('" + obj_key + "')\"><img src='/assets/tr8n/minus_node.png'></span> <span style='display:none' id='no_object_" + obj_key + "'>{...}</span> <span id='object_" + obj_key + "'>{");
1069
+ this.object_keys.push(obj_key);
1070
+
1071
+ var keys = Object.keys(obj).sort();
1072
+
1073
+ for (var i=0; i<keys.length; i++) {
1074
+ key = keys[i];
1075
+ if (this.isObject(obj[key])) {
1076
+ if (this.isArray(obj[key])) {
1077
+ html.push(this.createSpacer(level) + "<span class='tr8n_logger_obj_key'>" + key + ":</span>" + this.formatArray(obj[key], level + 1) + ",");
1078
+ } else {
1079
+ html.push(this.createSpacer(level) + "<span class='tr8n_logger_obj_key'>" + key + ":</span>" + this.formatObject(obj[key], level + 1) + ",");
1080
+ }
1081
+ } else {
1082
+ html.push(this.createSpacer(level) + this.formatProperty(key, obj[key]) + ",");
1083
+ }
1084
+ }
1085
+ html.push(this.createSpacer(level-1) + "}</span>");
1086
+ return html.join("<br>");
1087
+ },
1088
+ formatArray: function(arr, level) {
1089
+ if (arr == null) return "[<br>]";
1090
+
1091
+ var html = [];
1092
+ var obj_key = this.guid();
1093
+ html.push("<span class='tr8n_logger_expander' id='expander_" + obj_key + "' onClick=\"tr8nProxy.logger.toggleNode('" + obj_key + "')\"><img src='/assets/tr8n/minus_node.png'></span> <span style='display:none' id='no_object_" + obj_key + "'>[...]</span> <span id='object_" + obj_key + "'>[");
1094
+ this.object_keys.push(obj_key);
1095
+
1096
+ for (var i=0; i<arr.length; i++) {
1097
+ if (this.isObject(arr[i])) {
1098
+ if (this.isArray(arr[i])) {
1099
+ html.push(this.createSpacer(level) + this.formatArray(arr[i], level + 1) + ",");
1100
+ } else {
1101
+ html.push(this.createSpacer(level) + this.formatObject(arr[i], level + 1) + ",");
1102
+ }
1103
+ } else {
1104
+ html.push(this.createSpacer(level) + this.formatProperty(null, arr[i]) + ",");
1105
+ }
1106
+ }
1107
+ html.push(this.createSpacer(level-1) + "]</span>");
1108
+ return html.join("<br>");
1109
+ },
1110
+ formatProperty: function(key, value) {
1111
+ if (value == null) return "<span class='tr8n_logger_obj_key'>" + key + ":</span><span class='obj_value_null'>null</span>";
1112
+
1113
+ var cls = "tr8n_logger_obj_value_" + (typeof value);
1114
+ var value_span = "";
1115
+
1116
+ if (this.isString(value))
1117
+ value_span = "<span class='" + cls + "'>\"" + this.escapeHTML(value) + "\"</span>";
1118
+ else
1119
+ value_span = "<span class='" + cls + "'>" + value + "</span>";
1120
+
1121
+ if (key == null)
1122
+ return value_span;
1123
+
1124
+ return "<span class='tr8n_logger_obj_key'>" + key + ":</span>" + value_span;
1125
+ },
1126
+ createSpacer: function(level) {
1127
+ return "<img src='/assets/tr8n/pixel.gif' style='height:1px;width:" + (level * 20) + "px;'>";
1128
+ },
1129
+ isArray: function(obj) {
1130
+ if (obj == null) return false;
1131
+ return !(obj.constructor.toString().indexOf("Array") == -1);
1132
+ },
1133
+ isObject: function(obj) {
1134
+ if (obj == null) return false;
1135
+ return (typeof obj == 'object');
1136
+ },
1137
+ isString: function(obj) {
1138
+ return (typeof obj == 'string');
1139
+ },
1140
+ isURL: function(str) {
1141
+ str = "" + str;
1142
+ return (str.indexOf("http://") != -1) || (str.indexOf("https://") != -1);
958
1143
  }
959
1144
  }
960
1145
 
1146
+
1147
+
961
1148
  /****************************************************************************
962
1149
  **** Tr8n Proxy Utils
963
1150
  ****************************************************************************/
964
1151
 
965
1152
  Tr8n.Proxy.Utils = {
966
-
1153
+
967
1154
  element:function(element_id) {
968
1155
  if (typeof element_id == 'string') return document.getElementById(element_id);
969
1156
  return element_id;
970
1157
  },
971
1158
 
972
- indexOf: function(array, item, i) {
973
- i || (i = 0);
974
- var length = array.length;
975
- if (i < 0) i = length + i;
976
- for (; i < length; i++)
977
- if (array[i] === item) return i;
978
- return -1;
979
- },
980
-
981
- replaceAll: function(label, key, value) {
982
- while (label.indexOf(key) != -1) {
983
- label = label.replace(key, value);
984
- }
985
- return label;
986
- },
987
-
988
- trim: function(string) {
989
- return string.replace(/^\s+|\s+$/g,"");
990
- },
991
-
992
- ltrim: function(string) {
993
- return string.replace(/^\s+/,"");
994
- },
995
-
996
- rtrim: function(string) {
997
- return string.replace(/\s+$/,"");
998
- },
999
-
1159
+ hide: function(element_id) {
1160
+ Tr8n.element(element_id).style.display = "none";
1161
+ },
1162
+
1163
+ show: function(element_id) {
1164
+ var style = (Tr8n.element(element_id).tagName == "SPAN") ? "inline" : "block";
1165
+ Tr8n.element(element_id).style.display = style;
1166
+ },
1167
+
1168
+ indexOf: function(array, item, i) {
1169
+ i || (i = 0);
1170
+ var length = array.length;
1171
+ if (i < 0) i = length + i;
1172
+ for (; i < length; i++)
1173
+ if (array[i] === item) return i;
1174
+ return -1;
1175
+ },
1176
+
1177
+ replaceAll: function(label, key, value) {
1178
+ while (label.indexOf(key) != -1) {
1179
+ label = label.replace(key, value);
1180
+ }
1181
+ return label;
1182
+ },
1183
+
1184
+ trim: function(string) {
1185
+ return string.replace(/^\s+|\s+$/g,"");
1186
+ },
1187
+
1188
+ ltrim: function(string) {
1189
+ return string.replace(/^\s+/,"");
1190
+ },
1191
+
1192
+ rtrim: function(string) {
1193
+ return string.replace(/\s+$/,"");
1194
+ },
1195
+
1000
1196
  addEvent: function(elm, evType, fn, useCapture) {
1001
1197
  useCapture = useCapture || false;
1002
1198
  if (elm.addEventListener) {
@@ -1064,47 +1260,7 @@ Tr8n.Proxy.Utils = {
1064
1260
  request.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
1065
1261
  request.setRequestHeader('Accept', 'text/javascript, text/html, application/xml, text/xml, */*');
1066
1262
  request.send(options.parameters);
1067
- }
1068
- }
1069
-
1070
- /****************************************************************************
1071
- **** Tr8n Proxy Initialization
1072
- ****************************************************************************/
1073
- var tr8nProxy;
1074
-
1075
- //
1076
- // the following should be done by the tr8n_client_sdk_scripts_tag
1077
- //
1078
-
1079
- //function initializeTr8nClientSDK(source, debugger) {
1080
- // tr8nProxy = tr8nProxy || new Tr8n.Proxy({
1081
- // "default_source": source,
1082
- // "debugger_element_id": debugger,
1083
- // "default_decorations": {"bold": "<strong>{$0}</strong>", "italic": "<i>{$0}</i>", "link": "<a href='{$href}'>{$0}</a>"},
1084
- // "rules": {"number":{"token_suffixes":["count", "num"]},
1085
- // "gender":{"token_suffixes":["user", "profile", "actor", "target"]},
1086
- // "list":{"token_suffixes":["list"]}, "date":{"token_suffixes":["date"]}
1087
- // }
1088
- // });
1089
- //}
1090
-
1091
- // global javascript method
1092
- function reloadTranslations() {
1093
- tr8nProxy.initTranslations(true);
1094
- }
1095
-
1096
- // global javascript method - can be used after initialization
1097
- function tr(label, description, tokens, options) {
1098
- // tr8nProxy.logger.log("Translating: " + label);
1099
- return tr8nProxy.translate(label, description || '', tokens || {}, options || {});
1100
- }
1101
-
1102
- // global javascript method - can be used after initialization
1103
- function trl(label, description, tokens, options) {
1104
- // tr8nProxy.logger.log("Translating: " + label);
1105
- options = options || {};
1106
- options['skip_decorations'] = true;
1107
- return tr8nProxy.translate(label, description || '', tokens || {}, options);
1263
+ }
1108
1264
  }
1109
1265
 
1110
1266
  /****************************************************************************
@@ -1313,4 +1469,4 @@ var MD5 = function (string) {
1313
1469
  var temp = WordToHex(a)+WordToHex(b)+WordToHex(c)+WordToHex(d);
1314
1470
 
1315
1471
  return temp.toLowerCase();
1316
- }
1472
+ }