smalruby-editor 0.1.5-x86-mingw32 → 0.1.6-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of smalruby-editor might be problematic. Click here for more details.

Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/.rubocop.yml +8 -0
  4. data/README.rdoc +3 -0
  5. data/app/assets/javascripts/application.js +0 -1
  6. data/app/assets/javascripts/models/source_code.js.coffee +5 -2
  7. data/app/assets/javascripts/smalruby.js.coffee +18 -11
  8. data/app/assets/javascripts/views/main_menu_view.js.coffee +139 -81
  9. data/app/controllers/source_codes_controller.rb +7 -0
  10. data/app/models/concerns/ruby_to_block.rb +391 -0
  11. data/app/models/source_code.rb +3 -2
  12. data/app/views/editor/demo.html.erb +1 -1
  13. data/app/views/editor/index.html.haml +2 -2
  14. data/config/routes.rb +1 -0
  15. data/{app/assets/demos → demos}/default.xml +0 -0
  16. data/{app/assets/demos → demos}/rgb_led_anode.xml +82 -82
  17. data/lib/smalruby_editor/version.rb +3 -3
  18. data/lib/tasks/release.rake +0 -4
  19. data/public/assets/{application-0047adbc0fb7a529ef7a41b5e0e7d097.js → application-8bfffad1222d4e198f3c7ccc1cbd774f.js} +179 -144
  20. data/public/assets/{application-0047adbc0fb7a529ef7a41b5e0e7d097.js.gz → application-8bfffad1222d4e198f3c7ccc1cbd774f.js.gz} +0 -0
  21. data/public/assets/manifest-332a5a1668194028b55103e0ea45c054.json +1 -1
  22. data/smalruby-editor.gemspec +0 -6
  23. data/spec/acceptance/base.feature +119 -0
  24. data/spec/acceptance/block_mode/translate.feature +14 -0
  25. data/spec/acceptance/ruby_mode/translate.feature +65 -0
  26. data/spec/acceptance/standalone/run.feature +14 -1
  27. data/spec/controllers/source_codes_controller_spec.rb +22 -0
  28. data/{public/assets/default-5d1886100d7c8961e9962bbc4bb0c714.xml → spec/fixtures/files/01.rb.xml} +0 -0
  29. data/spec/models/concerns/ruby_to_block_spec.rb +329 -0
  30. data/spec/steps/base_steps.rb +230 -0
  31. data/spec/steps/block_mode_steps.rb +9 -1
  32. data/spec/steps/fix_turnip.rb +28 -0
  33. data/spec/steps/text_editor_steps.rb +52 -193
  34. metadata +19 -97
  35. data/app/assets/javascripts/ruby_mode.js.coffee.erb +0 -12
  36. data/public/assets/rgb_led_anode-91225bef2a8b97f1cefee862a0619b91.xml +0 -83
  37. data/spec/acceptance/ruby_mode/base.feature +0 -33
  38. data/spec/steps/ace_steps.rb +0 -77
