phrasing 4.0.0rc3 → 4.0.0rc4

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: aa17e70cddb3a13fbaefc3f473d185c93ddad028
4
- data.tar.gz: 4947a95d4f5c5f1dda178056a589b2f2548fedf9
3
+ metadata.gz: 6ec5cf82a1f8789b4f8c7f25f1fd93ec9c370ded
4
+ data.tar.gz: 9d92db89baa70f2adf1fd122ced6cb949ee4e44e
5
5
  SHA512:
6
- metadata.gz: 645b4738ea92b854116bac7cdaef56a797c4121629788a5d7b7b956a11d0869152ccb694a319552ff87ec9938ebc537c64716f419931e60fc6503a9772ac5014
7
- data.tar.gz: 01aff8859f2081498e5f274a5239f329b6f5ce0faf16b14b85170dd843edfaaaed5ab9a411874552e60708b662be0d945f60857b9a46eb47efe9fb6a76fbc91a
6
+ metadata.gz: 1ab0220b8ad7cf33ec522ba8155d2aeb65ffed693bb2c4eed8a8ce736efc0ae8b96d859618829092b6c3a6984dd4a13affe8cc9935fafc199f08ea3f9afd717b
7
+ data.tar.gz: 61f3907edde2443d5b50f050f01edfec95f258614601aebc3d77e02db8795868a6067b4e17e7ab6318cf7ce9436dd666271e80edcf7812b9bf470261d40b9197
@@ -1,9 +1,12 @@
1
1
  language: ruby
2
- rvm:
3
- - 1.9.3
4
- - 2.0.0
5
- - 2.1.2
6
- env:
7
- - "RAILS_VERSION=3.2.0"
8
- - "RAILS_VERSION=4.0.0"
9
- - "RAILS_VERSION=4.1.0"
2
+
3
+ matrix:
4
+ include:
5
+ - rvm: 1.9.3
6
+ env: "RAILS_VERSION=3.2.0"
7
+ - rvm: 2.0.0
8
+ env: "RAILS_VERSION=4.0.0"
9
+ - rvm: 2.1.2
10
+ env: "RAILS_VERSION=4.1.0"
11
+ - rvm: 2.2.0
12
+ env: "RAILS_VERSION=4.2.0"
@@ -1,5 +1,13 @@
1
1
  # Phrasing Change Log
2
2
 
3
+ ## 3.2.9 (January 7th, 2015)
4
+
5
+ Require only haml, not haml-rails.
6
+
7
+ ## 3.2.8 (January 6th, 2015)
8
+
9
+ Fix confirm dialogs when deleting phrases and phrase versions.
10
+
3
11
  ## 3.2.7 (October 3rd, 2014)
4
12
 
5
13
  Add a config option to set a parent controller to Phrasing Engine Controllers.
data/Gemfile CHANGED
@@ -8,10 +8,9 @@ rails_version = ENV["RAILS_VERSION"] || "4.1.4"
8
8
  gem "rails", "~> #{rails_version}"
9
9
 
10
10
  gem 'factory_girl_rails'
11
- gem 'haml-rails'
12
11
  gem 'sqlite3'
13
12
  gem 'rspec-rails'
14
13
  gem 'capybara', '~> 2.3.0'
15
14
  gem 'jasmine-rails'
16
15
  gem 'pry-rails'
