tr8n 3.0.2
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.
- data/.project +18 -0
- data/Gemfile +34 -0
- data/Gemfile.lock +79 -0
- data/LICENSE +18 -0
- data/README.rdoc +116 -0
- data/Rakefile +29 -0
- data/VERSION +1 -0
- data/app/controllers/application_controller.rb +28 -0
- data/app/controllers/tr8n/admin/base_controller.rb +65 -0
- data/app/controllers/tr8n/admin/clientsdk_controller.rb +34 -0
- data/app/controllers/tr8n/admin/domain_controller.rb +77 -0
- data/app/controllers/tr8n/admin/forum_controller.rb +58 -0
- data/app/controllers/tr8n/admin/glossary_controller.rb +56 -0
- data/app/controllers/tr8n/admin/language_controller.rb +129 -0
- data/app/controllers/tr8n/admin/translation_controller.rb +64 -0
- data/app/controllers/tr8n/admin/translation_key_controller.rb +157 -0
- data/app/controllers/tr8n/admin/translator_controller.rb +119 -0
- data/app/controllers/tr8n/api/v1/base_controller.rb +81 -0
- data/app/controllers/tr8n/api/v1/language_controller.rb +107 -0
- data/app/controllers/tr8n/api/v1/translation_controller.rb +75 -0
- data/app/controllers/tr8n/api/v1/translator_controller.rb +34 -0
- data/app/controllers/tr8n/awards_controller.rb +43 -0
- data/app/controllers/tr8n/base_controller.rb +206 -0
- data/app/controllers/tr8n/dashboard_controller.rb +32 -0
- data/app/controllers/tr8n/forum_controller.rb +100 -0
- data/app/controllers/tr8n/glossary_controller.rb +40 -0
- data/app/controllers/tr8n/help_controller.rb +40 -0
- data/app/controllers/tr8n/home_controller.rb +51 -0
- data/app/controllers/tr8n/language_cases_controller.rb +82 -0
- data/app/controllers/tr8n/language_controller.rb +372 -0
- data/app/controllers/tr8n/login_controller.rb +86 -0
- data/app/controllers/tr8n/phrases_controller.rb +293 -0
- data/app/controllers/tr8n/translations_controller.rb +194 -0
- data/app/controllers/tr8n/translator_controller.rb +83 -0
- data/app/helpers/application_helper.rb +27 -0
- data/app/helpers/tr8n/admin/base_helper.rb +84 -0
- data/app/helpers/tr8n/base_helper.rb +44 -0
- data/app/helpers/tr8n/dashboard_helper.rb +43 -0
- data/app/models/tr8n/base_filter.rb +68 -0
- data/app/models/tr8n/daily_language_metric.rb +42 -0
- data/app/models/tr8n/date_rule.rb +123 -0
- data/app/models/tr8n/gender_list_rule.rb +247 -0
- data/app/models/tr8n/gender_rule.rb +140 -0
- data/app/models/tr8n/glossary.rb +27 -0
- data/app/models/tr8n/glossary_filter.rb +33 -0
- data/app/models/tr8n/integration/ru/russian_gender_list_rule.rb +60 -0
- data/app/models/tr8n/integration/ru/russian_numeric_rule.rb +64 -0
- data/app/models/tr8n/ip_location.rb +74 -0
- data/app/models/tr8n/ip_location_filter.rb +34 -0
- data/app/models/tr8n/language.rb +318 -0
- data/app/models/tr8n/language_case.rb +141 -0
- data/app/models/tr8n/language_case_filter.rb +30 -0
- data/app/models/tr8n/language_case_rule.rb +187 -0
- data/app/models/tr8n/language_case_rule_filter.rb +30 -0
- data/app/models/tr8n/language_case_value_map.rb +100 -0
- data/app/models/tr8n/language_case_value_map_filter.rb +41 -0
- data/app/models/tr8n/language_filter.rb +75 -0
- data/app/models/tr8n/language_forum_abuse_report.rb +33 -0
- data/app/models/tr8n/language_forum_abuse_report_filter.rb +30 -0
- data/app/models/tr8n/language_forum_message.rb +46 -0
- data/app/models/tr8n/language_forum_message_filter.rb +34 -0
- data/app/models/tr8n/language_forum_topic.rb +41 -0
- data/app/models/tr8n/language_forum_topic_filter.rb +34 -0
- data/app/models/tr8n/language_metric.rb +91 -0
- data/app/models/tr8n/language_metric_filter.rb +63 -0
- data/app/models/tr8n/language_rule.rb +117 -0
- data/app/models/tr8n/language_rule_filter.rb +45 -0
- data/app/models/tr8n/language_user.rb +61 -0
- data/app/models/tr8n/language_user_filter.rb +34 -0
- data/app/models/tr8n/list_rule.rb +118 -0
- data/app/models/tr8n/monthly_language_metric.rb +34 -0
- data/app/models/tr8n/numeric_rule.rb +175 -0
- data/app/models/tr8n/total_language_metric.rb +59 -0
- data/app/models/tr8n/translation.rb +299 -0
- data/app/models/tr8n/translation_domain.rb +48 -0
- data/app/models/tr8n/translation_domain_filter.rb +26 -0
- data/app/models/tr8n/translation_filter.rb +34 -0
- data/app/models/tr8n/translation_key.rb +625 -0
- data/app/models/tr8n/translation_key_comment.rb +37 -0
- data/app/models/tr8n/translation_key_comment_filter.rb +30 -0
- data/app/models/tr8n/translation_key_filter.rb +45 -0
- data/app/models/tr8n/translation_key_lock.rb +59 -0
- data/app/models/tr8n/translation_key_lock_filter.rb +30 -0
- data/app/models/tr8n/translation_key_source.rb +58 -0
- data/app/models/tr8n/translation_key_source_filter.rb +30 -0
- data/app/models/tr8n/translation_source.rb +52 -0
- data/app/models/tr8n/translation_source_filter.rb +30 -0
- data/app/models/tr8n/translation_vote.rb +36 -0
- data/app/models/tr8n/translation_vote_filter.rb +34 -0
- data/app/models/tr8n/translator.rb +301 -0
- data/app/models/tr8n/translator_filter.rb +46 -0
- data/app/models/tr8n/translator_following.rb +38 -0
- data/app/models/tr8n/translator_following_filter.rb +34 -0
- data/app/models/tr8n/translator_log.rb +120 -0
- data/app/models/tr8n/translator_log_filter.rb +49 -0
- data/app/models/tr8n/translator_metric.rb +83 -0
- data/app/models/tr8n/translator_metric_filter.rb +38 -0
- data/app/models/tr8n/translator_report.rb +82 -0
- data/app/models/tr8n/translator_report_filter.rb +30 -0
- data/app/models/tr8n/value_rule.rb +117 -0
- data/app/views/layouts/_footer.html.erb +15 -0
- data/app/views/layouts/_header.html.erb +12 -0
- data/app/views/layouts/_html_head.html.erb +5 -0
- data/app/views/layouts/tr8n.html.erb +21 -0
- data/app/views/layouts/tr8n_admin.html.erb +33 -0
- data/app/views/tr8n/admin/clientsdk/index.html.erb +133 -0
- data/app/views/tr8n/admin/clientsdk/lb_samples.html.erb +54 -0
- data/app/views/tr8n/admin/common/_footer.html.erb +1 -0
- data/app/views/tr8n/admin/common/_header.html.erb +30 -0
- data/app/views/tr8n/admin/common/_lightbox_buttons.html.erb +5 -0
- data/app/views/tr8n/admin/common/_paginator.html.erb +20 -0
- data/app/views/tr8n/admin/domain/_tabs.html.erb +23 -0
- data/app/views/tr8n/admin/domain/index.html.erb +33 -0
- data/app/views/tr8n/admin/domain/key_sources.rhtml +53 -0
- data/app/views/tr8n/admin/domain/lb_caller.html.erb +35 -0
- data/app/views/tr8n/admin/domain/sources.html.erb +35 -0
- data/app/views/tr8n/admin/forum/_tabs.html.erb +22 -0
- data/app/views/tr8n/admin/forum/index.html.erb +34 -0
- data/app/views/tr8n/admin/forum/messages.html.erb +33 -0
- data/app/views/tr8n/admin/forum/reports.html.erb +50 -0
- data/app/views/tr8n/admin/glossary/index.html.erb +22 -0
- data/app/views/tr8n/admin/glossary/lb_update.html.erb +26 -0
- data/app/views/tr8n/admin/language/_rules.html.erb +22 -0
- data/app/views/tr8n/admin/language/_tabs.html.erb +27 -0
- data/app/views/tr8n/admin/language/_users.html.erb +40 -0
- data/app/views/tr8n/admin/language/case_rules.html.erb +24 -0
- data/app/views/tr8n/admin/language/case_values.html.erb +25 -0
- data/app/views/tr8n/admin/language/cases.html.erb +24 -0
- data/app/views/tr8n/admin/language/charts.html.erb +35 -0
- data/app/views/tr8n/admin/language/index.html.erb +99 -0
- data/app/views/tr8n/admin/language/lb_update.html.erb +76 -0
- data/app/views/tr8n/admin/language/lb_value_map.html.erb +42 -0
- data/app/views/tr8n/admin/language/metrics.rhtml +16 -0
- data/app/views/tr8n/admin/language/rules.html.erb +24 -0
- data/app/views/tr8n/admin/language/users.rhtml +31 -0
- data/app/views/tr8n/admin/language/view.html.erb +106 -0
- data/app/views/tr8n/admin/translation/_tabs.html.erb +21 -0
- data/app/views/tr8n/admin/translation/index.html.erb +75 -0
- data/app/views/tr8n/admin/translation/view.html.erb +142 -0
- data/app/views/tr8n/admin/translation/votes.rhtml +81 -0
- data/app/views/tr8n/admin/translation_key/_tabs.html.erb +22 -0
- data/app/views/tr8n/admin/translation_key/comments.html.erb +49 -0
- data/app/views/tr8n/admin/translation_key/index.html.erb +79 -0
- data/app/views/tr8n/admin/translation_key/lb_merge.html.erb +43 -0
- data/app/views/tr8n/admin/translation_key/lb_update.html.erb +44 -0
- data/app/views/tr8n/admin/translation_key/locks.html.erb +51 -0
- data/app/views/tr8n/admin/translation_key/view.html.erb +192 -0
- data/app/views/tr8n/admin/translator/_list.html.erb +51 -0
- data/app/views/tr8n/admin/translator/_tabs.html.erb +26 -0
- data/app/views/tr8n/admin/translator/following.html.erb +20 -0
- data/app/views/tr8n/admin/translator/index.html.erb +77 -0
- data/app/views/tr8n/admin/translator/ip_locations.html.erb +9 -0
- data/app/views/tr8n/admin/translator/lb_register.html.erb +18 -0
- data/app/views/tr8n/admin/translator/log.html.erb +27 -0
- data/app/views/tr8n/admin/translator/metrics.html.erb +25 -0
- data/app/views/tr8n/admin/translator/reports.html.erb +22 -0
- data/app/views/tr8n/admin/translator/view.html.erb +228 -0
- data/app/views/tr8n/awards/_list.html.erb +46 -0
- data/app/views/tr8n/awards/index.html.erb +42 -0
- data/app/views/tr8n/common/_flashes.html.erb +39 -0
- data/app/views/tr8n/common/_footer.html.erb +1 -0
- data/app/views/tr8n/common/_header.html.erb +5 -0
- data/app/views/tr8n/common/_language_selector.html.erb +8 -0
- data/app/views/tr8n/common/_language_strip.html.erb +29 -0
- data/app/views/tr8n/common/_language_table.html.erb +13 -0
- data/app/views/tr8n/common/_paginator.html.erb +8 -0
- data/app/views/tr8n/common/_permutations.html.erb +37 -0
- data/app/views/tr8n/common/_scripts.html.erb +49 -0
- data/app/views/tr8n/common/_splash_screen.html.erb +9 -0
- data/app/views/tr8n/common/_splash_screen_legacy.html.erb +4 -0
- data/app/views/tr8n/common/_tabs.html.erb +39 -0
- data/app/views/tr8n/common/_translation_votes.html.erb +41 -0
- data/app/views/tr8n/common/_translator_login.html.erb +11 -0
- data/app/views/tr8n/dashboard/_forum.html.erb +25 -0
- data/app/views/tr8n/dashboard/_language_metric.html.erb +49 -0
- data/app/views/tr8n/dashboard/_statistics.html.erb +35 -0
- data/app/views/tr8n/dashboard/_translations.html.erb +24 -0
- data/app/views/tr8n/dashboard/_translator_metric.html.erb +68 -0
- data/app/views/tr8n/dashboard/_votes.html.erb +76 -0
- data/app/views/tr8n/dashboard/index.rhtml +115 -0
- data/app/views/tr8n/forum/_message.html.erb +17 -0
- data/app/views/tr8n/forum/_messages.html.erb +21 -0
- data/app/views/tr8n/forum/_new_message.html.erb +28 -0
- data/app/views/tr8n/forum/_new_topic.html.erb +49 -0
- data/app/views/tr8n/forum/index.html.erb +84 -0
- data/app/views/tr8n/forum/topic.html.erb +36 -0
- data/app/views/tr8n/glossary/index.html.erb +42 -0
- data/app/views/tr8n/help/_navigation.html.erb +127 -0
- data/app/views/tr8n/help/awards.html.erb +13 -0
- data/app/views/tr8n/help/basic_information.html.erb +13 -0
- data/app/views/tr8n/help/context_rules.html.erb +13 -0
- data/app/views/tr8n/help/creating_translations.html.erb +16 -0
- data/app/views/tr8n/help/dashboard.html.erb +13 -0
- data/app/views/tr8n/help/direction.html.erb +13 -0
- data/app/views/tr8n/help/discussions.html.erb +13 -0
- data/app/views/tr8n/help/enter_translation.html.erb +13 -0
- data/app/views/tr8n/help/fallback_language.html.erb +13 -0
- data/app/views/tr8n/help/generate_context_rules.html.erb +17 -0
- data/app/views/tr8n/help/index.html.erb +18 -0
- data/app/views/tr8n/help/inline_translations.html.erb +28 -0
- data/app/views/tr8n/help/language_dashboard.html.erb +21 -0
- data/app/views/tr8n/help/language_phrases.html.erb +17 -0
- data/app/views/tr8n/help/language_selector.html.erb +13 -0
- data/app/views/tr8n/help/language_statistics.html.erb +13 -0
- data/app/views/tr8n/help/lb_credits.html.erb +9 -0
- data/app/views/tr8n/help/lb_shortcuts.html.erb +26 -0
- data/app/views/tr8n/help/manage.html.erb +13 -0
- data/app/views/tr8n/help/manage_language.html.erb +13 -0
- data/app/views/tr8n/help/native_name.html.erb +13 -0
- data/app/views/tr8n/help/original_phrase.html.erb +13 -0
- data/app/views/tr8n/help/other_languages.html.erb +15 -0
- data/app/views/tr8n/help/other_translatable_resources.html.erb +13 -0
- data/app/views/tr8n/help/phrases.html.erb +19 -0
- data/app/views/tr8n/help/phrases_with_translations.html.erb +21 -0
- data/app/views/tr8n/help/phrases_without_translations.html.erb +15 -0
- data/app/views/tr8n/help/prohibited_words.html.erb +13 -0
- data/app/views/tr8n/help/rank.html.erb +13 -0
- data/app/views/tr8n/help/recent_discussions.html.erb +13 -0
- data/app/views/tr8n/help/recent_translation_votes.html.erb +13 -0
- data/app/views/tr8n/help/recent_translations.html.erb +13 -0
- data/app/views/tr8n/help/site_map.html.erb +17 -0
- data/app/views/tr8n/help/site_sections.html.erb +13 -0
- data/app/views/tr8n/help/suggested_translation.html.erb +13 -0
- data/app/views/tr8n/help/translating_inline.html.erb +30 -0
- data/app/views/tr8n/help/translation_context_rules.html.erb +16 -0
- data/app/views/tr8n/help/translation_rank.html.erb +17 -0
- data/app/views/tr8n/help/translation_tokens.html.erb +13 -0
- data/app/views/tr8n/help/translation_tools.html.erb +13 -0
- data/app/views/tr8n/help/translations.html.erb +13 -0
- data/app/views/tr8n/help/user_rank.html.erb +13 -0
- data/app/views/tr8n/help/using_translation_tools.html.erb +13 -0
- data/app/views/tr8n/help/voting_on_translations.html.erb +13 -0
- data/app/views/tr8n/help/your_dashboard.html.erb +17 -0
- data/app/views/tr8n/help/your_languages.html.erb +19 -0
- data/app/views/tr8n/help/your_translations.html.erb +17 -0
- data/app/views/tr8n/home/credits.html.erb +102 -0
- data/app/views/tr8n/home/docs.html.erb +3 -0
- data/app/views/tr8n/home/index.html.erb +37 -0
- data/app/views/tr8n/home/integration.html.erb +564 -0
- data/app/views/tr8n/home/languages.html.erb +7 -0
- data/app/views/tr8n/home/license.html.erb +586 -0
- data/app/views/tr8n/home/rules.html.erb +668 -0
- data/app/views/tr8n/home/tokens.html.erb +324 -0
- data/app/views/tr8n/language/_basic_info.html.erb +53 -0
- data/app/views/tr8n/language/_edit_language_case_rules.html.erb +51 -0
- data/app/views/tr8n/language/_edit_language_cases.html.erb +68 -0
- data/app/views/tr8n/language/_edit_rules.html.erb +46 -0
- data/app/views/tr8n/language/_grammar.html.erb +84 -0
- data/app/views/tr8n/language/_header.html.erb +14 -0
- data/app/views/tr8n/language/_language_cases.html.erb +196 -0
- data/app/views/tr8n/language/_lists.html.erb +56 -0
- data/app/views/tr8n/language/_prohibited_words.html.erb +16 -0
- data/app/views/tr8n/language/_translator_dependencies.html.erb +27 -0
- data/app/views/tr8n/language/_translator_header.html.erb +19 -0
- data/app/views/tr8n/language/_translator_submit.html.erb +141 -0
- data/app/views/tr8n/language/_translator_votes.html.erb +27 -0
- data/app/views/tr8n/language/index.html.erb +54 -0
- data/app/views/tr8n/language/lb_language_case_rule.html.erb +94 -0
- data/app/views/tr8n/language/rules/_date_rule.html.erb +3 -0
- data/app/views/tr8n/language/rules/_gender_list_rule.html.erb +23 -0
- data/app/views/tr8n/language/rules/_gender_rule.html.erb +3 -0
- data/app/views/tr8n/language/rules/_list_rule.html.erb +3 -0
- data/app/views/tr8n/language/rules/_number_rule.html.erb +24 -0
- data/app/views/tr8n/language/rules/_value_rule.html.erb +3 -0
- data/app/views/tr8n/language/select.html.erb +72 -0
- data/app/views/tr8n/language/table.html.erb +32 -0
- data/app/views/tr8n/language/translator.html.erb +18 -0
- data/app/views/tr8n/language_cases/_gender_based.html.erb +32 -0
- data/app/views/tr8n/language_cases/_gender_neutral.html.erb +25 -0
- data/app/views/tr8n/language_cases/_manager_header.html.erb +18 -0
- data/app/views/tr8n/language_cases/index.html.erb +54 -0
- data/app/views/tr8n/language_cases/manager.html.erb +60 -0
- data/app/views/tr8n/login/index.html.erb +33 -0
- data/app/views/tr8n/login/register.html.erb +57 -0
- data/app/views/tr8n/phrases/_breadcrumb.html.erb +11 -0
- data/app/views/tr8n/phrases/_comment.html.erb +17 -0
- data/app/views/tr8n/phrases/_comments_module.html.erb +37 -0
- data/app/views/tr8n/phrases/_dictionary.rhtml +29 -0
- data/app/views/tr8n/phrases/_header.html.erb +24 -0
- data/app/views/tr8n/phrases/_new_comment.html.erb +31 -0
- data/app/views/tr8n/phrases/_permutations_module.html.erb +30 -0
- data/app/views/tr8n/phrases/_tokens.html.erb +122 -0
- data/app/views/tr8n/phrases/_toolbar.html.erb +33 -0
- data/app/views/tr8n/phrases/_translation_module.html.erb +127 -0
- data/app/views/tr8n/phrases/_translations_module.html.erb +70 -0
- data/app/views/tr8n/phrases/index.html.erb +90 -0
- data/app/views/tr8n/phrases/lb_sources.html.erb +51 -0
- data/app/views/tr8n/phrases/map.html.erb +42 -0
- data/app/views/tr8n/phrases/view.html.erb +77 -0
- data/app/views/tr8n/translations/_list.html.erb +71 -0
- data/app/views/tr8n/translations/_original_phrase.html.erb +11 -0
- data/app/views/tr8n/translations/_translation.html.erb +80 -0
- data/app/views/tr8n/translations/index.html.erb +30 -0
- data/app/views/tr8n/translator/_basic_info.html.erb +95 -0
- data/app/views/tr8n/translator/_header.html.erb +12 -0
- data/app/views/tr8n/translator/_header_key_report.html.erb +12 -0
- data/app/views/tr8n/translator/index.html.erb +25 -0
- data/app/views/tr8n/translator/lb_report.html.erb +113 -0
- data/config.ru +4 -0
- data/config/application.rb +65 -0
- data/config/boot.rb +6 -0
- data/config/database.yml +13 -0
- data/config/environment.rb +46 -0
- data/config/environments/development.rb +25 -0
- data/config/environments/test.rb +35 -0
- data/config/routes.rb +47 -0
- data/config/tr8n/config.yml +247 -0
- data/config/tr8n/data/ip_locations.csv +93460 -0
- data/config/tr8n/rules/default_cases.yml +141 -0
- data/config/tr8n/rules/default_date_rules.yml +20 -0
- data/config/tr8n/rules/default_gender_list_rules.yml +82 -0
- data/config/tr8n/rules/default_gender_rules.yml +20 -0
- data/config/tr8n/rules/default_list_rules.yml +19 -0
- data/config/tr8n/rules/default_numeric_rules.yml +42 -0
- data/config/tr8n/rules/default_value_rules.yml +18 -0
- data/config/tr8n/site/default_glossary.yml +18 -0
- data/config/tr8n/site/default_languages.yml +1591 -0
- data/config/tr8n/site/features.yml +111 -0
- data/config/tr8n/site/shortcuts.yml +55 -0
- data/config/tr8n/site/sitemap.json +42 -0
- data/config/tr8n/tokens/data.yml +19 -0
- data/config/tr8n/tokens/decorations.yml +16 -0
- data/config/will_filter/config.yml +97 -0
- data/db/extras/20100511185330_create_test_users.rb +43 -0
- data/db/migrate/20090730070119_create_will_filter_tables.rb +19 -0
- data/db/migrate/20100405201417_create_tr8n_tables.rb +350 -0
- data/db/seeds.rb +7 -0
- data/doc/README_FOR_APP +2 -0
- data/doc/cheat sheet.docx +0 -0
- data/doc/cheat sheet.pdf +0 -0
- data/doc/classes.graffle +12555 -0
- data/doc/classes.pdf +0 -0
- data/doc/client sdk sequence.graffle +2768 -0
- data/doc/integration.doc +0 -0
- data/doc/integration.docx +0 -0
- data/doc/pixel client sdk.graffle +1454 -0
- data/lib/application_controller.rb +38 -0
- data/lib/application_helper.rb +336 -0
- data/lib/core_ext/array.rb +61 -0
- data/lib/core_ext/date.rb +76 -0
- data/lib/core_ext/fixnum.rb +35 -0
- data/lib/core_ext/hash.rb +60 -0
- data/lib/core_ext/string.rb +49 -0
- data/lib/core_ext/time.rb +83 -0
- data/lib/generators/tr8n/templates/create_tr8n_tables.rb +350 -0
- data/lib/generators/tr8n/tr8n_generator.rb +49 -0
- data/lib/tasks/.gitkeep +0 -0
- data/lib/tasks/tr8n_tasks.rake +99 -0
- data/lib/tr8n.rb +3 -0
- data/lib/tr8n/active_dumper.rb +49 -0
- data/lib/tr8n/cache.rb +57 -0
- data/lib/tr8n/common_methods.rb +61 -0
- data/lib/tr8n/config.rb +719 -0
- data/lib/tr8n/controller_methods.rb +112 -0
- data/lib/tr8n/dictionary.rb +53 -0
- data/lib/tr8n/engine.rb +29 -0
- data/lib/tr8n/exception.rb +26 -0
- data/lib/tr8n/extender.rb +34 -0
- data/lib/tr8n/helper_methods.rb +304 -0
- data/lib/tr8n/ip_address.rb +52 -0
- data/lib/tr8n/key_registration_exception.rb +26 -0
- data/lib/tr8n/keyboard_mapping.rb +174 -0
- data/lib/tr8n/logger.rb +60 -0
- data/lib/tr8n/site_map.rb +85 -0
- data/lib/tr8n/site_map_section.rb +108 -0
- data/lib/tr8n/token.rb +438 -0
- data/lib/tr8n/token_exception.rb +26 -0
- data/lib/tr8n/tokenized_label.rb +141 -0
- data/lib/tr8n/tokens/data_token.rb +52 -0
- data/lib/tr8n/tokens/decoration_token.rb +124 -0
- data/lib/tr8n/tokens/hidden_token.rb +87 -0
- data/lib/tr8n/tokens/method_token.rb +60 -0
- data/lib/tr8n/tokens/transform_token.rb +131 -0
- data/public/404.html +26 -0
- data/public/422.html +26 -0
- data/public/500.html +26 -0
- data/public/favicon.ico +0 -0
- data/public/robots.txt +5 -0
- data/public/tr8n/images/accept.png +0 -0
- data/public/tr8n/images/action_tab_bkgd.gif +0 -0
- data/public/tr8n/images/action_tab_white_bkgd.gif +0 -0
- data/public/tr8n/images/add.png +0 -0
- data/public/tr8n/images/arrow_down.gif +0 -0
- data/public/tr8n/images/arrow_down.png +0 -0
- data/public/tr8n/images/arrow_down_grey.png +0 -0
- data/public/tr8n/images/arrow_right.gif +0 -0
- data/public/tr8n/images/arrow_up.png +0 -0
- data/public/tr8n/images/arrow_up_grey.png +0 -0
- data/public/tr8n/images/bullet_go.png +0 -0
- data/public/tr8n/images/buttons.png +0 -0
- data/public/tr8n/images/cancel.png +0 -0
- data/public/tr8n/images/close.gif +0 -0
- data/public/tr8n/images/cross.png +0 -0
- data/public/tr8n/images/delete.png +0 -0
- data/public/tr8n/images/disk.png +0 -0
- data/public/tr8n/images/examples/context_rules_1.png +0 -0
- data/public/tr8n/images/examples/context_rules_2.png +0 -0
- data/public/tr8n/images/examples/date_rules_1.png +0 -0
- data/public/tr8n/images/examples/date_rules_2.png +0 -0
- data/public/tr8n/images/examples/date_rules_3.png +0 -0
- data/public/tr8n/images/examples/gender_rules_1.png +0 -0
- data/public/tr8n/images/examples/gender_rules_2.png +0 -0
- data/public/tr8n/images/examples/gender_rules_3.png +0 -0
- data/public/tr8n/images/examples/language_manager_1.png +0 -0
- data/public/tr8n/images/examples/list_rules_1.png +0 -0
- data/public/tr8n/images/examples/list_rules_2.png +0 -0
- data/public/tr8n/images/examples/list_rules_3.png +0 -0
- data/public/tr8n/images/examples/numeric_rules_1.png +0 -0
- data/public/tr8n/images/examples/numeric_rules_2.png +0 -0
- data/public/tr8n/images/examples/numeric_rules_3.png +0 -0
- data/public/tr8n/images/examples/numeric_rules_4.png +0 -0
- data/public/tr8n/images/exclamation.png +0 -0
- data/public/tr8n/images/eye.png +0 -0
- data/public/tr8n/images/eye_not.png +0 -0
- data/public/tr8n/images/facebook/connect_light_medium_long.gif +0 -0
- data/public/tr8n/images/field_sprite.gif +0 -0
- data/public/tr8n/images/find.png +0 -0
- data/public/tr8n/images/flags/.DS_Store +0 -0
- data/public/tr8n/images/flags/ab.png +0 -0
- data/public/tr8n/images/flags/ach.png +0 -0
- data/public/tr8n/images/flags/af.png +0 -0
- data/public/tr8n/images/flags/ak.png +0 -0
- data/public/tr8n/images/flags/am.png +0 -0
- data/public/tr8n/images/flags/an.png +0 -0
- data/public/tr8n/images/flags/ar-AE.png +0 -0
- data/public/tr8n/images/flags/ar-BH.png +0 -0
- data/public/tr8n/images/flags/ar-DZ.png +0 -0
- data/public/tr8n/images/flags/ar-EG.png +0 -0
- data/public/tr8n/images/flags/ar-IQ.png +0 -0
- data/public/tr8n/images/flags/ar-JO.png +0 -0
- data/public/tr8n/images/flags/ar-KW.png +0 -0
- data/public/tr8n/images/flags/ar-LB.png +0 -0
- data/public/tr8n/images/flags/ar-LY.png +0 -0
- data/public/tr8n/images/flags/ar-MA.png +0 -0
- data/public/tr8n/images/flags/ar-OM.png +0 -0
- data/public/tr8n/images/flags/ar-QA.png +0 -0
- data/public/tr8n/images/flags/ar-SA.png +0 -0
- data/public/tr8n/images/flags/ar-SY.png +0 -0
- data/public/tr8n/images/flags/ar-TN.png +0 -0
- data/public/tr8n/images/flags/ar-YE.png +0 -0
- data/public/tr8n/images/flags/ar.png +0 -0
- data/public/tr8n/images/flags/as.png +0 -0
- data/public/tr8n/images/flags/ast.png +0 -0
- data/public/tr8n/images/flags/ay.png +0 -0
- data/public/tr8n/images/flags/az.png +0 -0
- data/public/tr8n/images/flags/ba.png +0 -0
- data/public/tr8n/images/flags/be.png +0 -0
- data/public/tr8n/images/flags/bg.png +0 -0
- data/public/tr8n/images/flags/bh.png +0 -0
- data/public/tr8n/images/flags/bn.png +0 -0
- data/public/tr8n/images/flags/bo.png +0 -0
- data/public/tr8n/images/flags/br.png +0 -0
- data/public/tr8n/images/flags/bs.png +0 -0
- data/public/tr8n/images/flags/ca.png +0 -0
- data/public/tr8n/images/flags/cb.png +0 -0
- data/public/tr8n/images/flags/ce.png +0 -0
- data/public/tr8n/images/flags/ch.png +0 -0
- data/public/tr8n/images/flags/ck-US.png +0 -0
- data/public/tr8n/images/flags/co.png +0 -0
- data/public/tr8n/images/flags/cr.png +0 -0
- data/public/tr8n/images/flags/cs.png +0 -0
- data/public/tr8n/images/flags/cv.png +0 -0
- data/public/tr8n/images/flags/cy.png +0 -0
- data/public/tr8n/images/flags/da.png +0 -0
- data/public/tr8n/images/flags/de-AT.png +0 -0
- data/public/tr8n/images/flags/de-CH.png +0 -0
- data/public/tr8n/images/flags/de-DE.png +0 -0
- data/public/tr8n/images/flags/de-LI.png +0 -0
- data/public/tr8n/images/flags/de-LU.png +0 -0
- data/public/tr8n/images/flags/de.png +0 -0
- data/public/tr8n/images/flags/el.png +0 -0
- data/public/tr8n/images/flags/en-AU.png +0 -0
- data/public/tr8n/images/flags/en-BZ.png +0 -0
- data/public/tr8n/images/flags/en-CA.png +0 -0
- data/public/tr8n/images/flags/en-IE.png +0 -0
- data/public/tr8n/images/flags/en-JM.png +0 -0
- data/public/tr8n/images/flags/en-NZ.png +0 -0
- data/public/tr8n/images/flags/en-PH.png +0 -0
- data/public/tr8n/images/flags/en-PI.png +0 -0
- data/public/tr8n/images/flags/en-SC.png +0 -0
- data/public/tr8n/images/flags/en-UK.png +0 -0
- data/public/tr8n/images/flags/en-US.png +0 -0
- data/public/tr8n/images/flags/en-ZA.png +0 -0
- data/public/tr8n/images/flags/en-ZW.png +0 -0
- data/public/tr8n/images/flags/en.png +0 -0
- data/public/tr8n/images/flags/eo.png +0 -0
- data/public/tr8n/images/flags/es-AR.png +0 -0
- data/public/tr8n/images/flags/es-BO.png +0 -0
- data/public/tr8n/images/flags/es-CL.png +0 -0
- data/public/tr8n/images/flags/es-CO.png +0 -0
- data/public/tr8n/images/flags/es-CR.png +0 -0
- data/public/tr8n/images/flags/es-DO.png +0 -0
- data/public/tr8n/images/flags/es-EC.png +0 -0
- data/public/tr8n/images/flags/es-ES.png +0 -0
- data/public/tr8n/images/flags/es-GT.png +0 -0
- data/public/tr8n/images/flags/es-HN.png +0 -0
- data/public/tr8n/images/flags/es-MX.png +0 -0
- data/public/tr8n/images/flags/es-NI.png +0 -0
- data/public/tr8n/images/flags/es-PA.png +0 -0
- data/public/tr8n/images/flags/es-PE.png +0 -0
- data/public/tr8n/images/flags/es-PR.png +0 -0
- data/public/tr8n/images/flags/es-PY.png +0 -0
- data/public/tr8n/images/flags/es-SV.png +0 -0
- data/public/tr8n/images/flags/es-UY.png +0 -0
- data/public/tr8n/images/flags/es-VE.png +0 -0
- data/public/tr8n/images/flags/es.png +0 -0
- data/public/tr8n/images/flags/et.png +0 -0
- data/public/tr8n/images/flags/eu.png +0 -0
- data/public/tr8n/images/flags/fa-IR.png +0 -0
- data/public/tr8n/images/flags/fa.png +0 -0
- data/public/tr8n/images/flags/fb-LT.png +0 -0
- data/public/tr8n/images/flags/fi.png +0 -0
- data/public/tr8n/images/flags/fj.png +0 -0
- data/public/tr8n/images/flags/fo.png +0 -0
- data/public/tr8n/images/flags/fr-BE.png +0 -0
- data/public/tr8n/images/flags/fr-CA.png +0 -0
- data/public/tr8n/images/flags/fr-CH.png +0 -0
- data/public/tr8n/images/flags/fr-FR.png +0 -0
- data/public/tr8n/images/flags/fr-LU.png +0 -0
- data/public/tr8n/images/flags/fr-MC.png +0 -0
- data/public/tr8n/images/flags/fr.png +0 -0
- data/public/tr8n/images/flags/fur.png +0 -0
- data/public/tr8n/images/flags/fy.png +0 -0
- data/public/tr8n/images/flags/ga.png +0 -0
- data/public/tr8n/images/flags/gd.png +0 -0
- data/public/tr8n/images/flags/gl.png +0 -0
- data/public/tr8n/images/flags/gn.png +0 -0
- data/public/tr8n/images/flags/gu.png +0 -0
- data/public/tr8n/images/flags/gv.png +0 -0
- data/public/tr8n/images/flags/ha.png +0 -0
- data/public/tr8n/images/flags/haw.png +0 -0
- data/public/tr8n/images/flags/he.png +0 -0
- data/public/tr8n/images/flags/hi.png +0 -0
- data/public/tr8n/images/flags/hr.png +0 -0
- data/public/tr8n/images/flags/hsb.png +0 -0
- data/public/tr8n/images/flags/ht.png +0 -0
- data/public/tr8n/images/flags/hu.png +0 -0
- data/public/tr8n/images/flags/hy.png +0 -0
- data/public/tr8n/images/flags/ia.png +0 -0
- data/public/tr8n/images/flags/id.png +0 -0
- data/public/tr8n/images/flags/ie.png +0 -0
- data/public/tr8n/images/flags/ig.png +0 -0
- data/public/tr8n/images/flags/is.png +0 -0
- data/public/tr8n/images/flags/it-CH.png +0 -0
- data/public/tr8n/images/flags/it.png +0 -0
- data/public/tr8n/images/flags/iu.png +0 -0
- data/public/tr8n/images/flags/ja.png +0 -0
- data/public/tr8n/images/flags/jw.png +0 -0
- data/public/tr8n/images/flags/ka.png +0 -0
- data/public/tr8n/images/flags/kk.png +0 -0
- data/public/tr8n/images/flags/kl.png +0 -0
- data/public/tr8n/images/flags/km.png +0 -0
- data/public/tr8n/images/flags/kn.png +0 -0
- data/public/tr8n/images/flags/ko-KP.png +0 -0
- data/public/tr8n/images/flags/ko-KR.png +0 -0
- data/public/tr8n/images/flags/ko.png +0 -0
- data/public/tr8n/images/flags/kok.png +0 -0
- data/public/tr8n/images/flags/ks.png +0 -0
- data/public/tr8n/images/flags/ku.png +0 -0
- data/public/tr8n/images/flags/ky.png +0 -0
- data/public/tr8n/images/flags/la.png +0 -0
- data/public/tr8n/images/flags/lb.png +0 -0
- data/public/tr8n/images/flags/lg.png +0 -0
- data/public/tr8n/images/flags/li-NL.png +0 -0
- data/public/tr8n/images/flags/ln.png +0 -0
- data/public/tr8n/images/flags/lo.png +0 -0
- data/public/tr8n/images/flags/lt.png +0 -0
- data/public/tr8n/images/flags/lv.png +0 -0
- data/public/tr8n/images/flags/md.png +0 -0
- data/public/tr8n/images/flags/mfe.png +0 -0
- data/public/tr8n/images/flags/mg.png +0 -0
- data/public/tr8n/images/flags/mh.png +0 -0
- data/public/tr8n/images/flags/mi.png +0 -0
- data/public/tr8n/images/flags/mk.png +0 -0
- data/public/tr8n/images/flags/ml.png +0 -0
- data/public/tr8n/images/flags/mn.png +0 -0
- data/public/tr8n/images/flags/mo.png +0 -0
- data/public/tr8n/images/flags/mr.png +0 -0
- data/public/tr8n/images/flags/ms.png +0 -0
- data/public/tr8n/images/flags/mt.png +0 -0
- data/public/tr8n/images/flags/my.png +0 -0
- data/public/tr8n/images/flags/na.png +0 -0
- data/public/tr8n/images/flags/nb.png +0 -0
- data/public/tr8n/images/flags/nd.png +0 -0
- data/public/tr8n/images/flags/ne.png +0 -0
- data/public/tr8n/images/flags/ng.png +0 -0
- data/public/tr8n/images/flags/nl-NE.png +0 -0
- data/public/tr8n/images/flags/nl.png +0 -0
- data/public/tr8n/images/flags/nn.png +0 -0
- data/public/tr8n/images/flags/no.png +0 -0
- data/public/tr8n/images/flags/nr.png +0 -0
- data/public/tr8n/images/flags/nso.png +0 -0
- data/public/tr8n/images/flags/nv.png +0 -0
- data/public/tr8n/images/flags/ny.png +0 -0
- data/public/tr8n/images/flags/nyn.png +0 -0
- data/public/tr8n/images/flags/oc.png +0 -0
- data/public/tr8n/images/flags/om.png +0 -0
- data/public/tr8n/images/flags/or.png +0 -0
- data/public/tr8n/images/flags/pa-IN.png +0 -0
- data/public/tr8n/images/flags/pa-PK.png +0 -0
- data/public/tr8n/images/flags/pa.png +0 -0
- data/public/tr8n/images/flags/pf.png +0 -0
- data/public/tr8n/images/flags/pl.png +0 -0
- data/public/tr8n/images/flags/pp.png +0 -0
- data/public/tr8n/images/flags/ps.png +0 -0
- data/public/tr8n/images/flags/pt-BZ.png +0 -0
- data/public/tr8n/images/flags/pt.png +0 -0
- data/public/tr8n/images/flags/qu-PE.png +0 -0
- data/public/tr8n/images/flags/qu.png +0 -0
- data/public/tr8n/images/flags/rj.png +0 -0
- data/public/tr8n/images/flags/rm.png +0 -0
- data/public/tr8n/images/flags/rn.png +0 -0
- data/public/tr8n/images/flags/ro-MD.png +0 -0
- data/public/tr8n/images/flags/ro-RO.png +0 -0
- data/public/tr8n/images/flags/ro.png +0 -0
- data/public/tr8n/images/flags/ru.png +0 -0
- data/public/tr8n/images/flags/rw.png +0 -0
- data/public/tr8n/images/flags/sa.png +0 -0
- data/public/tr8n/images/flags/sc.png +0 -0
- data/public/tr8n/images/flags/sd.png +0 -0
- data/public/tr8n/images/flags/se-NO.png +0 -0
- data/public/tr8n/images/flags/sg.png +0 -0
- data/public/tr8n/images/flags/sh.png +0 -0
- data/public/tr8n/images/flags/si.png +0 -0
- data/public/tr8n/images/flags/sk.png +0 -0
- data/public/tr8n/images/flags/sl.png +0 -0
- data/public/tr8n/images/flags/sm.png +0 -0
- data/public/tr8n/images/flags/sn.png +0 -0
- data/public/tr8n/images/flags/so.png +0 -0
- data/public/tr8n/images/flags/sq.png +0 -0
- data/public/tr8n/images/flags/sr-me.png +0 -0
- data/public/tr8n/images/flags/sr.png +0 -0
- data/public/tr8n/images/flags/ss.png +0 -0
- data/public/tr8n/images/flags/st.png +0 -0
- data/public/tr8n/images/flags/su.png +0 -0
- data/public/tr8n/images/flags/sv-FI.png +0 -0
- data/public/tr8n/images/flags/sv-SE.png +0 -0
- data/public/tr8n/images/flags/sv.png +0 -0
- data/public/tr8n/images/flags/sw.png +0 -0
- data/public/tr8n/images/flags/ta.png +0 -0
- data/public/tr8n/images/flags/te.png +0 -0
- data/public/tr8n/images/flags/tg.png +0 -0
- data/public/tr8n/images/flags/th.png +0 -0
- data/public/tr8n/images/flags/ti.png +0 -0
- data/public/tr8n/images/flags/tig.png +0 -0
- data/public/tr8n/images/flags/tk.png +0 -0
- data/public/tr8n/images/flags/tl.png +0 -0
- data/public/tr8n/images/flags/tlh.png +0 -0
- data/public/tr8n/images/flags/tn.png +0 -0
- data/public/tr8n/images/flags/to.png +0 -0
- data/public/tr8n/images/flags/tr.png +0 -0
- data/public/tr8n/images/flags/ts.png +0 -0
- data/public/tr8n/images/flags/tt.png +0 -0
- data/public/tr8n/images/flags/tw.png +0 -0
- data/public/tr8n/images/flags/ug.png +0 -0
- data/public/tr8n/images/flags/uk.png +0 -0
- data/public/tr8n/images/flags/ur.png +0 -0
- data/public/tr8n/images/flags/uz.png +0 -0
- data/public/tr8n/images/flags/ve.png +0 -0
- data/public/tr8n/images/flags/vi.png +0 -0
- data/public/tr8n/images/flags/vo.png +0 -0
- data/public/tr8n/images/flags/wa.png +0 -0
- data/public/tr8n/images/flags/wo.png +0 -0
- data/public/tr8n/images/flags/xh.png +0 -0
- data/public/tr8n/images/flags/yi.png +0 -0
- data/public/tr8n/images/flags/yo.png +0 -0
- data/public/tr8n/images/flags/zh-CN.png +0 -0
- data/public/tr8n/images/flags/zh-HK.png +0 -0
- data/public/tr8n/images/flags/zh-SG.png +0 -0
- data/public/tr8n/images/flags/zh-TW.png +0 -0
- data/public/tr8n/images/flags/zh.png +0 -0
- data/public/tr8n/images/flags/zu.png +0 -0
- data/public/tr8n/images/globe.gif +0 -0
- data/public/tr8n/images/help.png +0 -0
- data/public/tr8n/images/help/color_coding.png +0 -0
- data/public/tr8n/images/help/language_selector.png +0 -0
- data/public/tr8n/images/help/language_selector_default.png +0 -0
- data/public/tr8n/images/help/languages_disabled.png +0 -0
- data/public/tr8n/images/help/translator.png +0 -0
- data/public/tr8n/images/help2.png +0 -0
- data/public/tr8n/images/information.png +0 -0
- data/public/tr8n/images/keyboard.png +0 -0
- data/public/tr8n/images/language_selector_arrow.gif +0 -0
- data/public/tr8n/images/left_quote.png +0 -0
- data/public/tr8n/images/lightning.png +0 -0
- data/public/tr8n/images/loading.gif +0 -0
- data/public/tr8n/images/loading2.gif +0 -0
- data/public/tr8n/images/loading3.gif +0 -0
- data/public/tr8n/images/loading_large.gif +0 -0
- data/public/tr8n/images/lock.png +0 -0
- data/public/tr8n/images/lock_add.png +0 -0
- data/public/tr8n/images/lock_delete.png +0 -0
- data/public/tr8n/images/lock_open.png +0 -0
- data/public/tr8n/images/medals/bronze.png +0 -0
- data/public/tr8n/images/medals/gold.png +0 -0
- data/public/tr8n/images/medals/runner.png +0 -0
- data/public/tr8n/images/medals/silver.png +0 -0
- data/public/tr8n/images/pencil.png +0 -0
- data/public/tr8n/images/photo_silhouette.gif +0 -0
- data/public/tr8n/images/plus.png +0 -0
- data/public/tr8n/images/random.png +0 -0
- data/public/tr8n/images/random2.png +0 -0
- data/public/tr8n/images/rating_star0.png +0 -0
- data/public/tr8n/images/rating_star05.png +0 -0
- data/public/tr8n/images/rating_star1.png +0 -0
- data/public/tr8n/images/rating_stars.gif +0 -0
- data/public/tr8n/images/rating_stars.psd +0 -0
- data/public/tr8n/images/reply.png +0 -0
- data/public/tr8n/images/right_quote.png +0 -0
- data/public/tr8n/images/rotating_world.gif +0 -0
- data/public/tr8n/images/script.png +0 -0
- data/public/tr8n/images/script_edit.png +0 -0
- data/public/tr8n/images/script_gear.png +0 -0
- data/public/tr8n/images/site_sprite.gif +0 -0
- data/public/tr8n/images/spinner.gif +0 -0
- data/public/tr8n/images/star.png +0 -0
- data/public/tr8n/images/table_edit.png +0 -0
- data/public/tr8n/images/table_gear.png +0 -0
- data/public/tr8n/images/table_multiple.png +0 -0
- data/public/tr8n/images/thumb_down.png +0 -0
- data/public/tr8n/images/thumb_up.png +0 -0
- data/public/tr8n/images/toolbar_bg.gif +0 -0
- data/public/tr8n/images/top_left_stem.png +0 -0
- data/public/tr8n/images/top_right_stem.png +0 -0
- data/public/tr8n/images/tr8n_loading.gif +0 -0
- data/public/tr8n/images/tr8n_logo.jpg +0 -0
- data/public/tr8n/images/tr8n_logo.png +0 -0
- data/public/tr8n/images/tr8n_logo2.gif +0 -0
- data/public/tr8n/images/tr8n_logo2.png +0 -0
- data/public/tr8n/images/tr8n_logo_wiki.png +0 -0
- data/public/tr8n/images/tr8n_logo_wiki2.png +0 -0
- data/public/tr8n/images/translate_icn.gif +0 -0
- data/public/tr8n/images/wizard.png +0 -0
- data/public/tr8n/javascripts/jsDraw2D.js +24 -0
- data/public/tr8n/javascripts/keyboard_1_36.js +1214 -0
- data/public/tr8n/javascripts/keyboard_1_44.js +1735 -0
- data/public/tr8n/javascripts/shortcut.js +223 -0
- data/public/tr8n/javascripts/tr8n.js +904 -0
- data/public/tr8n/javascripts/tr8n_client_sdk.js +1182 -0
- data/public/tr8n/javascripts/tr8n_prototype_effects.js +65 -0
- data/public/tr8n/stylesheets/components.css +208 -0
- data/public/tr8n/stylesheets/keyboard_1_36.css +185 -0
- data/public/tr8n/stylesheets/keyboard_1_44.css +268 -0
- data/public/tr8n/stylesheets/layout.css +119 -0
- data/public/tr8n/stylesheets/tr8n.css +201 -0
- data/rails/init.rb +53 -0
- data/script/rails +6 -0
- data/test/performance/browsing_test.rb +9 -0
- data/test/test_helper.rb +13 -0
- data/tr8n.gemspec +40 -0
- metadata +865 -0
|
@@ -0,0 +1,625 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# Copyright (c) 2010-2011 Michael Berkovich
|
|
3
|
+
#
|
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
|
5
|
+
# a copy of this software and associated documentation files (the
|
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
|
10
|
+
# the following conditions:
|
|
11
|
+
#
|
|
12
|
+
# The above copyright notice and this permission notice shall be
|
|
13
|
+
# included in all copies or substantial portions of the Software.
|
|
14
|
+
#
|
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
22
|
+
#++
|
|
23
|
+
|
|
24
|
+
require 'digest/md5'
|
|
25
|
+
|
|
26
|
+
class Tr8n::TranslationKey < ActiveRecord::Base
|
|
27
|
+
set_table_name :tr8n_translation_keys
|
|
28
|
+
after_save :clear_cache
|
|
29
|
+
after_destroy :clear_cache
|
|
30
|
+
|
|
31
|
+
has_many :translations, :class_name => "Tr8n::Translation", :dependent => :destroy
|
|
32
|
+
has_many :translation_key_locks, :class_name => "Tr8n::TranslationKeyLock", :dependent => :destroy
|
|
33
|
+
has_many :translation_key_sources, :class_name => "Tr8n::TranslationKeySource", :dependent => :destroy
|
|
34
|
+
has_many :translation_sources, :class_name => "Tr8n::TranslationSource", :through => :translation_key_sources
|
|
35
|
+
has_many :translation_domains, :class_name => "Tr8n::TranslationDomain", :through => :translation_sources
|
|
36
|
+
has_many :translation_key_comments, :class_name => "Tr8n::TranslationKeyComment", :dependent => :destroy, :order => "created_at desc"
|
|
37
|
+
|
|
38
|
+
alias :locks :translation_key_locks
|
|
39
|
+
alias :key_sources :translation_key_sources
|
|
40
|
+
alias :sources :translation_sources
|
|
41
|
+
alias :domains :translation_domains
|
|
42
|
+
alias :comments :translation_key_comments
|
|
43
|
+
|
|
44
|
+
def self.find_or_create(label, desc = "", options = {})
|
|
45
|
+
key = generate_key(label, desc)
|
|
46
|
+
|
|
47
|
+
# translation keys don't ever change, so no real reason to invalidate them
|
|
48
|
+
tkey = Tr8n::Cache.fetch("translation_key_#{key}") do
|
|
49
|
+
existing_key = find_by_key(key)
|
|
50
|
+
|
|
51
|
+
unless existing_key
|
|
52
|
+
if options[:api] and (not Tr8n::Config.api[:allow_key_registration])
|
|
53
|
+
raise Tr8n::KeyRegistrationException.new("Key registration through API is disabled!")
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
level = options[:level] || Tr8n::Config.block_options[:level] || Tr8n::Config.default_translation_key_level
|
|
58
|
+
role_key = options[:role] || Tr8n::Config.block_options[:role]
|
|
59
|
+
if role_key # role overrides level
|
|
60
|
+
level = Tr8n::Config.translator_roles[role_key]
|
|
61
|
+
raise Tr8n::Exception("Unknown translator role: #{role_key}") unless level
|
|
62
|
+
end
|
|
63
|
+
locale = options[:locale] || Tr8n::Config.block_options[:default_locale] || Tr8n::Config.default_locale
|
|
64
|
+
|
|
65
|
+
existing_key ||= begin
|
|
66
|
+
new_tkey = create(:key => key,
|
|
67
|
+
:label => label,
|
|
68
|
+
:description => desc,
|
|
69
|
+
:locale => locale,
|
|
70
|
+
:level => level,
|
|
71
|
+
:admin => Tr8n::Config.block_options[:admin])
|
|
72
|
+
unless options[:source].blank?
|
|
73
|
+
# at the time of creation - mark the first source of the key
|
|
74
|
+
Tr8n::TranslationKeySource.find_or_create(new_tkey, Tr8n::TranslationSource.find_or_create(options[:source], options[:url]))
|
|
75
|
+
end
|
|
76
|
+
new_tkey
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# for backwards compatibility only
|
|
80
|
+
mark_as_admin(existing_key, options)
|
|
81
|
+
update_default_locale(existing_key, options)
|
|
82
|
+
|
|
83
|
+
# mark each key as verified - but only if caching is enabled
|
|
84
|
+
if Tr8n::Config.enable_caching?
|
|
85
|
+
existing_key.update_attributes(:verified_at => Time.now)
|
|
86
|
+
end
|
|
87
|
+
existing_key
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# for detailed tracking of all sources and caller stack - only needed for debugging - expensive
|
|
91
|
+
track_source(tkey, options)
|
|
92
|
+
tkey
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# for backwards compatibility only - new keys will be marked as such
|
|
96
|
+
def self.mark_as_admin(tkey, options)
|
|
97
|
+
return if options[:skip_block_options]
|
|
98
|
+
return unless Tr8n::Config.block_options[:admin]
|
|
99
|
+
return if tkey.admin?
|
|
100
|
+
tkey.update_attributes(:admin => true)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# for backwards compatibility only - if locale is provided update it in the key
|
|
104
|
+
def self.update_default_locale(tkey, options)
|
|
105
|
+
return if options[:skip_block_options]
|
|
106
|
+
return unless tkey.locale.blank?
|
|
107
|
+
key_locale = Tr8n::Config.block_options[:default_locale] || Tr8n::Config.default_locale
|
|
108
|
+
tkey.update_attributes(:locale => key_locale)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# used to create associations between the translation keys and source
|
|
112
|
+
# primarely used for the site map and only needs to be enabled
|
|
113
|
+
# for a short period of time on a single machine
|
|
114
|
+
def self.track_source(tkey, options)
|
|
115
|
+
return unless Tr8n::Config.enable_key_source_tracking?
|
|
116
|
+
return if options[:source].blank?
|
|
117
|
+
|
|
118
|
+
key_source = Tr8n::TranslationKeySource.find_or_create(tkey, Tr8n::TranslationSource.find_or_create(options[:source], options[:url]))
|
|
119
|
+
return unless Tr8n::Config.enable_key_caller_tracking?
|
|
120
|
+
|
|
121
|
+
options[:caller] ||= caller
|
|
122
|
+
options[:caller_key] = options[:caller].is_a?(Array) ? options[:caller].join(", ") : options[:caller].to_s
|
|
123
|
+
options[:caller_key] = generate_key(options[:caller_key])
|
|
124
|
+
key_source.update_details!(options)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def self.generate_key(label, desc = "")
|
|
128
|
+
Digest::MD5.hexdigest("#{label};;;#{desc}")
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def reset_key!
|
|
132
|
+
# remove old key from cache
|
|
133
|
+
Tr8n::Cache.delete("translation_key_#{key}")
|
|
134
|
+
|
|
135
|
+
self.key = self.class.generate_key(label, description)
|
|
136
|
+
save
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def language
|
|
140
|
+
@language ||= (locale ? Tr8n::Language.for(locale) : Tr8n::Config.default_language)
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def tokenized_label
|
|
144
|
+
@tokenized_label ||= Tr8n::TokenizedLabel.new(label)
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# comments are left for a specific language
|
|
148
|
+
def comments(language = Tr8n::Config.current_language)
|
|
149
|
+
Tr8n::TranslationKeyComment.find(:all, :conditions => ["language_id = ? and translation_key_id = ?", language.id, self.id])
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
delegate :tokens, :tokens?, :to => :tokenized_label
|
|
153
|
+
delegate :data_tokens, :data_tokens?, :to => :tokenized_label
|
|
154
|
+
delegate :decoration_tokens, :decoration_tokens?, :to => :tokenized_label
|
|
155
|
+
delegate :translation_tokens, :translation_tokens?, :to => :tokenized_label
|
|
156
|
+
delegate :sanitized_label, :tokenless_label, :suggestion_tokens, :words, :to => :tokenized_label
|
|
157
|
+
|
|
158
|
+
# returns only the tokens that depend on one or more rules of the language, if any defined for the language
|
|
159
|
+
def language_rules_dependant_tokens(language = Tr8n::Config.current_language)
|
|
160
|
+
toks = []
|
|
161
|
+
included_token_hash = {}
|
|
162
|
+
|
|
163
|
+
data_tokens.each do |token|
|
|
164
|
+
next unless token.dependant?
|
|
165
|
+
next if included_token_hash[token.name]
|
|
166
|
+
|
|
167
|
+
token.language_rules.each do |rule_class|
|
|
168
|
+
if language.rule_classes.include?(rule_class)
|
|
169
|
+
toks << token
|
|
170
|
+
included_token_hash[token.name] = token
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
toks << Tr8n::Config.viewing_user_token_for(label) if language.gender_rules?
|
|
176
|
+
toks.uniq
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
# determines whether the key can have rules generated for the language
|
|
180
|
+
def permutatable?(language = Tr8n::Config.current_language)
|
|
181
|
+
language_rules_dependant_tokens(language).any?
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def glossary
|
|
185
|
+
@glossary ||= Tr8n::Glossary.find(:all, :conditions => ["keyword in (?)", words], :order => "keyword asc")
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def glossary?
|
|
189
|
+
not glossary.empty?
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def lock_for(language)
|
|
193
|
+
Tr8n::TranslationKeyLock.for(self, language)
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def lock!(language = Tr8n::Config.current_language, translator = Tr8n::Config.current_translator)
|
|
197
|
+
lock_for(language).lock!(translator)
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def unlock!(language = Tr8n::Config.current_language, translator = Tr8n::Config.current_translator)
|
|
201
|
+
lock_for(language).unlock!(translator)
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def unlock_all!
|
|
205
|
+
locks.each do |lock|
|
|
206
|
+
lock.unlock!
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def locked?(language = Tr8n::Config.current_language)
|
|
211
|
+
lock_for(language).locked?
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def unlocked?(language = Tr8n::Config.current_language)
|
|
215
|
+
not locked?(language)
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
def followed?(translator = Tr8n::Config.current_translator)
|
|
219
|
+
Tr8n::TranslatorFollowing.following_for(translator, self)
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
def add_translation(label, rules = nil, language = Tr8n::Config.current_language, translator = Tr8n::Config.current_translator)
|
|
223
|
+
raise Tr8n::Exception.new("The sentence contains dirty words") unless language.clean_sentence?(label)
|
|
224
|
+
|
|
225
|
+
translation = Tr8n::Translation.create(:translation_key => self, :language => language,
|
|
226
|
+
:translator => translator, :label => label, :rules => rules)
|
|
227
|
+
translation.vote!(translator, 1)
|
|
228
|
+
translation
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
# returns all translations for the key, language and minimal rank
|
|
232
|
+
def translations_for(language, rank = nil)
|
|
233
|
+
conditions = ["translation_key_id = ? and language_id = ?", self.id, language.id]
|
|
234
|
+
|
|
235
|
+
if rank
|
|
236
|
+
conditions[0] << " and rank >= ?"
|
|
237
|
+
conditions << rank
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
Tr8n::Translation.find(:all, :conditions => conditions, :order => "rank desc")
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
# used by the inline popup dialog, we don't want to show blocked translations
|
|
244
|
+
def inline_translations_for(language)
|
|
245
|
+
translations_for(language, -50)
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
# returns only the translations that meet the minimum rank
|
|
249
|
+
def valid_translations_for(language)
|
|
250
|
+
Tr8n::Cache.fetch("translations_#{language.locale}_#{self.key}") do
|
|
251
|
+
translations_for(language, Tr8n::Config.translation_threshold)
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
def translation_with_such_rules_exist?(language_translations, translator, rules_hash)
|
|
256
|
+
language_translations.each do |translation|
|
|
257
|
+
return true if translation.matches_rule_definitions?(rules_hash)
|
|
258
|
+
end
|
|
259
|
+
false
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
# {"actor"=>{"gender"=>"true"}, "target"=>{"gender"=>"true", "value"=>"true"}}
|
|
263
|
+
def generate_rule_permutations(language, translator, dependencies)
|
|
264
|
+
return if dependencies.blank?
|
|
265
|
+
|
|
266
|
+
token_rules = {}
|
|
267
|
+
|
|
268
|
+
dependency_mapping = {}
|
|
269
|
+
|
|
270
|
+
# make into {"actor"=>[1], "target"=>[1], "target_@1"=>[2]}
|
|
271
|
+
dependencies.each do |dependency, rule_types|
|
|
272
|
+
rule_types.keys.each_with_index do |rule_type, index|
|
|
273
|
+
token_key = dependency + "_@#{index}"
|
|
274
|
+
dependency_mapping[token_key] = dependency
|
|
275
|
+
|
|
276
|
+
rules = language.default_rules_for(rule_type)
|
|
277
|
+
token_rules[token_key] = [] unless token_rules[token_key]
|
|
278
|
+
token_rules[token_key] << rules
|
|
279
|
+
token_rules[token_key].flatten!
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
language_translations = translations_for(language)
|
|
284
|
+
|
|
285
|
+
new_translations = []
|
|
286
|
+
token_rules.combinations.each do |combination|
|
|
287
|
+
rules = []
|
|
288
|
+
rules_hash = {}
|
|
289
|
+
|
|
290
|
+
combination.each do |token, language_rule|
|
|
291
|
+
token_key = dependency_mapping[token]
|
|
292
|
+
rules_hash[token_key] ||= []
|
|
293
|
+
rules_hash[token_key] << language_rule.id.to_s
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
rules = rules_hash.collect{|token_key, rule_ids| {:token => token_key, :rule_id => rule_ids}}
|
|
297
|
+
|
|
298
|
+
# if the user has previously create this particular combination, move on...
|
|
299
|
+
next if translation_with_such_rules_exist?(language_translations, translator, rules_hash)
|
|
300
|
+
new_translations << Tr8n::Translation.create(:translation_key => self, :language => language, :translator => translator, :label => sanitized_label, :rules => rules)
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
new_translations
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
def self.random
|
|
307
|
+
find(:first, :offset => rand(count - 1))
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
# returns back grouped by context
|
|
311
|
+
def find_all_valid_translations(translations)
|
|
312
|
+
if translations.empty?
|
|
313
|
+
return {:key => self.key, :label => self.label, :original => true}
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
# if the first translation does not depend on any of the context rules
|
|
317
|
+
# use it... we don't care about the rest of the rules.
|
|
318
|
+
if translations.first.rules_hash.blank?
|
|
319
|
+
return {:key => self.key, :label => translations.first.label}
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
# build a context hash for every kind of context rules combinations
|
|
323
|
+
# only the first one in the list should be used
|
|
324
|
+
context_hash_matches = {}
|
|
325
|
+
valid_translations = []
|
|
326
|
+
translations.each do |translation|
|
|
327
|
+
context_key = translation.rules_hash || ""
|
|
328
|
+
next if context_hash_matches[context_key]
|
|
329
|
+
context_hash_matches[context_key] = true
|
|
330
|
+
if translation.rules_definitions
|
|
331
|
+
valid_translations << {:label => translation.label, :context => translation.rules_definitions.clone}
|
|
332
|
+
else
|
|
333
|
+
valid_translations << {:label => translation.label}
|
|
334
|
+
end
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
# always add the default one at the end, so if none of the rules matched, use the english one
|
|
338
|
+
valid_translations << {:label => self.label} unless context_hash_matches[""]
|
|
339
|
+
{:key => self.key, :labels => valid_translations}
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
def find_first_valid_translation(language, token_values)
|
|
343
|
+
# find the first translation in the order of the rank that matches the rules
|
|
344
|
+
valid_translations_for(language).each do |translation|
|
|
345
|
+
return translation if translation.matches_rules?(token_values)
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
nil
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
# language fallback approach
|
|
352
|
+
# each language can have a fallback language
|
|
353
|
+
def find_first_valid_translation_for_language(language, token_values)
|
|
354
|
+
translation = find_first_valid_translation(language, token_values)
|
|
355
|
+
return [language, translation] if translation
|
|
356
|
+
|
|
357
|
+
if Tr8n::Config.enable_fallback_languages?
|
|
358
|
+
# recursevily go into the fallback language and look there
|
|
359
|
+
# no need to go to the default language - there obviously won't be any translations for it
|
|
360
|
+
# unless you really won't to keep the keys in the text, and translate the default language
|
|
361
|
+
if language.fallback_language and not language.fallback_language.default?
|
|
362
|
+
return find_first_valid_translation_for_language(language.fallback_language, token_values)
|
|
363
|
+
end
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
[language, nil]
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
# translator fallback approach
|
|
370
|
+
# each translator can have a fallback language, which may have a fallback language
|
|
371
|
+
def find_first_valid_translation_for_translator(language, translator, token_values)
|
|
372
|
+
translation = find_first_valid_translation(language, token_values)
|
|
373
|
+
return [language, translation] if translation
|
|
374
|
+
|
|
375
|
+
if translator.fallback_language and not translator.fallback_language.default?
|
|
376
|
+
return find_first_valid_translation_for_language(translator.fallback_language, token_values)
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
[language, nil]
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
def translate(language = Tr8n::Config.current_language, token_values = {}, options = {})
|
|
383
|
+
return find_all_valid_translations(valid_translations_for(language)) if options[:api]
|
|
384
|
+
|
|
385
|
+
if Tr8n::Config.disabled? or language.default?
|
|
386
|
+
return substitute_tokens(label, token_values, options.merge(:fallback => false), language).html_safe
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
if Tr8n::Config.enable_translator_language? and Tr8n::Config.current_user_is_translator?
|
|
390
|
+
translation_language, translation = find_first_valid_translation_for_translator(language, Tr8n::Config.current_translator, token_values)
|
|
391
|
+
else
|
|
392
|
+
translation_language, translation = find_first_valid_translation_for_language(language, token_values)
|
|
393
|
+
end
|
|
394
|
+
|
|
395
|
+
# if you want to present the label in it's sanitized form - for the phrase list
|
|
396
|
+
if options[:default_language]
|
|
397
|
+
return decorate_translation(language, sanitized_label, translation != nil, options).html_safe
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
if translation
|
|
401
|
+
translated_label = substitute_tokens(translation.label, token_values, options, language)
|
|
402
|
+
return decorate_translation(language, translated_label, translation != nil, options.merge(:fallback => (translation_language != language))).html_safe
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
# no translation found
|
|
406
|
+
translated_label = substitute_tokens(label, token_values, options, Tr8n::Config.default_language)
|
|
407
|
+
decorate_translation(language, translated_label, translation != nil, options).html_safe
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
###############################################################
|
|
411
|
+
## Substitution and Decoration Related Stuff
|
|
412
|
+
###############################################################
|
|
413
|
+
|
|
414
|
+
# this is done when the translations engine is disabled
|
|
415
|
+
def self.substitute_tokens(label, tokens, options = {}, language = Tr8n::Config.default_language)
|
|
416
|
+
return label.to_s if options[:skip_substitution]
|
|
417
|
+
Tr8n::TranslationKey.new(:label => label.to_s).substitute_tokens(label.to_s, tokens, options, language)
|
|
418
|
+
end
|
|
419
|
+
|
|
420
|
+
def substitute_tokens(translated_label, token_values, options = {}, language = Tr8n::Config.current_language)
|
|
421
|
+
processed_label = translated_label.to_s.clone
|
|
422
|
+
|
|
423
|
+
# substitute all data tokens
|
|
424
|
+
Tr8n::TokenizedLabel.new(processed_label).data_tokens.each do |token|
|
|
425
|
+
next unless tokenized_label.allowed_token?(token)
|
|
426
|
+
processed_label = token.substitute(processed_label, token_values, options, language)
|
|
427
|
+
end
|
|
428
|
+
|
|
429
|
+
# substitute all decoration tokens
|
|
430
|
+
Tr8n::TokenizedLabel.new(processed_label).decoration_tokens.each do |token|
|
|
431
|
+
next unless tokenized_label.allowed_token?(token)
|
|
432
|
+
processed_label = token.substitute(processed_label, token_values, options, language)
|
|
433
|
+
end
|
|
434
|
+
|
|
435
|
+
processed_label
|
|
436
|
+
end
|
|
437
|
+
|
|
438
|
+
def default_decoration(language = Tr8n::Config.current_language, options = {})
|
|
439
|
+
return label if Tr8n::Config.current_user_is_guest?
|
|
440
|
+
return label unless Tr8n::Config.current_user_is_translator?
|
|
441
|
+
return label unless translator_permitted_to_translate?
|
|
442
|
+
return label if locked?(language)
|
|
443
|
+
|
|
444
|
+
classes = ['tr8n_translatable']
|
|
445
|
+
|
|
446
|
+
if valid_translations_for(language).any?
|
|
447
|
+
classes << 'tr8n_translated'
|
|
448
|
+
else
|
|
449
|
+
classes << 'tr8n_not_translated'
|
|
450
|
+
end
|
|
451
|
+
|
|
452
|
+
html = "<tr8n class='#{classes.join(' ')}' translation_key_id='#{id}'>"
|
|
453
|
+
html << label
|
|
454
|
+
html << "</tr8n>"
|
|
455
|
+
html.html_safe
|
|
456
|
+
end
|
|
457
|
+
|
|
458
|
+
def level
|
|
459
|
+
return 0 if super.nil?
|
|
460
|
+
super
|
|
461
|
+
end
|
|
462
|
+
|
|
463
|
+
def translator_permitted_to_translate?(translator = Tr8n::Config.current_translator)
|
|
464
|
+
translator.level >= level
|
|
465
|
+
end
|
|
466
|
+
|
|
467
|
+
def decorate_translation(language, translated_label, translated = true, options = {})
|
|
468
|
+
return translated_label if options[:skip_decorations]
|
|
469
|
+
return translated_label if Tr8n::Config.current_user_is_guest?
|
|
470
|
+
return translated_label unless Tr8n::Config.current_user_is_translator?
|
|
471
|
+
return translated_label unless Tr8n::Config.current_translator.enable_inline_translations?
|
|
472
|
+
return translated_label unless translator_permitted_to_translate?
|
|
473
|
+
return translated_label if locked?(language)
|
|
474
|
+
return translated_label if self.language == language
|
|
475
|
+
|
|
476
|
+
classes = ['tr8n_translatable']
|
|
477
|
+
|
|
478
|
+
if language.default?
|
|
479
|
+
classes << 'tr8n_not_translated'
|
|
480
|
+
elsif options[:fallback]
|
|
481
|
+
classes << 'tr8n_fallback'
|
|
482
|
+
else
|
|
483
|
+
classes << (translated ? 'tr8n_translated' : 'tr8n_not_translated')
|
|
484
|
+
end
|
|
485
|
+
|
|
486
|
+
html = "<tr8n class='#{classes.join(' ')}' translation_key_id='#{id}'>"
|
|
487
|
+
html << translated_label
|
|
488
|
+
html << "</tr8n>"
|
|
489
|
+
html
|
|
490
|
+
end
|
|
491
|
+
|
|
492
|
+
def verify!(time = Time.now)
|
|
493
|
+
update_attributes(:verified_at => time)
|
|
494
|
+
end
|
|
495
|
+
|
|
496
|
+
def update_translation_count!
|
|
497
|
+
update_attributes(:translation_count => Tr8n::Translation.count(:conditions => ["translation_key_id = ?", self.id]))
|
|
498
|
+
end
|
|
499
|
+
|
|
500
|
+
def source_map
|
|
501
|
+
@source_map ||= begin
|
|
502
|
+
map = {}
|
|
503
|
+
sources.each do |source|
|
|
504
|
+
(map[source.domain.name] ||= []) << source
|
|
505
|
+
end
|
|
506
|
+
map
|
|
507
|
+
end
|
|
508
|
+
end
|
|
509
|
+
|
|
510
|
+
def clear_cache
|
|
511
|
+
Tr8n::Cache.delete("translation_key_#{key}")
|
|
512
|
+
end
|
|
513
|
+
|
|
514
|
+
def add_translation(label, rules = nil, lang = Tr8n::Config.current_language, translator = Tr8n::Config.current_translator)
|
|
515
|
+
Tr8n::Translation.create(:translation_key => self, :label => label, :language => lang, :translator => translator)
|
|
516
|
+
end
|
|
517
|
+
|
|
518
|
+
###############################################################
|
|
519
|
+
## Feature Related Stuff
|
|
520
|
+
###############################################################
|
|
521
|
+
|
|
522
|
+
def self.title
|
|
523
|
+
"Original Phrase in {language}".translate(nil, :language => Tr8n::Config.current_language.native_name)
|
|
524
|
+
end
|
|
525
|
+
|
|
526
|
+
def self.help_url
|
|
527
|
+
'/tr8n/help'
|
|
528
|
+
end
|
|
529
|
+
|
|
530
|
+
def suggestions?
|
|
531
|
+
true
|
|
532
|
+
end
|
|
533
|
+
|
|
534
|
+
def rules?
|
|
535
|
+
translation_tokens? or Tr8n::Config.current_language.has_rules?
|
|
536
|
+
end
|
|
537
|
+
|
|
538
|
+
def dictionary?
|
|
539
|
+
true
|
|
540
|
+
end
|
|
541
|
+
|
|
542
|
+
def sources?
|
|
543
|
+
true
|
|
544
|
+
end
|
|
545
|
+
|
|
546
|
+
###############################################################
|
|
547
|
+
## Search Related Stuff
|
|
548
|
+
###############################################################
|
|
549
|
+
|
|
550
|
+
def self.filter_phrase_type_options
|
|
551
|
+
[["all", "any"],
|
|
552
|
+
["without translations", "without"],
|
|
553
|
+
["with translations", "with"],
|
|
554
|
+
["followed by me", "followed"]
|
|
555
|
+
]
|
|
556
|
+
end
|
|
557
|
+
|
|
558
|
+
def self.filter_phrase_status_options
|
|
559
|
+
[["any", "any"],
|
|
560
|
+
["pending approval", "pending"],
|
|
561
|
+
["approved", "approved"]]
|
|
562
|
+
end
|
|
563
|
+
|
|
564
|
+
def self.filter_phrase_lock_options
|
|
565
|
+
[["locked and unlocked", "any"],
|
|
566
|
+
["locked only", "locked"],
|
|
567
|
+
["unlocked only", "unlocked"]]
|
|
568
|
+
end
|
|
569
|
+
|
|
570
|
+
def self.search_conditions_for(params)
|
|
571
|
+
conditions = ["tr8n_translation_keys.locale <> ? and (level is null or level <= ?)", Tr8n::Config.current_language.locale, Tr8n::Config.current_translator.level]
|
|
572
|
+
|
|
573
|
+
if Tr8n::Config.enable_caching?
|
|
574
|
+
conditions[0] << " and verified_at is not null"
|
|
575
|
+
end
|
|
576
|
+
|
|
577
|
+
unless params[:search].blank?
|
|
578
|
+
conditions[0] << " and (tr8n_translation_keys.label like ? or tr8n_translation_keys.description like ?)"
|
|
579
|
+
conditions << "%#{params[:search]}%"
|
|
580
|
+
conditions << "%#{params[:search]}%"
|
|
581
|
+
end
|
|
582
|
+
|
|
583
|
+
# for with and approved, allow user to specify the kinds
|
|
584
|
+
if params[:phrase_type] == "with"
|
|
585
|
+
conditions[0] << " and tr8n_translation_keys.id in (select tr8n_translations.translation_key_id from tr8n_translations where tr8n_translations.language_id = ?) "
|
|
586
|
+
conditions << Tr8n::Config.current_language.id
|
|
587
|
+
|
|
588
|
+
# if approved, ensure that translation key is locked
|
|
589
|
+
if params[:phrase_status] == "approved"
|
|
590
|
+
conditions[0] << " and tr8n_translation_keys.id in (select tr8n_translation_key_locks.translation_key_id from tr8n_translation_key_locks where tr8n_translation_key_locks.language_id = ? and tr8n_translation_key_locks.locked = ?) "
|
|
591
|
+
conditions << Tr8n::Config.current_language.id
|
|
592
|
+
conditions << true
|
|
593
|
+
|
|
594
|
+
# if approved, ensure that translation key does not have a lock or unlocked
|
|
595
|
+
elsif params[:phrase_status] == "pending"
|
|
596
|
+
conditions[0] << " and tr8n_translation_keys.id not in (select tr8n_translation_key_locks.translation_key_id from tr8n_translation_key_locks where tr8n_translation_key_locks.language_id = ? and tr8n_translation_key_locks.locked = ?) "
|
|
597
|
+
conditions << Tr8n::Config.current_language.id
|
|
598
|
+
conditions << true
|
|
599
|
+
end
|
|
600
|
+
|
|
601
|
+
elsif params[:phrase_type] == "without"
|
|
602
|
+
conditions[0] << " and tr8n_translation_keys.id not in (select tr8n_translations.translation_key_id from tr8n_translations where tr8n_translations.language_id = ?)"
|
|
603
|
+
conditions << Tr8n::Config.current_language.id
|
|
604
|
+
|
|
605
|
+
elsif params[:phrase_type] == "followed"
|
|
606
|
+
conditions[0] << " and tr8n_translation_keys.id in (select tr8n_translator_following.object_id from tr8n_translator_following where tr8n_translator_following.translator_id = ? and tr8n_translator_following.object_type = ?)"
|
|
607
|
+
|
|
608
|
+
conditions << Tr8n::Config.current_translator.id
|
|
609
|
+
conditions << 'Tr8n::TranslationKey'
|
|
610
|
+
end
|
|
611
|
+
|
|
612
|
+
if params[:phrase_lock] == "locked"
|
|
613
|
+
conditions[0] << " and tr8n_translation_keys.id in (select tr8n_translation_key_locks.translation_key_id from tr8n_translation_key_locks where tr8n_translation_key_locks.language_id = ? and tr8n_translation_key_locks.locked = ?) "
|
|
614
|
+
conditions << Tr8n::Config.current_language.id
|
|
615
|
+
conditions << true
|
|
616
|
+
|
|
617
|
+
elsif params[:phrase_lock] == "unlocked"
|
|
618
|
+
conditions[0] << " and tr8n_translation_keys.id not in (select tr8n_translation_key_locks.translation_key_id from tr8n_translation_key_locks where tr8n_translation_key_locks.language_id = ? and tr8n_translation_key_locks.locked = ?) "
|
|
619
|
+
conditions << Tr8n::Config.current_language.id
|
|
620
|
+
conditions << true
|
|
621
|
+
end
|
|
622
|
+
|
|
623
|
+
conditions
|
|
624
|
+
end
|
|
625
|
+
end
|