browser_app_base 0.0.2 → 0.0.6
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 +4 -4
- data/.vscode/launch.json +15 -0
- data/README.md +29 -4
- data/bin/create_browser_app.rb +2 -1
- data/lib/browser_app_base/version.rb +1 -1
- data/lib/browser_app_base.rb +50 -4
- data/lib/template/app_load.rb +2 -0
- data/lib/template/config/browser.json +1 -1
- data/lib/template/config/setting.json +50 -0
- data/lib/template/config.ru +29 -1
- data/lib/template/css/index.css +59 -7
- data/lib/template/index.html +33 -7
- data/lib/template/js/main.js +217 -42
- data/lib/template/{server_app.rb → my_app_sample.rb} +10 -7
- data/lib/template/server.rb +28 -10
- data/lib/template/server_app_base.rb +32 -0
- data/lib/template/start.rb +7 -7
- data/lib/template/wsserver.rb +67 -9
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ee14b20cd2c842b0c470d9b96f31549ae576912a5e79afcbb4b44b35d3cfc740
|
4
|
+
data.tar.gz: 746081592fef24334ae14f50fbcddb672fa29103b800ea8bd84048711ff0ec9e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a0360895d392e1fdbf2930c73c82ba09a8551ea15014ee30f5e71393b4b04d48ea52773f174cc4eb884eea85574e338bf0d8661362c3c4f1cda8512429466f4c
|
7
|
+
data.tar.gz: a48af4eeb30f310d5f601e19a212fb2c4e4239b61952ab33b2cc50d9e2392dc14b7fec672abc64507aadf55d415831cb194048af9c8903e7fb7e604476895441
|
data/.vscode/launch.json
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
{
|
2
|
+
// IntelliSense を使用して利用可能な属性を学べます。
|
3
|
+
// 既存の属性の説明をホバーして表示します。
|
4
|
+
// 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387
|
5
|
+
"version": "0.2.0",
|
6
|
+
"configurations": [
|
7
|
+
{
|
8
|
+
"name": "Debug Local File",
|
9
|
+
"type": "Ruby",
|
10
|
+
"request": "launch",
|
11
|
+
"cwd": "${workspaceRoot}/lib/template/",
|
12
|
+
"program": "${workspaceRoot}/lib/template/start.rb"
|
13
|
+
}
|
14
|
+
]
|
15
|
+
}
|
data/README.md
CHANGED
@@ -24,16 +24,41 @@ Or install it yourself as:
|
|
24
24
|
|
25
25
|
create_browser_app [options]
|
26
26
|
-d, --dir dir_name application directory
|
27
|
+
-a, --app app_name application name
|
27
28
|
-h, --help command help
|
28
29
|
|
29
30
|
|
30
|
-
|
31
|
+
## Create app templat
|
31
32
|
|
32
|
-
$ create_browser_app -d ~/test/
|
33
|
+
$ create_browser_app -d ~/test/ -a MyApp
|
33
34
|
|
34
|
-
|
35
|
+
## add application code
|
36
|
+
$ cd ~/test/
|
37
|
+
$ vi my_app.rb
|
35
38
|
|
36
|
-
|
39
|
+
```ruby
|
40
|
+
class MyApp < AppMainBase
|
41
|
+
def start(argv)
|
42
|
+
super
|
43
|
+
# add application code
|
44
|
+
end
|
45
|
+
|
46
|
+
def stop()
|
47
|
+
super
|
48
|
+
# add application code
|
49
|
+
end
|
50
|
+
end
|
51
|
+
```
|
52
|
+
|
53
|
+
ui application sample
|
54
|
+
|
55
|
+
index.html
|
56
|
+
css/index.css
|
57
|
+
js/main.js
|
58
|
+
|
59
|
+
## Start application
|
60
|
+
|
61
|
+
$ cd ~/test/
|
37
62
|
$ ruby start.rb
|
38
63
|
|
39
64
|
## Development
|
data/bin/create_browser_app.rb
CHANGED
@@ -7,6 +7,7 @@ require "optparse"
|
|
7
7
|
opt = OptionParser.new
|
8
8
|
o = {}
|
9
9
|
opt.on("-d dir_name", "--dir dir_name", "application directory") { |v| o[:dir] = v }
|
10
|
+
opt.on("-a app_name", "--app app_name", "application name") { |v| o[:app] = v }
|
10
11
|
opt.on("-h", "--help", "command help") { puts opt; exit }
|
11
12
|
begin
|
12
13
|
opt.parse!(ARGV)
|
@@ -20,4 +21,4 @@ if o[:dir] == nil
|
|
20
21
|
exit
|
21
22
|
end
|
22
23
|
|
23
|
-
BrowserAppBase.create o
|
24
|
+
BrowserAppBase.create o
|
data/lib/browser_app_base.rb
CHANGED
@@ -1,20 +1,66 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative "browser_app_base/version"
|
4
|
-
|
5
4
|
require "fileutils"
|
6
5
|
|
7
6
|
module BrowserAppBase
|
8
7
|
class Error < StandardError; end
|
9
8
|
|
10
|
-
|
9
|
+
def self.get_app_file(app)
|
10
|
+
app_file_name = ""
|
11
|
+
app.each_char do |s|
|
12
|
+
if s =~ /[A-Z]/
|
13
|
+
app_file_name += "_" if app_file_name.size != 0
|
14
|
+
app_file_name += s.downcase
|
15
|
+
else
|
16
|
+
app_file_name += s
|
17
|
+
end
|
18
|
+
end
|
19
|
+
return app_file_name + ".rb"
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.get_app_name(app)
|
23
|
+
app_name = ""
|
24
|
+
app.each_char do |s|
|
25
|
+
if s =~ /[a-z]/ and app_name.size == 0
|
26
|
+
app_name += s.upcase
|
27
|
+
else
|
28
|
+
app_name += s
|
29
|
+
end
|
30
|
+
end
|
31
|
+
return app_name
|
32
|
+
end
|
11
33
|
|
12
|
-
def self.create(
|
34
|
+
def self.create(arg)
|
35
|
+
dir = arg[:dir]
|
36
|
+
app = arg[:app]
|
13
37
|
puts "create application base #{dir}"
|
14
38
|
|
15
39
|
FileUtils.mkdir_p dir
|
16
40
|
|
17
41
|
path = File.dirname(File.expand_path(__FILE__))
|
18
|
-
|
42
|
+
Dir.glob("#{path}/template/*") do |f|
|
43
|
+
puts "#{f} => #{dir}"
|
44
|
+
FileUtils.cp_r f, "#{dir}/"
|
45
|
+
end
|
46
|
+
|
47
|
+
if app
|
48
|
+
app_file = get_app_file(app)
|
49
|
+
|
50
|
+
load_app = <<"EOS"
|
51
|
+
require '#{app_file}'
|
52
|
+
$app = #{get_app_name(app)}.new
|
53
|
+
EOS
|
54
|
+
|
55
|
+
File.open("#{dir}/app_load.rb", "w") do |f|
|
56
|
+
f.write load_app
|
57
|
+
end
|
58
|
+
|
59
|
+
puts "create #{app_file}"
|
60
|
+
new_file = "#{dir}/#{app_file}"
|
61
|
+
FileUtils.cp("#{dir}/my_app_sample.rb", new_file)
|
62
|
+
buf = File.binread(new_file)
|
63
|
+
File.binwrite(new_file, buf.gsub(/MyApp/, get_app_name(app)))
|
64
|
+
end
|
19
65
|
end
|
20
66
|
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
[
|
2
|
+
{
|
3
|
+
"name": "name1",
|
4
|
+
"value": "value1",
|
5
|
+
"type": "input",
|
6
|
+
"select": "",
|
7
|
+
"description": "設定項目1"
|
8
|
+
},
|
9
|
+
{
|
10
|
+
"name": "name2",
|
11
|
+
"value": true,
|
12
|
+
"type": "checkbox",
|
13
|
+
"select": "",
|
14
|
+
"description": "有効にする場合はチェック"
|
15
|
+
},
|
16
|
+
{
|
17
|
+
"name": "name3",
|
18
|
+
"value": "1",
|
19
|
+
"type": "select",
|
20
|
+
"select": [
|
21
|
+
"1",
|
22
|
+
"2",
|
23
|
+
"3",
|
24
|
+
"4",
|
25
|
+
"5"
|
26
|
+
],
|
27
|
+
"description": "選択項目"
|
28
|
+
},
|
29
|
+
{
|
30
|
+
"name": "name4",
|
31
|
+
"value": "value4",
|
32
|
+
"type": "input",
|
33
|
+
"select": "",
|
34
|
+
"description": "設定項目4"
|
35
|
+
},
|
36
|
+
{
|
37
|
+
"name": "name5",
|
38
|
+
"value": "value5",
|
39
|
+
"type": "input",
|
40
|
+
"select": "",
|
41
|
+
"description": "設定項目5"
|
42
|
+
},
|
43
|
+
{
|
44
|
+
"name": "name6",
|
45
|
+
"value": "value6",
|
46
|
+
"type": "input",
|
47
|
+
"select": "",
|
48
|
+
"description": "設定項目6"
|
49
|
+
}
|
50
|
+
]
|
data/lib/template/config.ru
CHANGED
@@ -24,6 +24,34 @@ get "/js/:name.js" do
|
|
24
24
|
File.read "js/#{params[:name]}.js"
|
25
25
|
end
|
26
26
|
|
27
|
+
get "/config/*.*" do |file, ext|
|
28
|
+
content_type "text/json", :charset => "utf-8"
|
29
|
+
puts "#{file}.#{ext}"
|
30
|
+
File.read "config/#{file}.#{ext}"
|
31
|
+
end
|
32
|
+
|
33
|
+
get "/open_dialog" do
|
34
|
+
dialog_html = <<'EOS'
|
35
|
+
<!DOCTYPE html>
|
36
|
+
<html>
|
37
|
+
<head>
|
38
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
39
|
+
<title>Message Dialog</title>
|
40
|
+
<style type="text/css">
|
41
|
+
<!--
|
42
|
+
body {
|
43
|
+
color: #000000;
|
44
|
+
background-color: #ffffff;
|
45
|
+
overflow: hidden;
|
46
|
+
font-size: 12px;
|
47
|
+
}
|
48
|
+
-->
|
49
|
+
</style>
|
50
|
+
</head>
|
51
|
+
EOS
|
52
|
+
dialog_html += "<body>" + params["msg"] + "</body></html>"
|
53
|
+
end
|
54
|
+
|
27
55
|
map "/search" do
|
28
56
|
run Search
|
29
57
|
end
|
@@ -46,6 +74,6 @@ configure do
|
|
46
74
|
|
47
75
|
end
|
48
76
|
|
49
|
-
#\ --port
|
77
|
+
#\ --port 54068
|
50
78
|
|
51
79
|
run Sinatra::Application
|
data/lib/template/css/index.css
CHANGED
@@ -2,6 +2,7 @@ body {
|
|
2
2
|
color: #000000;
|
3
3
|
background-color: #cac3ec4f;
|
4
4
|
overflow: hidden;
|
5
|
+
font-size: 12px;
|
5
6
|
}
|
6
7
|
|
7
8
|
hr {
|
@@ -22,9 +23,9 @@ hr {
|
|
22
23
|
padding: 5px;
|
23
24
|
width: 95vw;
|
24
25
|
height: 50vh;
|
26
|
+
overflow: auto;
|
25
27
|
}
|
26
28
|
|
27
|
-
|
28
29
|
.inarea {
|
29
30
|
border: thin solid #000000;
|
30
31
|
margin: 5px;
|
@@ -32,12 +33,6 @@ hr {
|
|
32
33
|
width: 95%;
|
33
34
|
}
|
34
35
|
|
35
|
-
input {
|
36
|
-
background-color: #FAFAFA;
|
37
|
-
margin: 5px;
|
38
|
-
padding: 5px;
|
39
|
-
}
|
40
|
-
|
41
36
|
input.long {
|
42
37
|
width: 90%;
|
43
38
|
background-color: #FAFAFA;
|
@@ -50,3 +45,60 @@ textarea.long {
|
|
50
45
|
height: 50vh;
|
51
46
|
}
|
52
47
|
|
48
|
+
.ui-widget {
|
49
|
+
font-size: 12px;
|
50
|
+
}
|
51
|
+
|
52
|
+
.ui-autocomplete {
|
53
|
+
max-height: 45vh;
|
54
|
+
max-width: 90wh;
|
55
|
+
overflow-y: auto;
|
56
|
+
overflow-x: auto;
|
57
|
+
padding-right: 10px;
|
58
|
+
}
|
59
|
+
|
60
|
+
#jquery-ui-autocomplete label {
|
61
|
+
float: left;
|
62
|
+
margin-right: 0.5em;
|
63
|
+
color: black;
|
64
|
+
}
|
65
|
+
|
66
|
+
.ui-dialog {
|
67
|
+
position: absolute;
|
68
|
+
top: 0;
|
69
|
+
left: 0;
|
70
|
+
padding: .2em;
|
71
|
+
outline: 0;
|
72
|
+
}
|
73
|
+
|
74
|
+
.long {
|
75
|
+
width: 90%;
|
76
|
+
}
|
77
|
+
|
78
|
+
#setting_dialog {
|
79
|
+
color: #796fe9;
|
80
|
+
background-color: #000000;
|
81
|
+
}
|
82
|
+
|
83
|
+
.setting_name {
|
84
|
+
width: 200px;
|
85
|
+
color: #796fe9;
|
86
|
+
background-color: #000000;
|
87
|
+
}
|
88
|
+
|
89
|
+
.setting_value {
|
90
|
+
width: 300px;
|
91
|
+
color: #796fe9;
|
92
|
+
background-color: #000000;
|
93
|
+
}
|
94
|
+
|
95
|
+
.setting_checkbox {
|
96
|
+
color: #796fe9;
|
97
|
+
background-color: #000000;
|
98
|
+
}
|
99
|
+
|
100
|
+
ul.log {
|
101
|
+
list-style-type: decimal;
|
102
|
+
font-size: 12px;
|
103
|
+
color: #5d0a94;
|
104
|
+
}
|
data/lib/template/index.html
CHANGED
@@ -11,12 +11,12 @@
|
|
11
11
|
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
|
12
12
|
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">
|
13
13
|
|
14
|
-
<script src="http://localhost:
|
15
|
-
<link rel="stylesheet" href="http://localhost:
|
14
|
+
<script src="http://localhost:54068/js/main.js"></script>
|
15
|
+
<link rel="stylesheet" href="http://localhost:54068/css/index.css" type="text/css">
|
16
16
|
</head>
|
17
17
|
|
18
18
|
<body>
|
19
|
-
<
|
19
|
+
<h4>サンプル</h4>
|
20
20
|
<hr>
|
21
21
|
<table>
|
22
22
|
<tr>
|
@@ -26,13 +26,39 @@
|
|
26
26
|
<td>
|
27
27
|
<input type="button" id="stop" name="stop" value="停止">
|
28
28
|
</td>
|
29
|
+
<td>
|
30
|
+
<div id="setting_dialog" style="display:none;">
|
31
|
+
<dl id="wrap"></dl>
|
32
|
+
</div>
|
33
|
+
<input type="button" id="setting" value="設定" />
|
34
|
+
</td>
|
35
|
+
</tr>
|
36
|
+
</table>
|
37
|
+
|
38
|
+
<div id="dialog1" style="display:none;">
|
39
|
+
<input class="inarea" type="text" name="search_str" id="search_str">
|
40
|
+
</div>
|
41
|
+
<table>
|
42
|
+
<tr>
|
43
|
+
<td class="long"><input class="inarea" type="text" id="upFile" name="upFile"></td>
|
44
|
+
<td><input type="button" id="select_file" value="ファイル選択" /></td>
|
45
|
+
</tr>
|
46
|
+
</table>
|
47
|
+
|
48
|
+
<div id="dialog2" style="display:none;">
|
49
|
+
<input class="inarea" type="text" name="search_str2" id="search_str2">
|
50
|
+
</div>
|
51
|
+
<table>
|
52
|
+
<tr>
|
53
|
+
<td class="long"><input class="inarea" type="text" id="upDir" name="upDir"></td>
|
54
|
+
<td><input type="button" id="select_dir" value="フォルダ選択" /></td>
|
29
55
|
</tr>
|
30
56
|
</table>
|
31
|
-
<input class="inarea" type="text" value="ファイル名を入力" name="search_str" id="search_str">
|
32
|
-
<input class="inarea" type="file" id="upFile" name="upFile" value="upFile"><br>
|
33
|
-
<input type="button" value="確認" onclick="dispFile()">
|
34
57
|
|
35
|
-
<
|
58
|
+
<div class="outarea">
|
59
|
+
<ul name="log" id="log" class="log">
|
60
|
+
</ul>
|
61
|
+
</div>
|
36
62
|
|
37
63
|
</body>
|
38
64
|
|
data/lib/template/js/main.js
CHANGED
@@ -1,6 +1,30 @@
|
|
1
1
|
// main.js
|
2
2
|
|
3
3
|
var $ws = null;
|
4
|
+
var $auto_scroll = true;
|
5
|
+
var dialog = null;
|
6
|
+
|
7
|
+
function open_dialog(msg) {
|
8
|
+
var top = window.screenTop + 10;
|
9
|
+
var left = window.screenLeft + 10;
|
10
|
+
if (dialog != null) {
|
11
|
+
dialog.close();
|
12
|
+
}
|
13
|
+
var dialog = window.open(
|
14
|
+
"/open_dialog?msg=" + msg,
|
15
|
+
"pop",
|
16
|
+
"width=300, height=100, left=" + left + ", top=" + top
|
17
|
+
);
|
18
|
+
console.log("open dialog dialog=" + dialog);
|
19
|
+
if (dialog == null) {
|
20
|
+
console.log("open dialog retry");
|
21
|
+
setTimeout(function () {
|
22
|
+
open_dialog(msg);
|
23
|
+
}, 1000);
|
24
|
+
} else {
|
25
|
+
dialog.focus();
|
26
|
+
}
|
27
|
+
}
|
4
28
|
|
5
29
|
function server_connect(url) {
|
6
30
|
var ws = new WebSocket(url);
|
@@ -10,21 +34,23 @@ function server_connect(url) {
|
|
10
34
|
};
|
11
35
|
ws.onmessage = function (evt) {
|
12
36
|
//alert(evt.data);
|
37
|
+
|
13
38
|
if (evt.data.match(/^startup:/)) {
|
14
39
|
file_name = evt.data.replace(/^startup:/, "");
|
15
40
|
//alert(file_name);
|
16
|
-
|
17
|
-
|
18
|
-
|
41
|
+
}
|
42
|
+
else if (evt.data.match(/^app_end:normal/)) {
|
43
|
+
open_dialog("終了しました");
|
44
|
+
}
|
45
|
+
else if (evt.data.match(/^app_end:error/)) {
|
46
|
+
open_dialog("<font color='red'>エラーが発生しました</font>");
|
19
47
|
} else {
|
20
|
-
var log =
|
21
|
-
$('#log').
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
);
|
48
|
+
var log = "<li>" + evt.data + "</li>";
|
49
|
+
$('#log').append(log);
|
50
|
+
if ($auto_scroll) {
|
51
|
+
$('.outarea').scrollTop($('.outarea').get(0).scrollHeight);
|
52
|
+
}
|
26
53
|
}
|
27
|
-
|
28
54
|
};
|
29
55
|
ws.onclose = function () {
|
30
56
|
alert("アプリケーションが終了しました!!");
|
@@ -41,11 +67,20 @@ function send_message(msg) {
|
|
41
67
|
}
|
42
68
|
}
|
43
69
|
|
44
|
-
function autocomp(id,
|
70
|
+
function autocomp(id, file_kind) {
|
45
71
|
$("#" + id).autocomplete({
|
72
|
+
autoFocus: true,
|
73
|
+
minLength: 0,
|
74
|
+
delay: 0,
|
75
|
+
select: function (event, ui) {
|
76
|
+
//console.log(ui.item.value);
|
77
|
+
jQuery("#" + id).val(ui.item.value);
|
78
|
+
//jQuery(this).autocomplete("search", "");
|
79
|
+
$(this).keydown();
|
80
|
+
},
|
46
81
|
source: function (req, resp) {
|
47
82
|
$.ajax({
|
48
|
-
url:
|
83
|
+
url: "http://localhost:54068/search?path=" + $("#" + id).val() + "&kind=" + file_kind,
|
49
84
|
type: "GET",
|
50
85
|
cache: false,
|
51
86
|
dataType: "json",
|
@@ -61,6 +96,142 @@ function autocomp(id, url) {
|
|
61
96
|
});
|
62
97
|
|
63
98
|
}
|
99
|
+
}).focus(function () {
|
100
|
+
//jQuery(this).autocomplete("search", "");
|
101
|
+
$(this).keydown();
|
102
|
+
});
|
103
|
+
}
|
104
|
+
|
105
|
+
function select_file_dialog(search_id, file_kind, dialog_id, select_file, file_name) {
|
106
|
+
$("#" + select_file).click(function () {
|
107
|
+
autocomp(search_id, file_kind);
|
108
|
+
$(".ui-autocomplete").css("z-index", 1000);
|
109
|
+
$("#" + search_id).val("/");
|
110
|
+
$("#" + dialog_id).dialog({
|
111
|
+
modal: true
|
112
|
+
, show: "slide" //表示時のアニメーション
|
113
|
+
, hide: "explode" //閉じた時のアニメーション
|
114
|
+
, title: "Select File" //ダイアログのタイトル
|
115
|
+
, width: 580 //ダイアログの横幅
|
116
|
+
, height: 400 //ダイアログの高さ
|
117
|
+
, resizable: true //リサイズ可
|
118
|
+
, closeOnEscape: false //[ESC]キーで閉じられなくする
|
119
|
+
, draggable: true //ダイアログの移動を可に
|
120
|
+
, buttons: {
|
121
|
+
"OK": function () { //OKボタン
|
122
|
+
$("#" + file_name).val($("#" + search_id).val());
|
123
|
+
$(this).dialog("close");
|
124
|
+
$("#" + search_id).autocomplete("destroy");
|
125
|
+
},
|
126
|
+
"Cancel": function () { //Cancelボタン
|
127
|
+
$(this).dialog("close");
|
128
|
+
$("#" + search_id).autocomplete("destroy");
|
129
|
+
}
|
130
|
+
}
|
131
|
+
});
|
132
|
+
});
|
133
|
+
}
|
134
|
+
|
135
|
+
function setting_dialog(open_id, dialog_id, json_file) {
|
136
|
+
$("#" + open_id).click(function () {
|
137
|
+
$("#" + dialog_id).val = $(function () {
|
138
|
+
$("dl#wrap").empty();
|
139
|
+
$.getJSON(json_file, function (s) {
|
140
|
+
for (var i in s) {
|
141
|
+
if (s[i].type == "input") {
|
142
|
+
var h = "<table><tr>"
|
143
|
+
+ "<td class='setting_name'>" + s[i].description + "</td>"
|
144
|
+
+ "<td><input class='setting_value' type='text' " + "id=" + s[i].name + "_value " + "value=" + s[i].value + ">"
|
145
|
+
+ "</td></tr></table>"
|
146
|
+
$("dl#wrap").append(h);
|
147
|
+
} else if (s[i].type == "checkbox") {
|
148
|
+
var h = "<table><tr>";
|
149
|
+
h += "<td class='setting_name'>" + s[i].description + "</td>";
|
150
|
+
if (s[i].value == true) {
|
151
|
+
h += "<td><input class='setting_checkbox' type='checkbox' " + "id=" + s[i].name + "_value checked ></td>";
|
152
|
+
} else {
|
153
|
+
h += "<td><input class='setting_checkbox' type='checkbox' " + "id=" + s[i].name + "_value ></td>";
|
154
|
+
}
|
155
|
+
h += "</tr></table>";
|
156
|
+
$("dl#wrap").append(h);
|
157
|
+
} else if (s[i].type == "select") {
|
158
|
+
var h = "<table><tr>";
|
159
|
+
h += "<td class='setting_name'>" + s[i].description + "</td>";
|
160
|
+
h += "<td> <select class='setting_value' id=" + s[i].name + "_value " + ">";
|
161
|
+
s[i].select.forEach(e => {
|
162
|
+
if (e == s[i].value) {
|
163
|
+
h += "<option value=" + e + " selected >" + e + "</option>";
|
164
|
+
} else {
|
165
|
+
h += "<option value=" + e + ">" + e + "</option>";
|
166
|
+
}
|
167
|
+
});
|
168
|
+
h += "</select></td>";
|
169
|
+
h += "</tr></table>";
|
170
|
+
$("dl#wrap").append(h);
|
171
|
+
} else {
|
172
|
+
//console.log("type=" + s[i].type);
|
173
|
+
}
|
174
|
+
}
|
175
|
+
});
|
176
|
+
});
|
177
|
+
$("#" + dialog_id).dialog({
|
178
|
+
modal: true
|
179
|
+
, show: "slide" //表示時のアニメーション
|
180
|
+
, hide: "explode" //閉じた時のアニメーション
|
181
|
+
, title: "Setting" //ダイアログのタイトル
|
182
|
+
, width: 580 //ダイアログの横幅
|
183
|
+
, height: 400 //ダイアログの高さ
|
184
|
+
, resizable: true //リサイズ可
|
185
|
+
, closeOnEscape: false //[ESC]キーで閉じられなくする
|
186
|
+
, draggable: true //ダイアログの移動を可に
|
187
|
+
, buttons: {
|
188
|
+
"OK": function () { //OKボタン
|
189
|
+
var json_data = []
|
190
|
+
$.getJSON(json_file, function (s) {
|
191
|
+
for (var i in s) {
|
192
|
+
//console.log(s[i].name);
|
193
|
+
if (s[i].type == "input") {
|
194
|
+
var data = {};
|
195
|
+
data["name"] = s[i].name;
|
196
|
+
data["value"] = $("#" + s[i].name + "_value").val();
|
197
|
+
data["type"] = s[i].type;
|
198
|
+
data["select"] = s[i].select;
|
199
|
+
data["description"] = s[i].description;
|
200
|
+
json_data.push(data);
|
201
|
+
}
|
202
|
+
else if (s[i].type == "checkbox") {
|
203
|
+
var data = {};
|
204
|
+
data["name"] = s[i].name;
|
205
|
+
if ($("#" + s[i].name + "_value:checked").val() == "on") {
|
206
|
+
data["value"] = true;
|
207
|
+
} else {
|
208
|
+
data["value"] = false;
|
209
|
+
}
|
210
|
+
data["type"] = s[i].type;
|
211
|
+
data["select"] = s[i].select;
|
212
|
+
data["description"] = s[i].description;
|
213
|
+
json_data.push(data);
|
214
|
+
} else if (s[i].type == "select") {
|
215
|
+
var data = {};
|
216
|
+
data["name"] = s[i].name;
|
217
|
+
data["value"] = $("#" + s[i].name + "_value" + " option:selected").val();
|
218
|
+
data["type"] = s[i].type;
|
219
|
+
data["select"] = s[i].select;
|
220
|
+
data["description"] = s[i].description;
|
221
|
+
json_data.push(data);
|
222
|
+
} else {
|
223
|
+
//console.log("type=" + s[i].type);
|
224
|
+
}
|
225
|
+
}
|
226
|
+
$ws.send("setting:" + JSON.stringify(json_data));
|
227
|
+
});
|
228
|
+
$(this).dialog("close");
|
229
|
+
},
|
230
|
+
"Cancel": function () { //Cancelボタン
|
231
|
+
$(this).dialog("close");
|
232
|
+
}
|
233
|
+
}
|
234
|
+
});
|
64
235
|
});
|
65
236
|
}
|
66
237
|
|
@@ -72,58 +243,62 @@ function get_dirname(path) {
|
|
72
243
|
return result.replace(/\//g, "\\");
|
73
244
|
}
|
74
245
|
|
75
|
-
function select_file(id) {
|
76
|
-
var file = $("#" + id).val();
|
77
|
-
var dir = get_dirname(file);
|
78
|
-
if (dir != "") {
|
79
|
-
dir = dir + "\\*.*";
|
80
|
-
} else {
|
81
|
-
dir = "c:\\*.*";
|
82
|
-
}
|
83
|
-
var path = "";
|
84
|
-
//alert(dir);
|
85
|
-
//path = HtmlDlgHelper.openfiledlg(dir,"*.db","database(*.db)|*.db|all(*.*)|*.*|Text file(*.txt)|*.txt|");
|
86
|
-
path = HtmlDlgHelper.openfiledlg(dir, "", "all(*.*)|*.*|Text file(*.txt)|*.txt|");
|
87
|
-
$("#" + id).val(path);
|
88
|
-
return (path);
|
89
|
-
}
|
90
|
-
|
91
246
|
function dispFile() {
|
92
247
|
var fName = $("#upFile").val();
|
93
248
|
alert('選択したファイルの値は' + fName + 'です');
|
94
249
|
}
|
95
250
|
|
251
|
+
function openFile(file) {
|
252
|
+
$ws.send("openfile:" + file);
|
253
|
+
}
|
254
|
+
|
96
255
|
// 起動時の処理
|
97
256
|
$(document).ready(function () {
|
98
257
|
// サーバに接続
|
99
|
-
server_connect("ws://localhost:
|
258
|
+
server_connect("ws://localhost:54068/wsserver")
|
100
259
|
// ウインドウサイズ
|
101
|
-
var width =
|
102
|
-
var height =
|
260
|
+
var width = 800;
|
261
|
+
var height = 600;
|
262
|
+
$(window).resize(function() {
|
263
|
+
$(".outarea").height( $(window).height() - 250 );
|
264
|
+
});
|
103
265
|
// ウインドウの位置
|
104
266
|
$(function () {
|
105
267
|
window.resizeTo(width, height);
|
106
268
|
window.moveTo((window.screen.width / 2) - (width / 2), (screen.height / 2) - (height / 2));
|
107
269
|
//window.moveTo(0,0);
|
270
|
+
$(".outarea").height( $(window).height() - 250 );
|
108
271
|
});
|
109
272
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
273
|
+
$('.outarea').scroll(function () {
|
274
|
+
var h = $('.outarea').get(0).scrollHeight - $('.outarea').innerHeight();
|
275
|
+
//console.log("scrollEnd=" + Math.abs($('.outarea').scrollTop() - h));
|
276
|
+
if (Math.abs($('.outarea').scrollTop() - h) < 30) {
|
277
|
+
// 最後までスクロールしている
|
278
|
+
// 自動スクロールON
|
279
|
+
$auto_scroll = true;
|
280
|
+
} else {
|
281
|
+
// 自動スクロールOFF
|
282
|
+
$auto_scroll = false;
|
283
|
+
}
|
284
|
+
//console.log("auto_scroll=" + $auto_scroll);
|
285
|
+
});
|
116
286
|
|
117
287
|
// ハンドラ登録
|
118
|
-
$("#
|
119
|
-
|
288
|
+
$("#stop").click(function () {
|
289
|
+
send_message("stop");
|
120
290
|
});
|
291
|
+
|
121
292
|
$("#exec").click(function () {
|
293
|
+
$('#log').empty();
|
122
294
|
send_message("exec:" + $("#upFile").val());
|
123
295
|
});
|
124
|
-
|
125
|
-
|
126
|
-
|
296
|
+
|
297
|
+
select_file_dialog("search_str", "file", "dialog1", "select_file", "upFile");
|
298
|
+
|
299
|
+
select_file_dialog("search_str2", "dir", "dialog2", "select_dir", "upDir");
|
300
|
+
|
301
|
+
setting_dialog("setting", "setting_dialog", "config/setting.json");
|
127
302
|
|
128
303
|
});
|
129
304
|
|
@@ -1,15 +1,18 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
|
-
|
3
|
-
def initialize
|
4
|
-
@aboet = false
|
5
|
-
end
|
2
|
+
require "server_app_base.rb"
|
6
3
|
|
7
|
-
|
4
|
+
class MyApp < AppMainBase
|
5
|
+
def start(argv)
|
6
|
+
super
|
8
7
|
begin
|
9
8
|
@abort = false
|
10
|
-
puts
|
9
|
+
puts argv
|
10
|
+
argv.each do |v|
|
11
|
+
yield v if block_given?
|
12
|
+
end
|
11
13
|
while true
|
12
14
|
yield Time.now.to_s if block_given?
|
15
|
+
yield @config["name1"]
|
13
16
|
sleep 1
|
14
17
|
break if @abort
|
15
18
|
end
|
@@ -20,6 +23,6 @@ class AppMain
|
|
20
23
|
end
|
21
24
|
|
22
25
|
def stop()
|
23
|
-
|
26
|
+
super
|
24
27
|
end
|
25
28
|
end
|
data/lib/template/server.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "json"
|
2
|
+
require "kconv"
|
3
3
|
|
4
4
|
class Search < Sinatra::Base
|
5
5
|
helpers Sinatra::Streaming
|
6
|
-
get
|
6
|
+
get "" do
|
7
7
|
q_hash = {}
|
8
8
|
puts request.query_string
|
9
9
|
request.query_string.split("&").each do |q|
|
@@ -14,27 +14,45 @@ class Search < Sinatra::Base
|
|
14
14
|
q_hash[work[0]] = ""
|
15
15
|
end
|
16
16
|
end
|
17
|
-
str = q_hash["path"].gsub(/\\/,"/")
|
17
|
+
str = q_hash["path"].gsub(/\\/, "/")
|
18
18
|
puts "str=#{str}"
|
19
|
+
kind = q_hash["kind"].gsub(/\\/, "/")
|
20
|
+
puts "kind=#{kind}"
|
19
21
|
res = []
|
20
22
|
str = str.gsub(/\\/, "/")
|
21
23
|
dir = File.dirname(str)
|
22
|
-
dir = "c:/" if dir == nil
|
23
24
|
file = File.basename(str)
|
24
|
-
|
25
|
+
puts "dir=#{dir}"
|
26
|
+
puts "file=#{file}"
|
27
|
+
|
28
|
+
kernel = Facter.value(:kernel)
|
29
|
+
if kernel == "windows"
|
30
|
+
dir = "c:/" if dir == nil
|
31
|
+
dir = "c:/" if dir == "/"
|
32
|
+
elsif kernel == "Linux"
|
33
|
+
dir = "/" if dir == nil
|
34
|
+
else
|
35
|
+
dir = "c:/" if dir == nil
|
36
|
+
dir = "c:/" if dir == "/"
|
37
|
+
end
|
38
|
+
|
25
39
|
path = "#{dir}/#{file}"
|
26
|
-
if File.
|
40
|
+
if File.directory?(path)
|
27
41
|
path = path + "/*"
|
28
42
|
else
|
29
43
|
path = path + "*"
|
30
44
|
end
|
45
|
+
path.gsub!(/[\/]+/, "/")
|
31
46
|
puts path
|
32
|
-
Dir.glob(path).each do |file|
|
47
|
+
Dir.glob(path, File::FNM_DOTMATCH).each do |file|
|
33
48
|
data = {}
|
49
|
+
next if File.basename(file) == "."
|
50
|
+
next if kind == "dir" and !File.directory?(file)
|
34
51
|
data["label"] = File.basename(file)
|
35
|
-
data["
|
52
|
+
data["label"] += "/" if (File.directory?(file))
|
53
|
+
data["value"] = File.expand_path(file)
|
36
54
|
res.push data
|
37
55
|
end
|
38
|
-
JSON.generate res
|
56
|
+
JSON.generate res.sort { |a, b| a["value"] <=> b["value"] }
|
39
57
|
end
|
40
58
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
class AppMainBase
|
3
|
+
def initialize
|
4
|
+
@config = nil
|
5
|
+
@aboet = false
|
6
|
+
@exec = false
|
7
|
+
@suspend = false
|
8
|
+
end
|
9
|
+
|
10
|
+
def set_config(config)
|
11
|
+
@config = config
|
12
|
+
end
|
13
|
+
|
14
|
+
def start(argv)
|
15
|
+
@exec = true
|
16
|
+
end
|
17
|
+
|
18
|
+
def stop()
|
19
|
+
@abort = true
|
20
|
+
@exec = false
|
21
|
+
end
|
22
|
+
|
23
|
+
def suspend()
|
24
|
+
@suspend = true
|
25
|
+
end
|
26
|
+
|
27
|
+
def resume()
|
28
|
+
@suspend = false
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
require "app_load.rb"
|
data/lib/template/start.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
1
2
|
# -*- coding: utf-8 -*-
|
2
3
|
$LOAD_PATH << File.dirname(File.expand_path(__FILE__))
|
3
4
|
|
@@ -22,19 +23,19 @@ port = get_unused_port
|
|
22
23
|
puts "port=#{port}"
|
23
24
|
|
24
25
|
# config.ruの編集
|
25
|
-
buf = File.
|
26
|
+
buf = File.binread("config.ru").toutf8
|
26
27
|
buf.gsub!(/port [0-9]+/, "port #{port}")
|
27
|
-
File.
|
28
|
+
File.binwrite("config.ru", buf)
|
28
29
|
|
29
30
|
# main.jsの編集
|
30
|
-
buf = File.
|
31
|
+
buf = File.binread("js/main.js").toutf8
|
31
32
|
buf.gsub!(/localhost:[0-9]+\//, "localhost:#{port}/")
|
32
|
-
File.
|
33
|
+
File.binwrite("js/main.js", buf)
|
33
34
|
|
34
35
|
# index.htaの編集
|
35
|
-
buf = File.
|
36
|
+
buf = File.binread("index.html").toutf8
|
36
37
|
buf.gsub!(/localhost:[0-9]+\//, "localhost:#{port}/")
|
37
|
-
File.
|
38
|
+
File.binwrite("index.html", buf)
|
38
39
|
|
39
40
|
Thread.start {
|
40
41
|
puts "start browser"
|
@@ -49,7 +50,6 @@ Thread.start {
|
|
49
50
|
else
|
50
51
|
browser = json["chrome_win"]
|
51
52
|
end
|
52
|
-
#browser = "\"C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe\" -app=http://localhost:#{port}"
|
53
53
|
browser += " -app=http://localhost:#{port}"
|
54
54
|
puts browser
|
55
55
|
system browser
|
data/lib/template/wsserver.rb
CHANGED
@@ -1,8 +1,19 @@
|
|
1
|
-
require "./
|
2
|
-
|
1
|
+
require "./server_app_base"
|
2
|
+
require "json"
|
3
|
+
require "cgi"
|
4
|
+
|
5
|
+
def config_json_hash(json)
|
6
|
+
config = {}
|
7
|
+
json.each do |j|
|
8
|
+
config[j["name"]] = j["value"]
|
9
|
+
end
|
10
|
+
return config
|
11
|
+
end
|
3
12
|
|
4
13
|
class WsServer < Sinatra::Base
|
5
14
|
$ws_list = []
|
15
|
+
json_config = nil
|
16
|
+
exec_thread = nil
|
6
17
|
get "" do
|
7
18
|
if !request.websocket?
|
8
19
|
"no supported"
|
@@ -15,16 +26,63 @@ class WsServer < Sinatra::Base
|
|
15
26
|
ws.onmessage do |msg|
|
16
27
|
puts msg
|
17
28
|
if msg =~ /^exec:/
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
29
|
+
if exec_thread == nil
|
30
|
+
json = JSON.parse(File.read("config/setting.json"))
|
31
|
+
json_config = config_json_hash(json)
|
32
|
+
$app.set_config(json_config)
|
33
|
+
argv = msg.gsub(/^exec:/, "")
|
34
|
+
exec_thread = Thread.new {
|
35
|
+
begin
|
36
|
+
$app.start(argv.split(",")) do |out|
|
37
|
+
ws.send(out)
|
38
|
+
end
|
39
|
+
ws.send("app_end:normal")
|
40
|
+
rescue
|
41
|
+
puts $!
|
42
|
+
puts $@
|
43
|
+
puts "app_end:err"
|
44
|
+
ws.send("app_end:error")
|
45
|
+
ensure
|
46
|
+
puts "exit thread"
|
47
|
+
exec_thread = nil
|
48
|
+
end
|
49
|
+
}
|
50
|
+
else
|
51
|
+
puts "app_end:err"
|
52
|
+
ws.send("app_end:error")
|
53
|
+
end
|
24
54
|
end
|
25
55
|
if msg =~ /^stop/
|
26
|
-
|
56
|
+
if exec_thread
|
57
|
+
$app.stop
|
58
|
+
end
|
59
|
+
end
|
60
|
+
if msg =~ /^suspend/
|
61
|
+
if exec_thread
|
62
|
+
$app.suspend
|
63
|
+
end
|
27
64
|
end
|
65
|
+
if msg =~ /^resume/
|
66
|
+
if exec_thread
|
67
|
+
$app.resume
|
68
|
+
end
|
69
|
+
end
|
70
|
+
if msg =~ /^setting:/
|
71
|
+
json_string = msg.gsub(/^setting:/, "")
|
72
|
+
json = JSON.parse(json_string)
|
73
|
+
File.open("config/setting.json", "w") do |w|
|
74
|
+
w.puts JSON.pretty_generate(json)
|
75
|
+
end
|
76
|
+
json_config = config_json_hash(json)
|
77
|
+
$app.set_config(json_config)
|
78
|
+
end
|
79
|
+
if msg =~ /^openfile:/
|
80
|
+
file = msg.gsub(/^openfile:/, "")
|
81
|
+
Thread.new {
|
82
|
+
system "#{json_config["editor"]} #{CGI.unescapeHTML(file)}"
|
83
|
+
}
|
84
|
+
end
|
85
|
+
|
28
86
|
if msg == "exit"
|
29
87
|
unless ENV["OCRA"] == "true"
|
30
88
|
halt
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: browser_app_base
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- masataka kuwayama
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-09-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sinatra
|
@@ -104,6 +104,7 @@ extra_rdoc_files: []
|
|
104
104
|
files:
|
105
105
|
- ".gitignore"
|
106
106
|
- ".rspec"
|
107
|
+
- ".vscode/launch.json"
|
107
108
|
- Gemfile
|
108
109
|
- LICENSE.txt
|
109
110
|
- README.md
|
@@ -112,13 +113,16 @@ files:
|
|
112
113
|
- browser_app_base.gemspec
|
113
114
|
- lib/browser_app_base.rb
|
114
115
|
- lib/browser_app_base/version.rb
|
116
|
+
- lib/template/app_load.rb
|
115
117
|
- lib/template/config.ru
|
116
118
|
- lib/template/config/browser.json
|
119
|
+
- lib/template/config/setting.json
|
117
120
|
- lib/template/css/index.css
|
118
121
|
- lib/template/index.html
|
119
122
|
- lib/template/js/main.js
|
123
|
+
- lib/template/my_app_sample.rb
|
120
124
|
- lib/template/server.rb
|
121
|
-
- lib/template/
|
125
|
+
- lib/template/server_app_base.rb
|
122
126
|
- lib/template/start.rb
|
123
127
|
- lib/template/wsserver.rb
|
124
128
|
homepage: https://github.com/kuwayama1971/BrowserAppBase
|