redis_dictionary 0.9.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.md +37 -0
  3. data/Rakefile +41 -0
  4. data/app/assets/javascripts/redis_dictionary/application.js +16 -0
  5. data/app/assets/javascripts/redis_dictionary/bootstrap.js +10 -0
  6. data/app/assets/javascripts/redis_dictionary/jquery.autosize.js +192 -0
  7. data/app/assets/javascripts/redis_dictionary/translations.js +35 -0
  8. data/app/assets/stylesheets/redis_dictionary/application.css +13 -0
  9. data/app/assets/stylesheets/redis_dictionary/bootstrap_and_overrides.css +7 -0
  10. data/app/assets/stylesheets/redis_dictionary/translations.css +42 -0
  11. data/app/controllers/redis_dictionary/application_controller.rb +25 -0
  12. data/app/controllers/redis_dictionary/translations_controller.rb +51 -0
  13. data/app/helpers/redis_dictionary/application_helper.rb +39 -0
  14. data/app/models/redis_dictionary/translation.rb +64 -0
  15. data/app/views/layouts/redis_dictionary/application.html.erb +43 -0
  16. data/app/views/redis_dictionary/translations/_key_translation.html.erb +22 -0
  17. data/app/views/redis_dictionary/translations/create.js.erb +14 -0
  18. data/app/views/redis_dictionary/translations/destroy.js.erb +2 -0
  19. data/app/views/redis_dictionary/translations/index.html.erb +69 -0
  20. data/config/environment.rb +1 -0
  21. data/config/initializers/will_paginate.rb +1 -0
  22. data/config/routes.rb +14 -0
  23. data/lib/redis_dictionary.rb +25 -0
  24. data/lib/redis_dictionary/configuration.rb +21 -0
  25. data/lib/redis_dictionary/engine.rb +53 -0
  26. data/lib/redis_dictionary/version.rb +3 -0
  27. data/test/dummy/README.rdoc +261 -0
  28. data/test/dummy/Rakefile +7 -0
  29. data/test/dummy/app/assets/images/favicon.ico +0 -0
  30. data/test/dummy/app/assets/javascripts/application.js +15 -0
  31. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  32. data/test/dummy/app/controllers/application_controller.rb +4 -0
  33. data/test/dummy/app/helpers/application_helper.rb +3 -0
  34. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  35. data/test/dummy/config.ru +4 -0
  36. data/test/dummy/config/application.rb +59 -0
  37. data/test/dummy/config/boot.rb +10 -0
  38. data/test/dummy/config/database.yml +25 -0
  39. data/test/dummy/config/environment.rb +6 -0
  40. data/test/dummy/config/environments/development.rb +33 -0
  41. data/test/dummy/config/environments/production.rb +70 -0
  42. data/test/dummy/config/environments/test.rb +37 -0
  43. data/test/dummy/config/initializers/backtrace_silencers.rb +8 -0
  44. data/test/dummy/config/initializers/inflections.rb +16 -0
  45. data/test/dummy/config/initializers/mime_types.rb +6 -0
  46. data/test/dummy/config/initializers/secret_token.rb +9 -0
  47. data/test/dummy/config/initializers/session_store.rb +9 -0
  48. data/test/dummy/config/initializers/wrap_parameters.rb +15 -0
  49. data/test/dummy/config/locales/en.yml +5 -0
  50. data/test/dummy/config/routes.rb +4 -0
  51. data/test/dummy/db/schema.rb +16 -0
  52. data/test/dummy/db/test.sqlite3 +0 -0
  53. data/test/dummy/log/test.log +1003 -0
  54. data/test/dummy/public/404.html +26 -0
  55. data/test/dummy/public/422.html +26 -0
  56. data/test/dummy/public/500.html +25 -0
  57. data/test/dummy/public/favicon.ico +0 -0
  58. data/test/dummy/script/rails +7 -0
  59. data/test/functional/redis_dictionary/translations_controller_test.rb +37 -0
  60. data/test/integration/redis_dictionary/translations_test.rb +113 -0
  61. data/test/redis_dictionary/configuration_test.rb +24 -0
  62. data/test/redis_dictionary_test.rb +22 -0
  63. data/test/test_helper.rb +43 -0
  64. data/test/unit/helpers/redis_dictionary/application_helper_test.rb +61 -0
  65. data/test/unit/redis_dictionary/translation_test.rb +89 -0
  66. metadata +360 -0