@@ -0,0 +1,230 @@
1
+ # encoding: utf-8
2
+
3
+ step ':name にアクセスする' do |name|
4
+ visit NAME_INFO[name][:path]
5
+
6
+ if poltergeist?
7
+ page.execute_script('window.confirmResult = true')
8
+ page.execute_script(<<-JS)
9
+ if (window.confirmMsg == undefined) {
10
+ window.confirmMsg = null;
11
+ window.confirm = function(msg) {
12
+ window.confirmMsg = msg;
13
+ return window.confirmResult;
14
+ }
15
+ }
16
+ JS
17
+ end
18
+ end
19
+
20
+ step ':name 画面を表示する' do |name|
21
+ send ':name にアクセスする', name
22
+ end
23
+
24
+ step ':name が表示されていること' do |name|
25
+ expect(page).to have_selector(NAME_INFO[name][:selector])
26
+ end
27
+
28
+ step ':name にタブを切り替える' do |name|
29
+ page.execute_script(<<-JS)
30
+ $('#tabs a[href=\"#{NAME_INFO[name][:selector]}\"]').click()
31
+ JS
32
+ end
33
+
34
+ step ':name タブを表示する' do |name|
35
+ step '"エディタ" 画面を表示する'
36
+ step %("#{name}タブ" にタブを切り替える)
37
+ end
38
+
39
+ step 'プログラムの名前に :filename を指定する' do |filename|
40
+ fill_in('filename', with: filename)
41
+ end
42
+
43
+ step 'サブメニューの :name をクリックする' do |name|
44
+ # HACK: 以下では期待通りの動作にならなかったのでjQueryで無理やり実現した
45
+ # click_on('submenu-button')
46
+ # click_on(NAME_INFO[name][:id])
47
+ page.execute_script("$('#{NAME_INFO[name][:selector]}').click()")
48
+ end
49
+
50
+ step ':name をクリックする' do |name|
51
+ click_on(NAME_INFO[name][:id])
52
+ end
53
+
54
+ step 'ダウンロードが完了するまで待つ' do
55
+ start_time = Time.now
56
+ if poltergeist?
57
+ until page.response_headers['Content-Disposition'] ||
58
+ (start_time + 5.seconds) < Time.now
59
+ sleep(1)
60
+ end
61
+ elsif selenium?
62
+ sleep(1) until downloads_dir.exist? || (start_time + 5.seconds) < Time.now
63
+ end
64
+ end
65
+
66
+ step ':filename をダウンロードすること' do |filename|
67
+ step 'ダウンロードが完了するまで待つ'
68
+ if poltergeist?
69
+ expect(page.response_headers['Content-Disposition'])
70
+ .to eq("attachment; filename=\"#{filename}\"")
71
+ expect(page.response_headers['Content-Type'])
72
+ .to eq('text/plain; charset=utf-8')
73
+ elsif selenium?
74
+ expect(downloads_dir.join(filename)).to be_exist
75
+ end
76
+ end
77
+
78
+ step 'ダウンロードしないこと' do
79
+ if poltergeist?
80
+ expect(page.response_headers['Content-Disposition']).to be_nil
81
+ elsif selenium?
82
+ expect(downloads_dir).not_to be_exist
83
+ end
84
+ end
85
+
86
+ step ':name にフォーカスを移す' do |name|
87
+ page.execute_script(<<-JS)
88
+ $('#{NAME_INFO[name][:selector]}').focus()
89
+ JS
90
+ end
91
+
92
+ step ':name にフォーカスがあること' do |name|
93
+ # HACK: 現在のPhantomJSでは$(':focus')は動作しない
94
+ # https://github.com/netzpirat/guard-jasmine/issues/48
95
+ expect(page.evaluate_script(<<-JS)).to be_true
96
+ $('#{NAME_INFO[name][:selector]}').get(0) == document.activeElement
97
+ JS
98
+ end
99
+
100
+ step ':filename をロードする' do |filename|
101
+ step '"ロードボタン" にフォーカスを移す'
102
+
103
+ # HACK: input#load-file[type="file"]は非表示要素であるため、.show()し
104
+ # ないと見つけられずattach_fileが失敗する
105
+ page.execute_script("$('#load-file').show()")
106
+
107
+ path = Pathname(fixture_path).join(filename).to_s
108
+ path.gsub!(File::SEPARATOR, File::ALT_SEPARATOR) if windows?
109
+ attach_file('load-file', path)
110
+ end
111
+
112
+ step 'JavaScriptによるリクエストが終わるまで待つ' do
113
+ start_time = Time.now
114
+ until page.evaluate_script('jQuery.isReady && jQuery.active == 0') ||
115
+ (start_time + 5.seconds) < Time.now
116
+ sleep 1
117
+ end
118
+ end
119
+
120
+ step ':name は :value であること' do |name, value|
121
+ expect(page.evaluate_script(<<-JS)).to eq(value)
122
+ $('#{NAME_INFO[name][:selector]}').val()
123
+ JS
124
+ end
125
+
126
+ step ':name に :message を含むこと' do |name, message|
127
+ expect(page.find(NAME_INFO[name][:selector])).to have_content(message)
128
+ end
129
+
130
+ step ':name に :message を含まないこと' do |name, message|
131
+ expect(page.find(NAME_INFO[name][:selector])).to have_no_content(message)
132
+ end
133
+
134
+ step 'ページをリロードする' do
135
+ begin
136
+ if poltergeist?
137
+ # HACK: Poltergeistではwindow.onbeforeunload によって表示されたダ
138
+ # イアログを消せないためタイムアウト時間を1秒にすることで回避し
139
+ # ている。
140
+ page.driver.timeout = 2
141
+ begin
142
+ step '"エディタ" 画面を表示する'
143
+ ensure
144
+ page.driver.timeout = 120
145
+ end
146
+ else
147
+ step '"エディタ" 画面を表示する'
148
+ end
149
+ rescue Capybara::Poltergeist::TimeoutError => e
150
+ Rails.logger.debug("#{e.class.name}: #{e.message}")
151
+ end
152
+ end
153
+
154
+ step '警告ダイアログの :name ボタンをクリックする' do |name|
155
+ case name
156
+ when 'dismiss'
157
+ page.driver.browser.switch_to.alert.dismiss if selenium?
158
+ else
159
+ page.driver.browser.switch_to.alert.accept if selenium?
160
+ end
161
+ end
162
+
163
+ step '確認ダイアログをキャンセルするようにしておく' do
164
+ page.execute_script('window.confirmResult = false') if poltergeist?
165
+ end
166
+
167
+ step '確認メッセージ :message を表示すること' do |message|
168
+ message.gsub!('\n', "\n")
169
+ if poltergeist?
170
+ actual = page.evaluate_script('window.confirmMsg')
171
+ page.execute_script('window.confirmMsg = null')
172
+ expect(actual).to eq(message)
173
+ elsif selenium?
174
+ expect(page.driver.browser.switch_to.alert.text).to eq(message)
175
+ page.driver.browser.switch_to.alert.dismiss
176
+ end
177
+ end
178
+
179
+ step '確認メッセージを表示しないこと' do
180
+ if poltergeist?
181
+ actual = page.evaluate_script('window.confirmMsg')
182
+ page.execute_script('window.confirmMsg = null')
183
+ expect(actual).to be_nil
184
+ elsif selenium?
185
+ expect {
186
+ page.driver.browser.switch_to.alert
187
+ }.to raise_exception(Selenium::WebDriver::Error::NoAlertPresentError)
188
+ end
189
+ end
190
+
191
+ step '実際にはファイルをロードしないようにしておく' do
192
+ if selenium?
193
+ page.execute_script("$('#load-button').off('click')")
194
+ page.execute_script(<<-JS)
195
+ $('#load-button').click(function(e) {
196
+ e.preventDefault();
197
+ if (changed) {
198
+ confirm('まだセーブしていないのでロードするとプログラムが消えてしまうよ!それでもロードしますか?');
199
+ }
200
+ })
201
+ JS
202
+ end
203
+ end
204
+
205
+ step '実際にはファイルをダウンロードしないようにしておく' do
206
+ if poltergeist?
207
+ page.execute_script(<<-JS)
208
+ $('#download-link').click(function(e) {
209
+ e.preventDefault();
210
+ return false;
211
+ })
212
+ JS
213
+ end
214
+ end
215
+
216
+ step 'ホームディレクトリに :program という内容の :filename が存在する' do |program, filename|
217
+ File.open(Pathname("~/#{filename}").expand_path, 'w') do |f|
218
+ f.write(program)
219
+ end
220
+ end
221
+
222
+ step 'ホームディレクトリに :filename が存在すること' do |filename|
223
+ path = Pathname("~/#{filename}").expand_path
224
+ expect(path).to be_exist
225
+ end
226
+
227
+ step 'ホームディレクトリの :filename の内容が :program であること' do |filename, program|
228
+ path = Pathname("~/#{filename}").expand_path
229
+ expect(path.read).to eq(program)
230
+ end
@@ -31,7 +31,7 @@ step 'すべてのブロックをクリアする' do
31
31
  end