17
- gem 'sass', '3.4.0'
16
+ gem 'sass', '3.4.0'
@@ -0,0 +1,153 @@
1
+ //= require editor
2
+
3
+ var Phrasing = {
4
+ Bus : $({}),
5
+ EDIT_MODE_KEY : 'editing-mode'
6
+ };
7
+
8
+ function StatusBubbleWidget(options){
9
+ this.$statusText = options.$statusText;
10
+ this.$statusIndicator = options.$statusIndicator;
11
+ this.$editModeChechbox = options.$editModeChechbox;
12
+ this._init();
13
+ }
14
+
15
+ StatusBubbleWidget.prototype = {
16
+ _init : function(){
17
+ this.$editModeChechbox.on('change', function(){
18
+ if(this.checked){
19
+ Phrasing.Bus.trigger('phrasing:edit-mode:on');
20
+ }else{
21
+ Phrasing.Bus.trigger('phrasing:edit-mode:off');
22
+ }
23
+ });
24
+ },
25
+
26
+ _alterStatus : function(text, color){
27
+ this.$statusText.text(text);
28
+ this.$statusIndicator.css('background-color', color);
29
+ },
30
+
31
+ saving : function(){
32
+ this._alterStatus('Saving', 'orange');
33
+ },
34
+
35
+ saved : function(){
36
+ this._alterStatus('Saved', '#56AE45');
37
+ },
38
+
39
+ error : function(){
40
+ this._alterStatus('Error', 'red');
41
+ }
42
+ };
43
+
44
+ var phrasing_setup = function(){
45
+ var statusBubbleWidget = new StatusBubbleWidget({
46
+ $statusText : $('#phrasing-edit-mode-bubble #phrasing-saved-status-headline p'),
47
+ $statusIndicator : $('#phrasing-saved-status-indicator-circle'),
48
+ $editModeChechbox : $('#edit-mode-onoffswitch')
49
+ });
50
+
51
+ Phrasing.Bus.on('phrasing:edit-mode:on', function(){
52
+ $('.phrasable').addClass("phrasable-on").attr("contenteditable", 'true');
53
+ localStorage.setItem(Phrasing.EDIT_MODE_KEY, 'true');
54
+ });
55
+
56
+ Phrasing.Bus.on('phrasing:edit-mode:off', function(){
57
+ $('.phrasable').removeClass("phrasable-on").attr("contenteditable", "false");
58
+ localStorage.setItem(Phrasing.EDIT_MODE_KEY, "false");
59
+ });
60
+
61
+ // Initialize the editing bubble
62
+ editor.init();
63
+
64
+ // Making sure to send csrf token from layout file.
65
+ $(document).ajaxSend(function(e, xhr, options) {
66
+ var token = $("meta[name='csrf-token']").attr("content");
67
+ xhr.setRequestHeader("X-CSRF-Token", token);
68
+ });
69
+
70
+ // Hash size function
71
+ Object.size = function(obj){
72
+ var size = 0, key;
73
+ for (key in obj) { if (obj.hasOwnProperty(key)) size++; }
74
+ return size;
75
+ };
76
+
77
+ // Trigger AJAX on textchange
78
+ var userTriggeredPhrasingDOMChange = true;
79
+ var timer = {};
80
+ var timer_status = {};
81
+
82
+ $('.phrasable').on('DOMNodeInserted DOMNodeRemoved DOMCharacterDataModified', function(e){
83
+ if (userTriggeredPhrasingDOMChange === false){
84
+ return;
85
+ }
86
+
87
+ statusBubbleWidget.saving();
88
+
89
+ var record = this;
90
+
91
+ clearTimeout(timer[$(record).data("url")]);
92
+ timer_status[$(record).data("url")] = 0;
93
+
94
+ timer[$(record).data("url")] = setTimeout(function(){
95
+ savePhraseViaAjax(record);
96
+ delete timer_status[$(record).data("url")];
97
+ },2500);
98
+
99
+ timer_status[$(record).data("url")] = 1;
100
+ });
101
+
102
+ // AJAX Request
103
+ function savePhraseViaAjax(record){
104
+
105
+ var url = $(record).data("url");
106
+
107
+ var content = record.innerHTML;
108
+
109
+ if(content.length === 0){
110
+ content = "Empty";
111
+ }
112
+
113
+ $.ajax({
114
+ type: "PUT",
115
+ url: url,
116
+ data: { new_value: content },
117
+ success: function(e){
118
+ userTriggeredPhrasingDOMChange = false;
119
+ if(content === "Empty"){
120
+ $('span.phrasable[data-url="'+ url +'"]').html(content);
121
+ }else{
122
+ // Not to lose the cursor on the current contenteditable element
123
+ $('span.phrasable[data-url="'+ url +'"]').not(record).html(content);
124
+ }
125
+ userTriggeredPhrasingDOMChange = true;
126
+
127
+ if (Object.size(timer_status) === 0){
128
+ statusBubbleWidget.saved();
129
+ }
130
+ },
131
+ error: function(e){
132
+ statusBubbleWidget.error();
133
+ }
134
+ });
135
+ }
136
+
137
+ if(localStorage.getItem(Phrasing.EDIT_MODE_KEY) === undefined){
138
+ localStorage.setItem(Phrasing.EDIT_MODE_KEY, 'true');
139
+ }
140
+
141
+ if(localStorage.getItem(Phrasing.EDIT_MODE_KEY) == 'true'){
142
+ $('#edit-mode-onoffswitch').prop('checked', true).change();
143
+ }else{
144
+ $('#edit-mode-onoffswitch').prop('checked', false).change();
145
+ }
146
+
147
+ };
148
+
149
+ $(document).ready(phrasing_setup);
150
+
151
+ $(document).on('page:before-change', function() {
152
+ Phrasing.Bus.off();
153
+ });
@@ -8,14 +8,14 @@
8
8
  overflow: hidden;