@@ -0,0 +1,20 @@
1
+ Copyright 2013 José Galisteo Ruiz and Fourmach S.L.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,37 @@
1
+ # Redis Dictionary
2
+
3
+ [![Build Status](https://travis-ci.org/redrick/redis_dictionary.png?branch=master)](https://travis-ci.org/redrick/redis_dictionary)
4
+ [![Coverage Status](https://coveralls.io/repos/redrick/redis_dictionary/badge.png?branch=master)](https://coveralls.io/r/redrick/redis_dictionary?branch=master)
5
+
6
+ Rails frontend for i18n with redis backend as extended version of [fourmach/i18n_dashboard](https://github.com/fourmach/i18n_dashboard) gem.
7
+
8
+ ## Screenshots
9
+
10
+ ![#](https://raw.github.com/redrick/redis_dictionary/master/doc/screenshot-1.png)
11
+ ![#](https://raw.github.com/redrick/redis_dictionary/master/doc/screenshot-2.png)
12
+
13
+
14
+ ## Installation
15
+
16
+ Add this line to your application's Gemfile:
17
+
18
+ ``` ruby
19
+ gem 'redis_dictionary'
20
+ ```
21
+
22
+
23
+ And then execute:
24
+
25
+ $ bundle
26
+
27
+ Modify your config/routes.rb and add:
28
+
29
+ ``` ruby
30
+ mount RedisDictionary::Engine => '/translations'
31
+ ```
32
+
33
+ ## Thanks
34
+
35
+ * [Jose Galisteo](https://github.com/ceritium) for writing [I18n_dashboard](https://github.com/fourmach/i18n_dashboard)
36
+ * [Alberto Fernández-Capel](https://github.com/afcapel): [Setup integration tests with capybara](https://github.com/fourmach/i18n_dashboard/pull/1)
37
+ * Great tips of [Blogit](https://github.com/KatanaCode/blogit).
@@ -0,0 +1,41 @@
1
+ # encoding: utf-8
2
+ #!/usr/bin/env rake
3
+ begin
4
+ require 'bundler/setup'
5
+ rescue LoadError
6
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
7
+ end
8
+ begin
9
+ require 'rdoc/task'
10
+ rescue LoadError
11
+ require 'rdoc/rdoc'
12
+ require 'rake/rdoctask'
13
+ RDoc::Task = Rake::RDocTask
14
+ end
15
+
16
+ RDoc::Task.new(:rdoc) do |rdoc|
17
+ rdoc.rdoc_dir = 'rdoc'
18
+ rdoc.title = 'RedisDictionary'
19
+ rdoc.options << '--line-numbers'
20
+ rdoc.rdoc_files.include('README.rdoc')
21
+ rdoc.rdoc_files.include('lib/**/*.rb')
22
+ end
23
+
24
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
25
+ load 'rails/tasks/engine.rake'
26
+
27
+
28
+
29
+ Bundler::GemHelper.install_tasks
30
+
31
+ require 'rake/testtask'
32
+
33
+ Rake::TestTask.new(:test) do |t|
34
+ t.libs << 'lib'
35
+ t.libs << 'test'
36
+ t.pattern = 'test/**/*_test.rb'
37
+ t.verbose = false
38
+ end
39
+
40
+
41
+ task :default => :test
@@ -0,0 +1,16 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // the compiled file.
9
+ //
10
+ // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
11
+ // GO AFTER THE REQUIRES BELOW.
12
+ //
13
+ //= require jquery
14
+ //= require jquery_ujs
15
+ //= require twitter/bootstrap
16
+ //= require_tree .
@@ -0,0 +1,10 @@
1
+ // jQuery ->
2
+ // $("a[rel=popover]").popover()
3
+ // $(".tooltip").tooltip()
4
+ // $("a[rel=tooltip]").tooltip()
5
+
6
+ jQuery(function() {
7
+ $("a[rel=popover]").popover();
8
+ $(".tooltip").tooltip();
9
+ return $("a[rel=tooltip]").tooltip();
10
+ });
@@ -0,0 +1,192 @@
1
+ /*!
2
+ jQuery Autosize v1.16.7
3
+ (c) 2013 Jack Moore - jacklmoore.com
4
+ updated: 2013-03-20
5
+ license: http://www.opensource.org/licenses/mit-license.php
6
+ */
7
+
8
+
9
+ (function ($) {
10
+ var
11
+ defaults = {
12
+ className: 'autosizejs',
13
+ append: '',
14
+ callback: false
15
+ },
16
+ hidden = 'hidden',
17
+ borderBox = 'border-box',
18
+ lineHeight = 'lineHeight',
19
+ supportsScrollHeight,
20
+
21
+ // border:0 is unnecessary, but avoids a bug in FireFox on OSX (http://www.jacklmoore.com/autosize#comment-851)
22
+ copy = '<textarea tabindex="-1" style="position:absolute; top:-999px; left:0; right:auto; bottom:auto; border:0; -moz-box-sizing:content-box; -webkit-box-sizing:content-box; box-sizing:content-box; word-wrap:break-word; height:0 !important; min-height:0 !important; width: 0; overflow:hidden;"/>',
23
+
24
+ // line-height is conditionally included because IE7/IE8/old Opera do not return the correct value.
25
+ copyStyle = [
26
+ 'fontFamily',
27
+ 'fontSize',
28
+ 'fontWeight',
29
+ 'fontStyle',
30
+ 'letterSpacing',
31
+ 'textTransform',
32
+ 'wordSpacing',
33
+ 'textIndent'
34
+ ],
35
+ oninput = 'oninput',
36
+ onpropertychange = 'onpropertychange',
37
+
38
+ // to keep track which textarea is being mirrored when adjust() is called.
39
+ mirrored,
40
+
41
+ // the mirror element, which is used to calculate what size the mirrored element should be.
42
+ mirror = $(copy).data('autosize', true)[0];
43
+
44
+ // test that line-height can be accurately copied.
45
+ mirror.style.lineHeight = '99px';
46
+ if ($(mirror).css(lineHeight) === '99px') {
47
+ copyStyle.push(lineHeight);
48
+ }
49
+ mirror.style.lineHeight = '';
50
+
51
+ $.fn.autosize = function (options) {
52
+ options = $.extend({}, defaults, options || {});
53
+
54
+ if (mirror.parentNode !== document.body) {
55
+ $(document.body).append(mirror);
56
+
57
+ mirror.value = "\n\n\n";
58
+ mirror.scrollTop = 9e4;
59
+ supportsScrollHeight = mirror.scrollHeight === mirror.scrollTop + mirror.clientHeight;
60
+ }
61
+
62
+ return this.each(function () {
63
+ var
64
+ ta = this,
65
+ $ta = $(ta),
66
+ minHeight,
67
+ active,
68
+ resize,
69
+ boxOffset = 0,
70
+ callback = $.isFunction(options.callback);
71
+
72
+ if ($ta.data('autosize')) {
73
+ // exit if autosize has already been applied, or if the textarea is the mirror element.
74
+ return;
75
+ }
76
+
77
+ if ($ta.css('box-sizing') === borderBox || $ta.css('-moz-box-sizing') === borderBox || $ta.css('-webkit-box-sizing') === borderBox){
78
+ boxOffset = $ta.outerHeight() - $ta.height();
79
+ }
80
+
81
+ minHeight = Math.max(parseInt($ta.css('minHeight'), 10) - boxOffset, $ta.height());
82
+
83
+ resize = ($ta.css('resize') === 'none' || $ta.css('resize') === 'vertical') ? 'none' : 'horizontal';
84
+
85
+ $ta.css({
86
+ overflow: hidden,
87
+ overflowY: hidden,
88
+ wordWrap: 'break-word',
89
+ resize: resize
90
+ }).data('autosize', true);
91
+
92
+ function initMirror() {
93
+ mirrored = ta;
94
+ mirror.className = options.className;
95
+
96
+ // mirror is a duplicate textarea located off-screen that
97
+ // is automatically updated to contain the same text as the
98
+ // original textarea. mirror always has a height of 0.
99
+ // This gives a cross-browser supported way getting the actual
100
+ // height of the text, through the scrollTop property.
101
+ $.each(copyStyle, function(i, val){
102
+ mirror.style[val] = $ta.css(val);
103
+ });
104
+ }
105
+
106
+ // Using mainly bare JS in this function because it is going
107
+ // to fire very often while typing, and needs to very efficient.
108
+ function adjust() {
109
+ var height, overflow, original;
110
+
111
+ if (mirrored !== ta) {
112
+ initMirror();
113
+ }
114
+
115
+ // the active flag keeps IE from tripping all over itself. Otherwise
116
+ // actions in the adjust function will cause IE to call adjust again.
117
+ if (!active) {
118
+ active = true;
119
+ mirror.value = ta.value + options.append;
120
+ mirror.style.overflowY = ta.style.overflowY;
121
+ original = parseInt(ta.style.height,10);
122
+
123
+ // Update the width in case the original textarea width has changed
124
+ // A floor of 0 is needed because IE8 returns a negative value for hidden textareas, raising an error.
125
+ mirror.style.width = Math.max($ta.width(), 0) + 'px';
126
+
127
+ if (supportsScrollHeight) {
128
+ height = mirror.scrollHeight;
129
+ } else { // IE6 & IE7
130
+ mirror.scrollTop = 0;
131
+ mirror.scrollTop = 9e4;
132
+ height = mirror.scrollTop;
133
+ }
134
+
135
+ var maxHeight = parseInt($ta.css('maxHeight'), 10);
136
+ // Opera returns '-1px' when max-height is set to 'none'.
137
+ maxHeight = maxHeight && maxHeight > 0 ? maxHeight : 9e4;
138
+ if (height > maxHeight) {
139
+ height = maxHeight;
140
+ overflow = 'scroll';
141
+ } else if (height < minHeight) {
142
+ height = minHeight;
143
+ }
144
+ height += boxOffset;
145
+ ta.style.overflowY = overflow || hidden;
146
+
147
+ if (original !== height) {
148
+ ta.style.height = height + 'px';
149
+ if (callback) {
150
+ options.callback.call(ta,ta);
151
+ }
152
+ }
153
+
154
+ // This small timeout gives IE a chance to draw it's scrollbar
155
+ // before adjust can be run again (prevents an infinite loop).
156
+ setTimeout(function () {
157
+ active = false;
158
+ }, 1);
159
+ }
160
+ }
161
+
162
+ if (onpropertychange in ta) {
163
+ if (oninput in ta) {
164
+ // Detects IE9. IE9 does not fire onpropertychange or oninput for deletions,
165
+ // so binding to onkeyup to catch most of those occassions. There is no way that I
166
+ // know of to detect something like 'cut' in IE9.
167
+ ta[oninput] = ta.onkeyup = adjust;
168
+ } else {
169
+ // IE7 / IE8
170
+ ta[onpropertychange] = adjust;
171
+ }
172
+ } else {
173
+ // Modern Browsers
174
+ ta[oninput] = adjust;
175
+ }
176
+
177
+ $(window).on('resize', function(){
178
+ active = false;
179
+ adjust();
180
+ });
181
+
182
+ // Allow for manual triggering if needed.
183
+ $ta.on('autosize', function(){
184
+ active = false;
185
+ adjust();
186
+ });
187
+
188
+ // Call adjust in case the textarea already contains text.
189
+ adjust();
190
+ });
191
+ };
192
+ }(window.jQuery || window.Zepto));
@@ -0,0 +1,35 @@
1
+ // jQuery ->
2
+ // $('#form-translation textarea').autosize()
3
+
4
+ // $('#add-translation-link').click (event) ->
5
+ // event.preventDefault()
6
+ // $('#form-translation #locale').val('')
7
+ // $('#form-translation #key').val('')
8
+ // $('#form-translation #value').val('')
9
+ // $('#form-translation #value').trigger('autosize')
10
+
11
+ // $('.edit-translation').click (event) ->
12
+ // event.preventDefault()
13
+ // $('#form-translation #locale').val($(@).data('locale'))
14
+ // $('#form-translation #key').val($(@).data('key'))
15
+ // $('#form-translation #value').val($(@).html().trim())
16
+
17
+ // $('#form-translation #value').trigger('autosize')
18
+
19
+ jQuery(function() {
20
+ $('#form-translation textarea').autosize();
21
+ $('#add-translation-link').click(function(event) {
22
+ event.preventDefault();
23
+ $('#form-translation #locale').val('');
24
+ $('#form-translation #key').val('');
25
+ $('#form-translation #value').val('');
26
+ return $('#form-translation #value').trigger('autosize');
27
+ });
28
+ return $('.edit-translation').click(function(event) {
29
+ event.preventDefault();
30
+ $('#form-translation #locale').val($(this).data('locale'));
31
+ $('#form-translation #key').val($(this).data('key'));
32
+ $('#form-translation #value').val($(this).html().trim());
33
+ return $('#form-translation #value').trigger('autosize');
34
+ });
35
+ });
@@ -0,0 +1,13 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the top of the
9
+ * compiled file, but it's generally better to create a new file per style scope.
10
+ *
11
+ *= require_self
12
+ *= require_tree .
13
+ */
@@ -0,0 +1,7 @@
1
+ /*
2
+ =require twitter-bootstrap-static/bootstrap
3
+
4
+ Use Font Awesome icons (default)
5
+ To use Glyphicons sprites instead of Font Awesome, replace with "require twitter-bootstrap-static/sprites"
6
+ =require twitter-bootstrap-static/fontawesome
7
+ */
@@ -0,0 +1,42 @@
1
+ /*
2
+ Place all the styles related to the matching controller here.
3
+ They will automatically be included in application.css.
4
+ */
5
+
6
+ .apple_pagination {
7
+ background: #f1f1f1;
8
+ border: 1px solid #e5e5e5;
9
+ text-align: center;
10
+ padding: 1em;
11
+ cursor: default; }
12
+ .apple_pagination a, .apple_pagination span {
13
+ padding: 0.2em 0.3em; }
14
+ .apple_pagination .disabled {
15
+ color: #aaaaaa; }
16
+ .apple_pagination .current {
17
+ font-style: normal;
18
+ font-weight: bold;
19
+ background-color: #bebebe;
20
+ display: inline-block;
21
+ width: 1.4em;
22
+ height: 1.4em;
23
+ line-height: 1.5;
24
+ -moz-border-radius: 1em;
25
+ -webkit-border-radius: 1em;
26
+ border-radius: 1em;
27
+ text-shadow: rgba(255, 255, 255, 0.8) 1px 1px 1px; }
28
+ .apple_pagination a {
29
+ text-decoration: none;
30
+ color: black; }
31
+ .apple_pagination a:hover, .apple_pagination a:focus {
32
+ text-decoration: underline; }
33
+
34
+
35
+ #footer {
36
+ min-height:60px;
37
+ background-color: #333;
38
+ }
39
+
40
+ .flr {
41
+ float:right;
42
+ }
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+
3
+ module RedisDictionary
4
+ class ApplicationController < ActionController::Base
5
+
6
+ layout RedisDictionary.configuration.layout if RedisDictionary.configuration.layout
7
+
8
+ # Sets a class method to specify a before-filter csalling
9
+ # whatever RedisDictionary.configuration.authentication_method is set to
10
+ # Accepts the usual before_filter optionss
11
+ def self.redis_dictionary_authenticate(options ={})
12
+ if redis_dictionary_conf.authentication_method
13
+ before_filter redis_dictionary_conf.authentication_method, options
14
+ end
15
+ end
16
+
17
+ # A helper method to access the RedisDictionary::configuration
18
+ # at the class level
19
+ def self.redis_dictionary_conf
20
+ RedisDictionary::configuration
21
+ end
22
+
23
+
24
+ end
25
+ end