32
32
 
33
33
  step 'ブロックからソースコードを生成する' do
34
- step '"ブロックタブ" にタブを切り替える'
34
+ page.execute_script('window.blockMode = true')
35
35
  step '"Rubyタブ" にタブを切り替える'
36
36
  end
37
37
 
@@ -49,3 +49,11 @@ step '次のキャラクターを追加する:' do |table|
49
49
  JS
50
50
  end
51
51
  end
52
+
53
+ step '次のXMLと同等のブロックが配置されていること:' do |xml|
54
+ expect(page.evaluate_script('Smalruby.dumpXml()')).to eq(xml)
55
+ end
56
+
57
+ step 'ブロックが配置されていないこと' do
58
+ send '次のXMLと同等のブロックが配置されていること:', '<xml></xml>'
59
+ end
@@ -33,3 +33,31 @@ class Turnip::Builder
33
33
  end
34
34
  end
35
35
  end
36
+
37
+ # HACK: RSpecのフォーマットがdocumentationの場合にTurnipの実行経過を出
38
+ # 力する。Cucumberのようにしたいがstepの定義場所は取得できないため、
39
+ # featureの行番号を表示している。
40
+ module Turnip::RSpec::Execute
41
+ def run_step_with_progress(feature_file, step)
42
+ require 'rspec/core/formatters/documentation_formatter'
43
+ if formatter.is_a?(RSpec::Core::Formatters::DocumentationFormatter)
44
+ output.print " #{step.description} # #{feature_file.sub(/^#{Regexp.quote(Rails.root.to_s.sub(/^(\S)/) { |s| s.downcase } + '/')}/, '')}:#{step.line}"
45
+ s = Time.now
46
+ run_step_without_progress(feature_file, step)
47
+ elapsed = Time.now - s
48
+ output.puts " (#{elapsed} sec)"
49
+ else
50
+ run_step_without_progress(feature_file, step)
51
+ end
52
+ end
53
+ alias_method :run_step_without_progress, :run_step
54
+ alias_method :run_step, :run_step_with_progress
55
+
56
+ def formatter
57
+ @formatter ||= RSpec.configuration.formatters.first
58
+ end
59
+
60
+ def output
61
+ @output ||= formatter.output
62
+ end
63
+ end
@@ -1,218 +1,77 @@
1
1
  # encoding: utf-8