9
9
  }*/
10
10
 
11
- .phrasable_on{
11
+ .phrasable.phrasable-on{
12
12
  border-bottom: 1px dashed black;
13
-
13
+
14
14
  a{
15
15
  pointer-events: none;
16
16
  cursor: default;
17
17
  }
18
-
18
+
19
19
  &:focus{
20
20
  outline: none;
21
21
  }
@@ -172,7 +172,7 @@ span.no-overflow {
172
172
  margin-right: 0px;
173
173
  opacity: 0;
174
174
  }
175
-
175
+
176
176
  input{
177
177
  border-left: 2px solid transparent;
178
178
  padding-right: 5px;
@@ -248,4 +248,4 @@ span.no-overflow {
248
248
 
249
249
  .url {
250
250
  -webkit-font-smoothing: antialiased;
251
- }
251
+ }
@@ -8,8 +8,11 @@ class PhrasingPhrasesController < Phrasing.parent_controller.constantize
8
8
 
9
9
  before_filter :authorize_editor
10
10
 
11
- def import_export; end
12
- def help; end
11
+ def import_export
12
+ end
13
+
14
+ def help
15
+ end
13
16
 
14
17
  def index
15
18
  params[:locale] ||= I18n.default_locale
@@ -22,33 +25,29 @@ class PhrasingPhrasesController < Phrasing.parent_controller.constantize
22
25
  end
23
26
 
24
27
  def update
25
- if request.xhr?
26
- xhr_phrase_update
27
- else
28
- phrase_update
29
- end
28
+ request.xhr? ? xhr_phrase_update : phrase_update
30
29
  end
31
30
 
32
31
  def download
33
32
  app_name = Rails.application.class.to_s.split("::").first
34
33
  app_env = Rails.env
35
- filename = "phrasing_phrases_#{app_name}_#{app_env}_#{Time.now.strftime("%Y_%m_%d_%H_%M_%S")}.yml"
34
+ time = Time.now.strftime('%Y_%m_%d_%H_%M_%S')
35
+ filename = "phrasing_phrases_#{app_name}_#{app_env}_#{time}.yml"
36
36
  send_data Phrasing::Serializer.export_yaml, filename: filename
37
37
  end
38
38
 
39
39
  def upload
40
- number_of_changes = Phrasing::Serializer.import_yaml(params["file"].tempfile)
41
- redirect_to phrasing_phrases_path, notice: "YAML file uploaded successfully! Number of phrases changed: #{number_of_changes}."
42
- rescue => e
43
- logger.info "\n#{e.class}\n#{e.message}"
44
- message = if params[:file].nil?
45
- "Please choose a file."
46
- else
47
- "Please upload a valid YAML file."
48
- end
49
-
50
- flash[:alert] = "There was an error processing your upload! #{message}"
51
- render action: 'import_export', status: 400
40
+ number_of_changes = Phrasing::Serializer.import_yaml(params["file"].tempfile)
41
+ redirect_to phrasing_phrases_path, notice: "YAML file uploaded successfully! Number of phrases changed: #{number_of_changes}."
42
+ rescue => e
43
+ message = if params[:file].nil?
44
+ 'Please choose a file.'
45
+ else
46
+ 'Please upload a valid YAML file.'
47
+ end
48
+
49
+ flash[:alert] = "There was an error processing your upload! #{message}"
50
+ render action: 'import_export', status: 400
52
51
  end
53
52
 
54
53
  def destroy
@@ -59,33 +58,30 @@ class PhrasingPhrasesController < Phrasing.parent_controller.constantize
59
58
 
60
59
  private
61
60
 
62
- def authorize_editor
63
- redirect_to root_path unless can_edit_phrases?
64
- end
61
+ def authorize_editor
62
+ redirect_to root_path unless can_edit_phrases?
63
+ end
65
64
 
66
- def xhr_phrase_update
67
- klass, attribute = params[:klass], params[:attribute]
68
-
69
- if Phrasing.is_whitelisted?(klass, attribute)
70
- class_object = klass.classify.constantize
71
- @object = class_object.where(id: params[:id]).first
72
- @object.send("#{attribute}=",params[:new_value])
73
- @object.save!
74
- render json: @object
75
- else
76
- render status: 403, text: "Attribute not whitelisted!"
77
- end
78
-
79
- rescue ActiveRecord::RecordInvalid => e
80
- render status: 403, text: e
81
- end
65
+ def xhr_phrase_update
66
+ klass, attribute = params[:klass], params[:attribute]
67
+
68
+ return render status: 403, text: 'Phrase not whitelisted' unless Phrasing.whitelisted?(klass, attribute)
82
69
 
83
- def phrase_update
84
- phrase = PhrasingPhrase.find(params[:id])
85
- phrase.value = params[:phrasing_phrase][:value]
86
- phrase.save!
70
+ record = klass.classify.constantize.find(params[:id])
87
71
 
88
- redirect_to phrasing_phrases_path, notice: "#{phrase.key} updated!"
72
+ if record.update(attribute => params[:new_value])
73
+ render json: record
74
+ else
75
+ render status: 403, json: record.error.full_messages
89
76
  end
77
+ end
78
+
79
+ def phrase_update
80
+ phrase = PhrasingPhrase.find(params[:id])
81
+ phrase.value = params[:phrasing_phrase][:value]
82
+ phrase.save!
83
+
84
+ redirect_to phrasing_phrases_path, notice: "#{phrase.key} updated!"
85
+ end
90
86
 
91
87
  end
@@ -1,14 +1,13 @@
1
1
  module InlineHelper
2
- # Normal phrase
3
- # phrase("headline", url: www.infinum.co/yabadaba, inverse: true, scope: "models.errors")
4
-
5
- # Data model phrase
6
- # phrase(record, :title, inverse: true, class: phrase-record-title)
7
2
 
3
+ # Normal phrase
4
+ # phrase("headline", url: www.infinum.co/yabadaba, inverse: true, scope: "models.errors")
5
+ # Data model phrase
6
+ # phrase(record, :title, inverse: true, class: phrase-record-title)
8
7
  def phrase(*args)
9
- if args[0].class == String or args[0].class == Symbol
10
- key, options = args[0].to_s, args[1]
11
- phrasing_phrase(key,options || {})
8
+ if args[0].class.in? [String, Symbol]
9
+ key, options = args[0].to_s, (args[1] || {})
10
+ inline(extract_record(key, options), :value, options)
12
11
  else
13
12
  record, attribute, options = args[0], args[1], args[2]
14
13
  inline(record, attribute, options || {})
@@ -17,33 +16,31 @@ module InlineHelper
17
16
 
18
17
  private
19
18
 
20
- def inline(record, attribute, options={})
21
- return uneditable_phrase(record, attribute) unless can_edit_phrases?
19
+ def inline(record, attribute, options = {})
20
+ return uneditable_phrase(record, attribute) unless can_edit_phrases?
22
21
 
23
- klass = 'phrasable phrasable_on'
24
- klass += ' inverse' if options[:inverse]
25
- klass += options[:class] if options[:class]
22
+ klass = 'phrasable'
23
+ klass += ' inverse' if options[:inverse]
24
+ klass += options[:class] if options[:class]
26
25
 
27
- url = phrasing_polymorphic_url(record, attribute)
26
+ url = phrasing_polymorphic_url(record, attribute)
28
27
 
29
- content_tag(:span, { class: klass, contenteditable: true, spellcheck: false, "data-url" => url }) do
30
- (record.send(attribute) || record.try(:key)).to_s.html_safe
31
- end
28
+ content_tag(:span, class: klass, contenteditable: true, spellcheck: false, 'data-url' => url) do
29
+ (record.send(attribute) || record.try(:key)).to_s.html_safe
32
30
  end
31
+ end
33
32
 
34
- def phrasing_phrase(key, options = {})
35
- key = options[:scope] ? "#{options[:scope]}.#{key}" : key
36
- record = PhrasingPhrase.find_phrase(key)
37
- inline(record, :value, options)
38
- end
33
+ def extract_record(key, options = {})
34
+ key = options[:scope] ? "#{options[:scope]}.#{key}" : key
35
+ PhrasingPhrase.find_phrase(key)
36
+ end
39
37
 
40
- def uneditable_phrase(record, attribute)
41
- record_value = record.send(attribute)
42
- record_value.to_s.html_safe
43
- end
38
+ def uneditable_phrase(record, attribute)
39
+ record.public_send(attribute).to_s.html_safe
40
+ end
44
41
 
45
- def phrasing_polymorphic_url(record, attribute)
46
- phrasing_phrase_path(klass: record.class.to_s, id: record.id, attribute: attribute)
47
- end
42
+ def phrasing_polymorphic_url(record, attribute)
43
+ phrasing_phrase_path(klass: record.class.to_s, id: record.id, attribute: attribute)
44
+ end
48
45
 
49
- end
46
+ end
@@ -1,6 +1,6 @@
1
1
  .edit
2
2
  %h2= @phrasing_phrase.key
3
- = link_to "Delete Phrase", phrasing_phrase_path(@phrasing_phrase), class: "btn btn-danger delete-phrase", method: :delete, onclick: "return confirm('Are you sure?');"
3
+ = link_to "Delete Phrase", phrasing_phrase_path(@phrasing_phrase), class: "btn btn-danger delete-phrase", method: :delete, data: { confirm: 'Are you sure?' }
4
4
  = form_for @phrasing_phrase, url: { action: "update" } do |f|
5
5
  = f.text_area :value, rows: 12
6
6
  = f.submit "Update", class: "btn btn-success submit-edit-phrase"
@@ -20,4 +20,4 @@
20
20
  %td.phrasing-version-value= version.value.html_safe
21
21
  %td.phrasing-version-created_at= version.created_at.strftime("%d-%m-%Y %H:%M:%S")
22
22
  %td= link_to "Revert", phrasing_phrase_path(@phrasing_phrase.id, phrasing_phrase: {value: version.value}), class: "btn btn-success", method: :put
23
- %td= link_to "Delete", phrasing_phrase_version_path(version.id), class: "btn btn-danger", method: :delete, onclick: "return confirm('Are you sure?');"
23
+ %td= link_to "Delete", phrasing_phrase_version_path(version.id), class: "btn btn-danger", method: :delete, data: { confirm: 'Are you sure?' }
@@ -3,7 +3,7 @@ require 'phrasing/serializer'
3
3
  require 'phrasing/rails/engine'
4
4
  require 'jquery-rails'
5
5
  require 'jquery-cookie-rails'
6
- require 'haml-rails'
6
+ require 'haml'
7
7
 
8
8
  module Phrasing
9
9
  mattr_accessor :allow_update_on_all_models_and_attributes
@@ -33,7 +33,7 @@ module Phrasing
33
33
  @@whitelist = whitelist
34
34
  end
35
35
 
36
- def self.is_whitelisted?(klass,attribute)
37
- allow_update_on_all_models_and_attributes == true or whitelist.include? "#{klass}.#{attribute}"
36
+ def self.whitelisted?(klass, attribute)
37
+ allow_update_on_all_models_and_attributes == true || whitelist.include?("#{klass}.#{attribute}")
38
38
  end
39
- end
39
+ end
@@ -1,3 +1,3 @@
1
1
  module Phrasing
2
- VERSION = "4.0.0rc3"
3
- end
2
+ VERSION = "4.0.0rc4"
3
+ end
@@ -18,7 +18,7 @@ Gem::Specification.new do |s|
18
18
 
19
19
  s.add_dependency "rails", ">= 3.2.0"
20
20
  s.add_dependency "railties", ">= 3.2"
21
- s.add_dependency "haml-rails"
21
+ s.add_dependency "haml"
22
22
  s.add_dependency "jquery-rails"
23
23
  s.add_dependency "jquery-cookie-rails"
24
24
  s.add_dependency "sass"
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ describe PhrasingPhrasesController do
4
+ describe 'GET #new' do
5
+ it 'renders index template' do
6
+ get :index
7
+ expect(response).to render_template(:index)
8
+ end
9
+
10
+ let(:phrase) { FactoryGirl.create(:phrasing_phrase, value: 'old_value') }
11
+
12
+ it 'updates phrase' do
13
+ expect do
14
+ xhr(:put, :update, klass: 'PhrasingPhrase',
15
+ attribute: 'value',
16
+ id: phrase.id,
17
+ new_value: 'new_value')
18
+ end.to change { phrase.reload.value }.from('old_value').to('new_value')
19
+
20
+ expect(response.code).to eq('200')
21
+ end
22
+
23
+ it 'updates phrase' do
24
+ expect do
25
+ xhr(:put, :update, klass: 'PhrasingPhrase',
26
+ attribute: 'locale',
27
+ id: phrase.id,
28
+ new_value: 'de')
29
+ end.to_not change { phrase.reload.locale }
30
+
31
+ expect(response.code).to eq('403')
32
+ end
33
+ end
34
+ end
@@ -6,6 +6,8 @@
6
6
 
7
7
  <div><%= phrase('test', scope: 'models.errors') %></div>
8
8
 
9
+ <div><%= phrase('test', scope: 'models.errors') %></div>
10
+
9
11
  <div><%= phrase 'test', scope: :site %></div>
10
12
 
11
- <div><%= distance_of_time_in_words(Time.now, Time.now) %></div>
13
+ <div><%= distance_of_time_in_words(Time.now, Time.now) %></div>
@@ -2,7 +2,6 @@
2
2
  require 'spec_helper'
3
3
 
4
4
  describe Phrasing::Serializer do
5
-
6
5
  let(:english_phrases) do
7
6
  PhrasingPhrase.where(locale: :en)
8
7
  end
@@ -12,15 +11,14 @@ describe Phrasing::Serializer do
12
11
  end
13
12
 
14
13
  describe 'flatten_the_hash' do
15
-
16
14
  it 'with simple data' do
17
- hash = { "site.intro" => "Hello", "site.outro" => "KthnxBye", "site.overture" => "The Butler"}
15
+ hash = { "site.intro" => "Hello", "site.outro" => "KthnxBye", "site.overture" => "The Butler" }
18
16
  new_hash = Phrasing::Serializer.flatten_the_hash(hash)
19
17
  expect(new_hash).to eq(hash)
20
18
  end
21
19
 
22
20
  it 'with nested data' do
23
- hash = { "site.text" => {"intro" => "Hello", "outro" => "KthnxBye"}}
21
+ hash = { "site.text" => { "intro" => "Hello", "outro" => "KthnxBye" } }
24
22
  new_hash = Phrasing::Serializer.flatten_the_hash(hash)
25
23
 
26
24
  predicted_new_hash = { "site.text.intro" => "Hello", "site.text.outro" => "KthnxBye" }
@@ -28,17 +26,24 @@ describe Phrasing::Serializer do
28
26
  end
29
27
 
30
28
  it 'with deeply nested data' do
31
- hash = { "site" => {"text" => {"intro" => "Hello", "outro" => "KthnxBye", "overture" => {"intro" => "Overture intro", "outro" => "Overture outro"}}}}
29
+ hash = { "site" => { "text" => { "intro" => "Hello",
30
+ "outro" => "KthnxBye",
31
+ "overture" => { "intro" => "Overture intro",
32
+ "outro" => "Overture outro" }
33
+ }
34
+ }
35
+ }
32
36
  new_hash = Phrasing::Serializer.flatten_the_hash(hash)
33
37
 
34
- predicted_new_hash = { "site.text.intro" => "Hello", "site.text.outro" => "KthnxBye", "site.text.overture.intro" => "Overture intro", "site.text.overture.outro" => "Overture outro"}
38
+ predicted_new_hash = { "site.text.intro" => "Hello",
39
+ "site.text.outro" => "KthnxBye",
40
+ "site.text.overture.intro" => "Overture intro",
41
+ "site.text.overture.outro" => "Overture outro" }
35
42
  expect(new_hash).to eq(predicted_new_hash)
36
43
  end
37
-
38
44
  end
39
45
 
40
46
  context 'import_yaml' do
41
-
42
47
  it 'simply formatted phrases' do
43
48
  yaml = <<-YAML
44
49
  en:
@@ -84,7 +89,6 @@ describe Phrasing::Serializer do
84
89
  expect(english_phrases.where(key: "site.text.overture.outro").first.value).to eq("Overture outro")
85
90
  end
86
91
 
87
-
88
92
  it 'overrides old values' do
89
93
  FactoryGirl.create(:phrasing_phrase, key: "site.intro", value: "Go Home")
90
94
  FactoryGirl.create(:phrasing_phrase, key: "site.outro", value: "Kthnx Bye")
@@ -104,10 +108,8 @@ describe Phrasing::Serializer do
104
108
 
105
109
  expect(number_of_changes).to eq(1)
106
110
  end
107
-
108
111
  end
109
112
 
110
-
111
113
  context 'imports and exports' do
112
114
  it 'without changing, should return 0 number of changes' do
113
115
  FactoryGirl.create(:phrasing_phrase, key: "site.intro", value: "Go Home")
@@ -126,7 +128,6 @@ describe Phrasing::Serializer do
126
128
  end
127
129
  end
128
130
 
129
-
130
131
  context 'export_yaml' do
131
132
  it 'flattened phrases' do
132
133
  FactoryGirl.create(:phrasing_phrase, key: "site.intro", value: "Go Home")
@@ -153,13 +154,5 @@ describe Phrasing::Serializer do
153
154
  expect(yaml).to match(/en:\s*\n\s*site.intro:\sHello/)
154
155
  expect(yaml).to match(/fr:\s*\n\s*site.intro:\sBonjour/)
155
156
  end
156
-
157
157
  end
158
-
159
-
160
-
161
158
  end
162
-
163
-
164
-
165
-
@@ -10,4 +10,5 @@ Dir["#{File.dirname(__FILE__)}/factories/**/*.rb"].each { |f| require f }
10
10
  RSpec.configure do |config|
11
11
  config.mock_with :rspec
12
12
  config.use_transactional_fixtures = true
13
+ config.infer_spec_type_from_file_location!
13
14
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: phrasing
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.0rc3
4
+ version: 4.0.0rc4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tomislav Car
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-10-17 00:00:00.000000000 Z
12
+ date: 2015-05-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -40,7 +40,7 @@ dependencies:
40
40
  - !ruby/object:Gem::Version
41
41
  version: '3.2'
42
42
  - !ruby/object:Gem::Dependency
43
- name: haml-rails
43
+ name: haml
44
44
  requirement: !ruby/object:Gem::Requirement
45
45
  requirements:
46
46
  - - ">="
@@ -118,7 +118,7 @@ files:
118
118
  - app/assets/fonts/icomoon.woff
119
119
  - app/assets/images/phrasing_icon_edit_all.png
120
120
  - app/assets/javascripts/editor.js
121
- - app/assets/javascripts/phrasing.js.erb
121
+ - app/assets/javascripts/phrasing.js
122
122
  - app/assets/javascripts/phrasing_engine.js
123
123
  - app/assets/stylesheets/phrasing.css.scss
124
124
  - app/assets/stylesheets/phrasing_edit_mode_bubble.css.scss
@@ -149,6 +149,7 @@ files:
149
149
  - lib/phrasing/serializer.rb
150
150
  - lib/phrasing/version.rb
151
151
  - phrasing.gemspec
152
+ - spec/controllers/phrasing_phrases_controller.rb
152
153
  - spec/dummy/Rakefile
153
154
  - spec/dummy/app/assets/javascripts/application.js
154
155
  - spec/dummy/app/assets/stylesheets/application.css
@@ -1,127 +0,0 @@
1
- //= require editor
2
-
3
- function StatusBubble(){
4
- var $headline = $('#phrasing-edit-mode-bubble #phrasing-saved-status-headline p');
5
- var $circle = $('#phrasing-saved-status-indicator-circle');
6
-
7
- var alterStatus = function(text, color){
8
- $headline.text(text);
9
- $circle.css('background-color', color);
10
- }
11
-
12
- this.saving = function(){
13
- alterStatus('Saving', 'orange');
14
- }
15
-
16
- this.saved = function(){
17
- alterStatus('Saved', '#56AE45');
18
- }
19
-
20
- this.error = function(){
21
- alterStatus('Error', 'red');
22
- }
23
- }
24
-
25
- var phrasing_setup = function(){
26
- var status = new StatusBubble();
27
-
28
- // Initialize the editing bubble
29
- editor.init();
30
-
31
- // Making sure to send csrf token from layout file.
32
- $(document).ajaxSend(function(e, xhr, options) {
33
- var token = $("meta[name='csrf-token']").attr("content");
34
- xhr.setRequestHeader("X-CSRF-Token", token);
35
- });
36
-
37
- // Hash size function
38
- Object.size = function(obj){
39
- var size = 0, key;
40
- for (key in obj) { if (obj.hasOwnProperty(key)) size++; }
41
- return size;
42
- };
43
-
44
- // Trigger AJAX on textchange
45
- var trigger_binded_events_for_phrasable_class = 1;
46
- var timer = {}
47
- var timer_status = {}
48
-
49
- $('.phrasable').on('DOMNodeInserted DOMNodeRemoved DOMCharacterDataModified', function(e){
50
- status.saving();
51
-
52
- if (trigger_binded_events_for_phrasable_class == 1){
53
-
54
- var record = this;
55
-
56
- clearTimeout(timer[$(record).data("url")]);
57
- timer_status[$(record).data("url")] = 0;
58
-
59
- timer[$(record).data("url")] = setTimeout(function(){
60
- savePhraseViaAjax(record);
61
- delete timer_status[$(record).data("url")]
62
- },2500)
63
- timer_status[$(record).data("url")] = 1;
64
- }
65
-
66
- });
67
-
68
- // AJAX Request
69
- function savePhraseViaAjax(record){
70
-
71
- var url = $(record).data("url");
72
-
73
- var content = record.innerHTML;
74
-
75
- if(content.length == 0){
76
- content = "Empty"
77
- }
78
-
79
- $.ajax({
80
- type: "PUT",
81
- url: url,
82
- data: { new_value: content },
83
- success: function(e){
84
- trigger_binded_events_for_phrasable_class = 0;
85
- if(content === "Empty"){
86
- $('span.phrasable[data-url="'+ url +'"]').html(content)
87
- }else{
88
- // Not to lose the cursor on the current contenteditable element
89
- $('span.phrasable[data-url="'+ url +'"]').not(record).html(content)
90
- }
91
- trigger_binded_events_for_phrasable_class = 1;
92
-
93
- if (Object.size(timer_status) == 0){
94
- status.saved();
95
- }
96
- },
97
- error: function(e){
98
- status.error();
99
- }
100
- });
101
- }
102
-
103
- // Edit Mode On/Off Button
104
- $('#edit-mode-onoffswitch').on('change', function(){
105
- if(this.checked){
106
- $('.phrasable').addClass("phrasable_on").attr("contenteditable", "true");
107
- $.cookie("editing_mode", "true");
108
- }
109
- else{
110
- $('.phrasable').removeClass("phrasable_on").attr("contenteditable", "false");
111
- $.cookie("editing_mode", "false");
112
- }
113
- });
114
-
115
- if($.cookie("editing_mode") === null){
116
- $.cookie("editing_mode", "true");
117
- $('#edit-mode-onoffswitch').prop('checked', true).change();
118
- }
119
- else if($.cookie("editing_mode") == "true"){
120
- $('#edit-mode-onoffswitch').prop('checked', true).change();
121
- }else{
122
- $('#edit-mode-onoffswitch').prop('checked', false).change();
123
- }
124
-
125
- };
126
-
127
- $(document).ready(phrasing_setup)