smalruby-editor 0.0.5 → 0.0.6
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rspec +2 -1
- data/.rubocop.yml +18 -0
- data/.travis.yml +24 -23
- data/LEGAL +13 -0
- data/README.rdoc +1 -0
- data/Rakefile +3 -0
- data/app/assets/javascripts/application.js +1 -1
- data/app/assets/javascripts/editor.js.coffee +60 -15
- data/app/assets/stylesheets/application.css +1 -2
- data/app/assets/stylesheets/flatstrap-custom.css.scss +2 -0
- data/app/controllers/editor_controller.rb +0 -24
- data/app/controllers/source_codes_controller.rb +67 -0
- data/app/models/source_code.rb +42 -0
- data/app/views/editor/index.html.erb +5 -3
- data/bin/smalruby-editor +11 -0
- data/config/application.rb +8 -20
- data/config/boot.rb +3 -0
- data/config/environments/development.rb +2 -1
- data/config/environments/production.rb +12 -6
- data/config/environments/standalone.rb +3 -2
- data/config/environments/test.rb +14 -4
- data/config/initializers/backtrace_silencers.rb +4 -2
- data/config/initializers/session_store.rb +2 -1
- data/config/initializers/wrap_parameters.rb +2 -1
- data/config/routes.rb +10 -6
- data/config/unicorn.rb +7 -6
- data/db/migrate/20131216121603_create_source_codes.rb +9 -0
- data/db/migrate/20131219045113_add_filename_to_source_code.rb +5 -0
- data/db/schema.rb +8 -1
- data/lib/smalruby_editor.rb +29 -15
- data/lib/smalruby_editor/version.rb +1 -1
- data/lib/tasks/rspec.rake +2 -2
- data/lib/tasks/rubocop.rake +3 -0
- data/public/fonts/FontAwesome.otf +0 -0
- data/public/fonts/fontawesome-webfont.eot +0 -0
- data/public/fonts/fontawesome-webfont.ttf +0 -0
- data/public/fonts/fontawesome-webfont.woff +0 -0
- data/smalruby-editor.gemspec +3 -3
- data/spec/acceptance/readme.md +3 -0
- data/spec/acceptance/text_editor/base.feature +24 -0
- data/spec/acceptance/text_editor/check.feature +20 -0
- data/spec/acceptance/text_editor/load.feature +74 -0
- data/spec/acceptance/text_editor/save.feature +31 -0
- data/spec/controllers/editor_controller_spec.rb +2 -63
- data/spec/controllers/source_codes_controller_spec.rb +296 -0
- data/spec/models/source_code_spec.rb +44 -0
- data/spec/spec_helper.rb +123 -65
- data/spec/steps/ace_steps.rb +60 -0
- data/spec/steps/global_variable.rb +39 -0
- data/spec/steps/text_editor_steps.rb +160 -0
- data/spec/support/capybara.rb +17 -0
- metadata +49 -19
- data/spec/acceptance/editor.feature +0 -68
- data/spec/steps/editor_steps.rb +0 -123
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d71a9e4754ddc023b99130576187b13e97cca3ce
|
4
|
+
data.tar.gz: 4ed1b62b217727d2a96bfa9c337049a8850e2684
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bb60b2b55e43a4403b29441647b3eae78b6ae563be42d2b84c5c6f4971eccd10875fe131bac0013042d641a0aa5165b564472cf1cc3db5039fadb54ac688e9f5
|
7
|
+
data.tar.gz: 77272e287ef54a97a9c8fdf70e9da1c02a7a62eee9cf5e05df6413b0ae4285b6686616aa35020ebe64735e1ead930cb80e1d00840f193c4a24250bc49661f237
|
data/.gitignore
CHANGED
data/.rspec
CHANGED
data/.rubocop.yml
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
AllCops:
|
2
|
+
Excludes:
|
3
|
+
- db/seeds.rb
|
4
|
+
|
5
|
+
AsciiComments:
|
6
|
+
Enabled: false
|
7
|
+
|
8
|
+
# メソッドの戻り値としてブロックの値を使う場合にもエラーになるため無効
|
9
|
+
# にしている
|
10
|
+
Blocks:
|
11
|
+
Enabled: false
|
12
|
+
|
13
|
+
Documentation:
|
14
|
+
Enabled: false
|
15
|
+
|
16
|
+
# WindowsだとEndOfLine copが動作しないため無効にしている
|
17
|
+
EndOfLine:
|
18
|
+
Enabled: false
|
data/.travis.yml
CHANGED
@@ -1,23 +1,24 @@
|
|
1
|
-
language: ruby
|
2
|
-
|
3
|
-
rvm:
|
4
|
-
- 2.0.0
|
5
|
-
|
6
|
-
before_script:
|
7
|
-
- cp config/database.yml.travis config/database.yml
|
8
|
-
- mysql -e 'create database myapp_test;'
|
9
|
-
|
10
|
-
script:
|
11
|
-
- export SECRET_KEY_BASE='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
|
12
|
-
- export COVERALLS='1'
|
13
|
-
- RAILS_ENV=test bundle exec rake db:migrate --trace
|
14
|
-
- bundle exec rake db:test:prepare
|
15
|
-
- bundle exec rake
|
16
|
-
|
17
|
-
deploy:
|
18
|
-
provider: heroku
|
19
|
-
api_key:
|
20
|
-
secure: HqZ7FylThjaB3XguCZJbccu7dB8CvWIWFlZpWLLfJwfUkjvoEC1F6VPFakFbwjLXLsvaKlYLakzL+bhaLnxu+HyeNmCrvpIRR2j8EuHmSkxdWrlxAZRV2ojHuDpZuVNaEzd7YtcBCoPiTvqnxWzhAfzZWbPrZfCdA1f+5t5/So0=
|
21
|
-
app: smalruby
|
22
|
-
on:
|
23
|
-
repo: smalruby/smalruby-editor
|
1
|
+
language: ruby
|
2
|
+
|
3
|
+
rvm:
|
4
|
+
- 2.0.0
|
5
|
+
|
6
|
+
before_script:
|
7
|
+
- cp config/database.yml.travis config/database.yml
|
8
|
+
- mysql -e 'create database myapp_test;'
|
9
|
+
|
10
|
+
script:
|
11
|
+
- export SECRET_KEY_BASE='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
|
12
|
+
- export COVERALLS='1'
|
13
|
+
- RAILS_ENV=test bundle exec rake db:migrate --trace
|
14
|
+
- bundle exec rake db:test:prepare
|
15
|
+
- bundle exec rake
|
16
|
+
|
17
|
+
deploy:
|
18
|
+
provider: heroku
|
19
|
+
api_key:
|
20
|
+
secure: HqZ7FylThjaB3XguCZJbccu7dB8CvWIWFlZpWLLfJwfUkjvoEC1F6VPFakFbwjLXLsvaKlYLakzL+bhaLnxu+HyeNmCrvpIRR2j8EuHmSkxdWrlxAZRV2ojHuDpZuVNaEzd7YtcBCoPiTvqnxWzhAfzZWbPrZfCdA1f+5t5/So0=
|
21
|
+
app: smalruby
|
22
|
+
on:
|
23
|
+
repo: smalruby/smalruby-editor
|
24
|
+
run: "rake db:migrate"
|
data/LEGAL
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
LEGAL NOTICE INFORMATION
|
2
|
+
------------------------
|
3
|
+
|
4
|
+
All the files in this distribution are covered under either the
|
5
|
+
smalruby-editor's license (see the file LICENSE) except some files
|
6
|
+
mentioned below.
|
7
|
+
|
8
|
+
public/fonts/FontAwesome.otf, public/fonts/fontawesome-webfont.eot,
|
9
|
+
public/fonts/fontawesome-webfont.ttf,
|
10
|
+
public/fonts/fontawesome-webfont.woff:
|
11
|
+
|
12
|
+
These's license is SIL Open Font License (OFL) 1.1:
|
13
|
+
http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL .
|
data/README.rdoc
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
== smalruby-editor
|
2
2
|
|
3
|
+
{<img src="https://badge.fury.io/rb/smalruby-editor.png" alt="Gem Version" />}[http://badge.fury.io/rb/smalruby-editor]
|
3
4
|
{<img src="https://travis-ci.org/smalruby/smalruby-editor.png?branch=master" alt="Build Status" />}[https://travis-ci.org/smalruby/smalruby-editor]
|
4
5
|
{<img src="https://coveralls.io/repos/smalruby/smalruby-editor/badge.png?branch=master" alt="Coverage Status" />}[https://coveralls.io/r/smalruby/smalruby-editor?branch=master]
|
5
6
|
{<img src="https://codeclimate.com/github/smalruby/smalruby-editor.png" />}[https://codeclimate.com/github/smalruby/smalruby-editor]
|
data/Rakefile
CHANGED
@@ -2,11 +2,22 @@
|
|
2
2
|
# All this logic will automatically be available in application.js.
|
3
3
|
# You can use CoffeeScript in this file: http://coffeescript.org/
|
4
4
|
|
5
|
+
changed = false
|
6
|
+
|
5
7
|
$ ->
|
8
|
+
saving = false
|
9
|
+
|
6
10
|
textEditor = ace.edit('text-editor')
|
7
|
-
textEditor.setTheme('ace/theme/
|
11
|
+
textEditor.setTheme('ace/theme/github')
|
8
12
|
textEditor.setShowInvisibles(true)
|
9
13
|
|
14
|
+
textEditor.focus()
|
15
|
+
textEditor.gotoLine(0, 0)
|
16
|
+
|
17
|
+
textEditor.on('change', (e) ->
|
18
|
+
changed = true
|
19
|
+
)
|
20
|
+
|
10
21
|
session = textEditor.getSession()
|
11
22
|
session.setMode('ace/mode/ruby')
|
12
23
|
session.setTabSize(2)
|
@@ -20,18 +31,40 @@ $ ->
|
|
20
31
|
e.preventDefault()
|
21
32
|
false
|
22
33
|
|
23
|
-
$('#
|
34
|
+
$('#check-button').click (e) ->
|
35
|
+
e.preventDefault()
|
36
|
+
data =
|
37
|
+
source_code:
|
38
|
+
data: session.getDocument().getValue()
|
39
|
+
success = (data, textStatus, jqXHR) ->
|
40
|
+
for errorInfo in data
|
41
|
+
do (errorInfo) ->
|
42
|
+
msg = $('<div class="alert alert-error" style="display: none">')
|
43
|
+
.append('<button type="button" class="close" data-dismiss="alert">×</button>')
|
44
|
+
.append('<h4><i class="icon-exclamation-sign"></i>エラー</h4>')
|
45
|
+
.append("#{errorInfo.row}行")
|
46
|
+
if errorInfo.column > 0
|
47
|
+
msg.append("、#{errorInfo.column}文字")
|
48
|
+
msg.append(": #{errorInfo.message}")
|
49
|
+
$('#messages').append(msg)
|
50
|
+
msg.fadeIn('slow')
|
51
|
+
$.post('/source_codes/check', data, success, 'json')
|
52
|
+
|
53
|
+
$('#save-button').click (e) ->
|
54
|
+
e.preventDefault()
|
24
55
|
filename = $.trim($('#filename').val())
|
25
56
|
if filename.length <= 0
|
26
57
|
$('#filename').focus()
|
27
58
|
else
|
28
59
|
data =
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
60
|
+
source_code:
|
61
|
+
filename: filename
|
62
|
+
data: session.getDocument().getValue()
|
63
|
+
success = (data, textStatus, jqXHR) ->
|
64
|
+
saving = true
|
65
|
+
changed = false
|
66
|
+
$('#download-link').click()
|
67
|
+
$.post('/source_codes/', data, success, 'json')
|
35
68
|
|
36
69
|
$('#filename').keypress (e) ->
|
37
70
|
e = window.event if !e
|
@@ -41,20 +74,32 @@ $ ->
|
|
41
74
|
else
|
42
75
|
true
|
43
76
|
|
77
|
+
$('#load-button').click (e) ->
|
78
|
+
e.preventDefault()
|
79
|
+
if changed
|
80
|
+
return unless confirm('まだセーブしていないのでロードするとプログラムが消えてしまうよ!それでもロードしますか?')
|
81
|
+
$(@).parent().find('input[name="source_code[file]"]').click()
|
82
|
+
|
44
83
|
$('#file-form').fileupload(
|
45
84
|
dataType: 'json'
|
46
|
-
add: (e, data) ->
|
47
|
-
data.submit()
|
48
85
|
done: (e, data) ->
|
49
|
-
|
50
|
-
if
|
86
|
+
info = data.result.source_code
|
87
|
+
if info.error
|
51
88
|
msg = $('<div class="alert alert-error" style="display: none">')
|
52
89
|
.append('<button type="button" class="close" data-dismiss="alert">×</button>')
|
53
90
|
.append('<h4><i class="icon-exclamation-sign"></i>エラー</h4>')
|
54
|
-
.append(
|
91
|
+
.append(info.filename + 'は' + info.error)
|
55
92
|
$('#messages').append(msg)
|
56
93
|
msg.fadeIn('slow').delay(5000).fadeOut('slow')
|
57
94
|
else
|
58
|
-
$('#filename').val(
|
59
|
-
session.getDocument().setValue(
|
95
|
+
$('#filename').val(info.filename)
|
96
|
+
session.getDocument().setValue(info.data)
|
97
|
+
changed = false
|
60
98
|
)
|
99
|
+
|
100
|
+
window.onbeforeunload = (event) ->
|
101
|
+
if !saving && session.getDocument().getValue().length > 0
|
102
|
+
return '作成中のプログラムが消えてしまいます。'
|
103
|
+
else
|
104
|
+
saving = false
|
105
|
+
return
|
@@ -8,8 +8,7 @@
|
|
8
8
|
* You're free to add application-wide styles to this file and they'll appear at the top of the
|
9
9
|
* compiled file, but it's generally better to create a new file per style scope.
|
10
10
|
*
|
11
|
-
*= require flatstrap
|
12
|
-
*= require font-awesome
|
11
|
+
*= require flatstrap-custom
|
13
12
|
*= require_self
|
14
13
|
*= require_tree .
|
15
14
|
*/
|
@@ -1,29 +1,5 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
|
-
require 'nkf'
|
3
|
-
|
4
2
|
class EditorController < ApplicationController
|
5
3
|
def index
|
6
4
|
end
|
7
|
-
|
8
|
-
def save_file
|
9
|
-
send_data(params[:source], filename: params[:filename],
|
10
|
-
disposition: 'attachment', type: 'text/plain; charset=utf-8')
|
11
|
-
end
|
12
|
-
|
13
|
-
def load_file
|
14
|
-
f = params['load_file']
|
15
|
-
mime_type = MIME.check(f.path)
|
16
|
-
content_type = mime_type.try(:content_type) || f.content_type
|
17
|
-
res = {
|
18
|
-
name: f.original_filename,
|
19
|
-
type: content_type,
|
20
|
-
size: f.size,
|
21
|
-
}
|
22
|
-
if /\Atext\/plain/ =~ content_type
|
23
|
-
res[:source] = NKF.nkf('-w', f.read)
|
24
|
-
else
|
25
|
-
res[:error] = 'Rubyのプログラムではありません'
|
26
|
-
end
|
27
|
-
render json: res, content_type: request.format
|
28
|
-
end
|
29
5
|
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
require 'nkf'
|
3
|
+
|
4
|
+
class SourceCodesController < ApplicationController
|
5
|
+
def check
|
6
|
+
render json: SourceCode.new(source_code_params).check_syntax
|
7
|
+
end
|
8
|
+
|
9
|
+
def create
|
10
|
+
source_code = SourceCode.create!(source_code_params)
|
11
|
+
session[:source_code] = {
|
12
|
+
id: source_code.id,
|
13
|
+
digest: source_code.digest,
|
14
|
+
}
|
15
|
+
render json: { source_code: { id: source_code.id } }
|
16
|
+
end
|
17
|
+
|
18
|
+
def download
|
19
|
+
source_code = SourceCode.find(session[:source_code][:id])
|
20
|
+
unless source_code.digest == session[:source_code][:digest]
|
21
|
+
fail ActiveRecord::RecordNotFound
|
22
|
+
end
|
23
|
+
|
24
|
+
send_data(source_code.data,
|
25
|
+
filename: encode_filename(source_code.filename),
|
26
|
+
disposition: 'attachment',
|
27
|
+
type: 'text/plain; charset=utf-8')
|
28
|
+
|
29
|
+
source_code.destroy
|
30
|
+
|
31
|
+
session[:source_code] = nil
|
32
|
+
end
|
33
|
+
|
34
|
+
def load
|
35
|
+
f = params[:source_code][:file]
|
36
|
+
info = get_file_info(f)
|
37
|
+
if /\Atext\/plain/ =~ info[:type]
|
38
|
+
info[:data] = NKF.nkf('-w', f.read)
|
39
|
+
else
|
40
|
+
info[:error] = 'Rubyのプログラムではありません'
|
41
|
+
end
|
42
|
+
|
43
|
+
render json: { source_code: info }, content_type: request.format
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def source_code_params
|
49
|
+
params.require(:source_code).permit(:data, :filename)
|
50
|
+
end
|
51
|
+
|
52
|
+
def get_file_info(file)
|
53
|
+
{
|
54
|
+
filename: file.original_filename,
|
55
|
+
type: MIME.check(file.path).try(:content_type) || file.content_type,
|
56
|
+
size: file.size,
|
57
|
+
}
|
58
|
+
end
|
59
|
+
|
60
|
+
def encode_filename(filename)
|
61
|
+
if request.env['HTTP_USER_AGENT'] =~ /MSIE|Trident/
|
62
|
+
return ERB::Util.url_encode(filename)
|
63
|
+
else
|
64
|
+
filename
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'tempfile'
|
4
|
+
require 'open3'
|
5
|
+
require 'digest/sha2'
|
6
|
+
|
7
|
+
# ソースコードを表現するモデル
|
8
|
+
class SourceCode < ActiveRecord::Base
|
9
|
+
validates :filename, presence: true
|
10
|
+
validates :data, presence: true, allow_blank: true
|
11
|
+
|
12
|
+
# シンタックスをチェックする
|
13
|
+
def check_syntax
|
14
|
+
_, stderr_str, status = *open3_capture3_ruby_c
|
15
|
+
return [] if status.success?
|
16
|
+
|
17
|
+
stderr_str.lines.each.with_object([]) { |line, res|
|
18
|
+
if (md = /^.*:(\d+): (.*)$/.match(line))
|
19
|
+
res << { row: md[1].to_i, column: 0, message: md[2] }
|
20
|
+
elsif (md = /( +)\^$/.match(line))
|
21
|
+
res[-1][:column] = md[1].length
|
22
|
+
end
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
# ハッシュ値を計算する
|
27
|
+
def digest
|
28
|
+
Digest::SHA256.hexdigest(data)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def open3_capture3_ruby_c
|
34
|
+
tempfile = Tempfile.new('smalruby-editor')
|
35
|
+
tempfile.write(data)
|
36
|
+
path = tempfile.path
|
37
|
+
tempfile.close
|
38
|
+
ruby_cmd = File.join(RbConfig::CONFIG['bindir'],
|
39
|
+
RbConfig::CONFIG['RUBY_INSTALL_NAME'])
|
40
|
+
Open3.capture3("#{ruby_cmd} -c #{path}")
|
41
|
+
end
|
42
|
+
end
|
@@ -4,11 +4,13 @@
|
|
4
4
|
<li class="active"><a id="ruby-tab" href="#">Ruby</a></li>
|
5
5
|
</ul>
|
6
6
|
|
7
|
-
<%= form_tag(
|
7
|
+
<%= form_tag(source_codes_load_path, id: "file-form", class: "navbar-form pull-right", method: "post", multipart: true) do %>
|
8
|
+
<button id="check-button" type="button" class="btn btn-primary">チェック</button>
|
8
9
|
<input id="filename" type="text" class="span4" placeholder="プログラムの名前を入れてね(例:01.rb)">
|
9
10
|
<button id="save-button" type="button" class="btn btn-primary">セーブ</button>
|
10
|
-
|
11
|
-
<
|
11
|
+
<%= link_to '', source_codes_download_path, id: 'download-link', style: 'display: none', 'data-method' => 'delete' %>
|
12
|
+
<button id="load-button" class="btn btn-primary">ロード</button>
|
13
|
+
<input id="load-file" type="file" name="source_code[file]" style="display: none">
|
12
14
|
<% end %>
|
13
15
|
</div>
|
14
16
|
</div>
|
data/bin/smalruby-editor
CHANGED
@@ -17,6 +17,7 @@ require 'smalruby_editor'
|
|
17
17
|
Dir.chdir(File.expand_path('../../', APP_PATH))
|
18
18
|
require 'rails/commands/server'
|
19
19
|
|
20
|
+
# rubocop:disable all
|
20
21
|
module Rails
|
21
22
|
class Server < ::Rack::Server
|
22
23
|
def start
|
@@ -35,6 +36,15 @@ module Rails
|
|
35
36
|
console.level = Rails.logger.level
|
36
37
|
|
37
38
|
Rails.logger.extend(ActiveSupport::Logger.broadcast(console))
|
39
|
+
|
40
|
+
if ActiveRecord::Migrator.needs_migration?
|
41
|
+
ActiveRecord::Migration.verbose = true
|
42
|
+
begin
|
43
|
+
ActiveRecord::Migrator.migrate(ActiveRecord::Migrator.migrations_paths)
|
44
|
+
ensure
|
45
|
+
ActiveRecord::Migration.verbose = false
|
46
|
+
end
|
47
|
+
end
|
38
48
|
end
|
39
49
|
|
40
50
|
uri = "http://localhost:#{options[:Port]}"
|
@@ -71,3 +81,4 @@ Rails::Server.new.tap do |server|
|
|
71
81
|
Dir.chdir(Rails.application.root)
|
72
82
|
server.start
|
73
83
|
end
|
84
|
+
# rubocop:enable all
|