2
2
 
3
- step ':name にアクセスする' do |name|
4
- visit NAME_INFO[name][:path]
3
+ text_editor = 'テキストエディタ'
5
4
 
6
- if poltergeist?
7
- page.execute_script('window.confirmResult = true')
8
- page.execute_script(<<-JS)
9
- if (window.confirmMsg == undefined) {
10
- window.confirmMsg = null;
11
- window.confirm = function(msg) {
12
- window.confirmMsg = msg;
13
- return window.confirmResult;
14
- }
15
- }
16
- JS
17
- end
18
- end
19
-
20
- step ':name 画面を表示する' do |name|
21
- send ':name にアクセスする', name
22
- end
23
-
24
- step ':name が表示されていること' do |name|
25
- expect(page).to have_selector(NAME_INFO[name][:selector])
26
- end
27
-
28
- step ':name にタブを切り替える' do |name|
29
- page.execute_script(<<-JS)
30
- $('#tabs a[href=\"#{NAME_INFO[name][:selector]}\"]').tab('show')
5
+ step 'テキストエディタにフォーカスがあること' do
6
+ expect(page.evaluate_script(<<-JS)).to be_true
7
+ ace.edit('#{NAME_INFO[text_editor][:id]}').isFocused()
31
8
  JS
32
9
  end
33
10
 
34
- step ':name タブを表示する' do |name|
35
- step '"エディタ" 画面を表示する'
36
- step %("#{name}タブ" にタブを切り替える)
37
- end
38
-
39
- step 'プログラムの名前に :filename を指定する' do |filename|
40
- fill_in('filename', with: filename)
41
- end
42
-
43
- step 'サブメニューの :name をクリックする' do |name|
44
- # HACK: 以下では期待通りの動作にならなかったのでjQueryで無理やり実現した
45
- # click_on('submenu-button')
46
- # click_on(NAME_INFO[name][:id])
47
- page.execute_script("$('#{NAME_INFO[name][:selector]}').click()")
11
+ step 'テキストエディタの :row 行目の :column 文字目にカーソルがあること' do |row, column|
12
+ get_cursor_position_js =
13
+ "ace.edit('#{NAME_INFO[text_editor][:id]}').getCursorPosition()"
14
+ expect(page.evaluate_script("#{get_cursor_position_js}.row")).to eq(row.to_i)
15
+ expect(page.evaluate_script("#{get_cursor_position_js}.column"))
16
+ .to eq(column.to_i)
48
17
  end
49
18
 
50
- step ':name をクリックする' do |name|
51
- click_on(NAME_INFO[name][:id])
19
+ step 'テキストエディタに :program を入力済みである' do |program|
20
+ send 'テキストエディタにプログラムを入力済みである:', program
52
21
  end
53
22
 
54
- step 'ダウンロードが完了するまで待つ' do
55
- start_time = Time.now
56
- if poltergeist?
57
- until page.response_headers['Content-Disposition'] ||
58
- (start_time + 5.seconds) < Time.now
59
- sleep(1)
60
- end
61
- elsif selenium?
62
- sleep(1) until downloads_dir.exist? || (start_time + 5.seconds) < Time.now
63
- end
64
- end
65
-
66
- step ':filename をダウンロードすること' do |filename|
67
- step 'ダウンロードが完了するまで待つ'
68
- if poltergeist?
69
- expect(page.response_headers['Content-Disposition'])
70
- .to eq("attachment; filename=\"#{filename}\"")
71
- expect(page.response_headers['Content-Type'])
72
- .to eq('text/plain; charset=utf-8')
73
- elsif selenium?
74
- expect(downloads_dir.join(filename)).to be_exist
75
- end
76
- end
77
-
78
- step 'ダウンロードしないこと' do
79
- if poltergeist?
80
- expect(page.response_headers['Content-Disposition']).to be_nil
81
- elsif selenium?
82
- expect(downloads_dir).not_to be_exist
83
- end
84
- end
85
-
86
- step ':name にフォーカスを移す' do |name|
23
+ step 'テキストエディタにプログラムを入力済みである:' do |program|
87
24
  page.execute_script(<<-JS)
88
- $('#{NAME_INFO[name][:selector]}').focus()
25
+ ace.edit('#{NAME_INFO[text_editor][:id]}')
26
+ .getSession()
27
+ .getDocument()
28
+ .setValue('#{program.gsub(/'/, "\\\\'").gsub(/\r?\n/, '\n')}')
89
29
  JS
90
30
  end
91
31
 
92
- step ':name にフォーカスがあること' do |name|
93
- # HACK: 現在のPhantomJSでは$(':focus')は動作しない
94
- # https://github.com/netzpirat/guard-jasmine/issues/48
95
- expect(page.evaluate_script(<<-JS)).to be_true
96
- $('#{NAME_INFO[name][:selector]}').get(0) == document.activeElement
32
+ step 'テキストエディタに :filename を読み込むこと' do |filename|
33
+ js = <<-JS
34
+ ace.edit('#{NAME_INFO[text_editor][:id]}')
35
+ .getSession()
36
+ .getDocument()
37
+ .getValue()
97
38
  JS
39
+ path = Pathname(fixture_path).join(filename)
40
+ expect(page.evaluate_script(js)).to eq(path.read)
98
41
  end
99
42
 
100
- step ':filename をロードする' do |filename|
101
- step '"ロードボタン" にフォーカスを移す'
102
-
103
- # HACK: input#load-file[type="file"]は非表示要素であるため、.show()
104
- # ないと見つけられずattach_fileが失敗する
105
- page.execute_script("$('#load-file').show()")
106
-
107
- path = Pathname(fixture_path).join(filename).to_s
108
- path.gsub!(File::SEPARATOR, File::ALT_SEPARATOR) if windows?
109
- attach_file('load-file', path)
110
- end
111
-
112
- step 'JavaScriptによるリクエストが終わるまで待つ' do
113
- start_time = Time.now
114
- until page.evaluate_script('jQuery.isReady && jQuery.active == 0') ||
115
- (start_time + 5.seconds) < Time.now
116
- sleep 1
117
- end
118
- end
119
-
120
- step ':name は :value であること' do |name, value|
121
- expect(page.evaluate_script(<<-JS)).to eq(value)
122
- $('#{NAME_INFO[name][:selector]}').val()
43
+ step 'テキストエディタのプログラムは以下であること:' do |program|
44
+ expect(page.evaluate_script(<<-JS)).to eq(program)
45
+ ace.edit('#{NAME_INFO[text_editor][:id]}')
46
+ .getSession()
47
+ .getDocument()
48
+ .getValue()
123
49
  JS
124
50
  end
125
51
 
126
- step ':name に :message を含むこと' do |name, message|
127
- expect(page.find(NAME_INFO[name][:selector])).to have_content(message)
128
- end
129
-
130
- step ':name に :message を含まないこと' do |name, message|
131
- expect(page.find(NAME_INFO[name][:selector])).to have_no_content(message)
132
- end
133
-
134
- step 'ページをリロードする' do
135
- begin
136
- step '"エディタ" 画面を表示する'
137
- rescue Capybara::Poltergeist::TimeoutError => e
138
- Rails.logger.debug("#{e.class.name}: #{e.message}")
139
- end
140
- end
141
-
142
- step '警告ダイアログの :name ボタンをクリックする' do |name|
143
- case name
144
- when 'dismiss'
145
- page.driver.browser.switch_to.alert.dismiss if selenium?
146
- else
147
- page.driver.browser.switch_to.alert.accept if selenium?
148
- end
149
- end
150
-
151
- step '確認ダイアログをキャンセルするようにしておく' do
152
- page.execute_script('window.confirmResult = false') if poltergeist?
153
- end
154
-
155
- step '確認メッセージ :message を表示すること' do |message|
156
- message.gsub!('\n', "\n")
157
- if poltergeist?
158
- actual = page.evaluate_script('window.confirmMsg')
159
- page.execute_script('window.confirmMsg = null')
160
- expect(actual).to eq(message)
161
- elsif selenium?
162
- expect(page.driver.browser.switch_to.alert.text).to eq(message)
163
- page.driver.browser.switch_to.alert.dismiss
164
- end
165
- end
166
-
167
- step '確認メッセージを表示しないこと' do
168
- if poltergeist?
169
- actual = page.evaluate_script('window.confirmMsg')
170
- page.execute_script('window.confirmMsg = null')
171
- expect(actual).to be_nil
172
- elsif selenium?
173
- expect {
174
- page.driver.browser.switch_to.alert
175
- }.to raise_exception(Selenium::WebDriver::Error::NoAlertPresentError)
176
- end
177
- end
178
-
179
- step '実際にはファイルをロードしないようにしておく' do
180
- if selenium?
181
- page.execute_script("$('#load-button').off('click')")
182
- page.execute_script(<<-JS)
183
- $('#load-button').click(function(e) {
184
- e.preventDefault();
185
- if (changed) {
186
- confirm('まだセーブしていないのでロードするとプログラムが消えてしまうよ!それでもロードしますか?');
187
- }
188
- })
189
- JS
190
- end
191
- end
192
-
193
- step '実際にはファイルをダウンロードしないようにしておく' do
194
- if poltergeist?
195
- page.execute_script(<<-JS)
196
- $('#download-link').click(function(e) {
197
- e.preventDefault();
198
- return false;
199
- })
200
- JS
201
- end
202
- end
203
-
204
- step 'ホームディレクトリに :program という内容の :filename が存在する' do |program, filename|
205
- File.open(Pathname("~/#{filename}").expand_path, 'w') do |f|
206
- f.write(program)
207
- end
52
+ step 'テキストエディタのプログラムは以下を含むこと:' do |program|
53
+ expect(page.evaluate_script(<<-JS)).to include(program)
54
+ ace.edit('#{NAME_INFO[text_editor][:id]}')
55
+ .getSession()
56
+ .getDocument()
57
+ .getValue()
58
+ JS
208
59
  end
209
60
 
210
- step 'ホームディレクトリに :filename が存在すること' do |filename|
211
- path = Pathname("~/#{filename}").expand_path
212
- expect(path).to be_exist
61
+ step 'テキストエディタのプログラムは以下を含まないこと:' do |program|
62
+ expect(page.evaluate_script(<<-JS)).not_to include(program)
63
+ ace.edit('#{NAME_INFO[text_editor][:id]}')
64
+ .getSession()
65
+ .getDocument()
66
+ .getValue()
67
+ JS
213
68
  end
214
69
 
215
- step 'ホームディレクトリの :filename の内容が :program であること' do |filename, program|
216
- path = Pathname("~/#{filename}").expand_path
217
- expect(path.read).to eq(program)
70
+ step 'テキストエディタのプログラムは :program であること' do |program|
71
+ expect(page.evaluate_script(<<-JS)).to eq(program)
72
+ ace.edit('#{NAME_INFO[text_editor][:id]}')
73
+ .getSession()
74
+ .getDocument()
75
+ .getValue()
76
+ JS
218
77
  end