browser_app_base 0.0.6 → 0.1.0
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 +8 -2
- data/README.md +44 -2
- data/bin/start_sample.rb +25 -0
- data/lib/browser_app_base/version.rb +1 -1
- data/lib/browser_app_base.rb +12 -7
- data/lib/template/config/setting.json +2 -2
- data/lib/template/config.ru +30 -3
- data/lib/template/css/index.css +38 -18
- data/lib/template/history/history.json +0 -0
- data/lib/template/{index.html → html/index.html} +10 -7
- data/lib/template/html/test.html +85 -0
- data/lib/template/js/main.js +85 -10
- data/lib/template/my_app_sample.rb +8 -0
- data/lib/template/server_app_base.rb +27 -0
- data/lib/template/start.rb +86 -21
- data/lib/template/wsserver.rb +52 -20
- 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: c449614e4619060aa9e9f5799bc67822e61c1f603ff099914aff5e60593828dd
|
4
|
+
data.tar.gz: c146b0df93c05a64dceb9d6987895635bef0d733f9421581aa421c51d7077fd9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ed31b5268858c2ac45a01f20924cfe569c0f360797bfad8650a37cf07eff9452b229dbc30ecd0b3200ac5ebcbddc20fcca8f485d4a49440573ee0c6c6a6b7cd2
|
7
|
+
data.tar.gz: 00fa73805f8d27f12464fea9bee92720c9303960890e23a02d804f060b6e1429f5b9b02c0dc58ff1bd0ae90ffd4f8ed38c918bdc45e843e203f68563dbce9009
|
data/.vscode/launch.json
CHANGED
@@ -5,10 +5,16 @@
|
|
5
5
|
"version": "0.2.0",
|
6
6
|
"configurations": [
|
7
7
|
{
|
8
|
-
"name": "Debug
|
8
|
+
"name": "Debug create_browser_app.rb",
|
9
9
|
"type": "Ruby",
|
10
10
|
"request": "launch",
|
11
|
-
"
|
11
|
+
"program": "${workspaceRoot}/bin/create_browser_app.rb"
|
12
|
+
},
|
13
|
+
{
|
14
|
+
"name": "Debug start.rb",
|
15
|
+
"type": "Ruby",
|
16
|
+
"request": "launch",
|
17
|
+
"cwd": "${workspaceRoot}/lib/template",
|
12
18
|
"program": "${workspaceRoot}/lib/template/start.rb"
|
13
19
|
}
|
14
20
|
]
|
data/README.md
CHANGED
@@ -58,8 +58,50 @@ ui application sample
|
|
58
58
|
|
59
59
|
## Start application
|
60
60
|
|
61
|
-
|
62
|
-
|
61
|
+
```shell
|
62
|
+
$ /tmp/test/bin/start_my_app.rb
|
63
|
+
```
|
64
|
+
|
65
|
+
## browser setting
|
66
|
+
|
67
|
+
config/browser.json
|
68
|
+
Set the path for your Windows or Linux Chrome browser
|
69
|
+
|
70
|
+
```json
|
71
|
+
{
|
72
|
+
"chrome_win": "start chrome",
|
73
|
+
"chrome_linux": "/bin/google-chrome"
|
74
|
+
}
|
75
|
+
```
|
76
|
+
|
77
|
+
## Send a message from your browser application to your ruby application
|
78
|
+
|
79
|
+
Use the send_message function
|
80
|
+
|
81
|
+
main.js sample
|
82
|
+
```javascript
|
83
|
+
$("#exec").click(function () {
|
84
|
+
send_message("exec:" + $("#upFile").val());
|
85
|
+
});
|
86
|
+
|
87
|
+
```
|
88
|
+
|
89
|
+
## Send a message from the ruby application to the browser application
|
90
|
+
|
91
|
+
Use the app_send function
|
92
|
+
|
93
|
+
my_app_sample.rb sample
|
94
|
+
```ruby
|
95
|
+
class MyApp < AppMainBase
|
96
|
+
def start(argv)
|
97
|
+
# popup message
|
98
|
+
app_send("popup:message string")
|
99
|
+
|
100
|
+
# log message
|
101
|
+
yield "log message"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
```
|
63
105
|
|
64
106
|
## Development
|
65
107
|
|
data/bin/start_sample.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "fileutils"
|
4
|
+
require "facter"
|
5
|
+
require "tmpdir"
|
6
|
+
|
7
|
+
# tmpdirディレクトリにコピー
|
8
|
+
dir = File.dirname(File.expand_path(__FILE__)) + "/../"
|
9
|
+
Dir.mktmpdir { |tmpdir|
|
10
|
+
puts tmpdir
|
11
|
+
Dir.glob("#{dir}/lib/*") do |f|
|
12
|
+
puts "#{f} => #{tmpdir}"
|
13
|
+
FileUtils.cp_r f, "#{tmpdir}"
|
14
|
+
end
|
15
|
+
|
16
|
+
FileUtils.cd "#{tmpdir}"
|
17
|
+
kernel = Facter.value(:kernel)
|
18
|
+
if kernel == "windows"
|
19
|
+
system "rubyw ./start.rb"
|
20
|
+
elsif kernel == "Linux"
|
21
|
+
system "ruby ./start.rb"
|
22
|
+
else
|
23
|
+
system "ruby ./start.rb"
|
24
|
+
end
|
25
|
+
}
|
data/lib/browser_app_base.rb
CHANGED
@@ -37,28 +37,33 @@ module BrowserAppBase
|
|
37
37
|
puts "create application base #{dir}"
|
38
38
|
|
39
39
|
FileUtils.mkdir_p dir
|
40
|
+
FileUtils.mkdir_p dir + "/lib/"
|
41
|
+
FileUtils.mkdir_p dir + "/bin/"
|
40
42
|
|
41
|
-
path = File.dirname(File.expand_path(__FILE__))
|
42
|
-
Dir.glob("#{path}/template/*") do |f|
|
43
|
-
puts "#{f} => #{dir}"
|
44
|
-
FileUtils.cp_r f, "#{dir}/"
|
43
|
+
path = File.dirname(File.expand_path(__FILE__)) + "/../"
|
44
|
+
Dir.glob("#{path}/lib/template/*") do |f|
|
45
|
+
puts "#{f} => #{dir}/lib"
|
46
|
+
FileUtils.cp_r f, "#{dir}/lib"
|
45
47
|
end
|
46
48
|
|
47
49
|
if app
|
48
50
|
app_file = get_app_file(app)
|
49
51
|
|
52
|
+
puts "#{path}/bin/start_sample.rb #{dir}/bin/start_#{app_file}"
|
53
|
+
FileUtils.cp_r "#{path}/bin/start_sample.rb", "#{dir}/bin/start_#{app_file}"
|
54
|
+
|
50
55
|
load_app = <<"EOS"
|
51
56
|
require '#{app_file}'
|
52
57
|
$app = #{get_app_name(app)}.new
|
53
58
|
EOS
|
54
59
|
|
55
|
-
File.open("#{dir}/app_load.rb", "w") do |f|
|
60
|
+
File.open("#{dir}/lib/app_load.rb", "w") do |f|
|
56
61
|
f.write load_app
|
57
62
|
end
|
58
63
|
|
59
64
|
puts "create #{app_file}"
|
60
|
-
new_file = "#{dir}/#{app_file}"
|
61
|
-
FileUtils.cp("#{dir}/my_app_sample.rb", new_file)
|
65
|
+
new_file = "#{dir}/lib/#{app_file}"
|
66
|
+
FileUtils.cp("#{dir}/lib/my_app_sample.rb", new_file)
|
62
67
|
buf = File.binread(new_file)
|
63
68
|
File.binwrite(new_file, buf.gsub(/MyApp/, get_app_name(app)))
|
64
69
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
[
|
2
2
|
{
|
3
3
|
"name": "name1",
|
4
|
-
"value": "value1",
|
4
|
+
"value": "value1 2 3 4",
|
5
5
|
"type": "input",
|
6
6
|
"select": "",
|
7
7
|
"description": "設定項目1"
|
@@ -15,7 +15,7 @@
|
|
15
15
|
},
|
16
16
|
{
|
17
17
|
"name": "name3",
|
18
|
-
"value": "
|
18
|
+
"value": "2",
|
19
19
|
"type": "select",
|
20
20
|
"select": [
|
21
21
|
"1",
|
data/lib/template/config.ru
CHANGED
@@ -8,8 +8,20 @@ require "json"
|
|
8
8
|
require "./server"
|
9
9
|
require "./wsserver"
|
10
10
|
|
11
|
+
temp_dir = ENV["temp"]
|
12
|
+
temp_dir = "/tmp" if temp_dir == nil
|
13
|
+
puts "temp_dir=#{temp_dir}"
|
14
|
+
access_log = File.new("#{temp_dir}/logs/sinatra.log", "a+")
|
15
|
+
access_log.sync = true
|
16
|
+
use Rack::CommonLogger, access_log
|
17
|
+
|
11
18
|
get "/" do
|
12
|
-
File.read("index.html")
|
19
|
+
File.read("html/index.html")
|
20
|
+
end
|
21
|
+
|
22
|
+
get "*.html" do |file|
|
23
|
+
content_type "text/html", :charset => "utf-8"
|
24
|
+
File.read "./html/#{file}.html"
|
13
25
|
end
|
14
26
|
|
15
27
|
get "/css/:name.css" do
|
@@ -30,6 +42,21 @@ get "/config/*.*" do |file, ext|
|
|
30
42
|
File.read "config/#{file}.#{ext}"
|
31
43
|
end
|
32
44
|
|
45
|
+
post "/history/*.*" do |file, ext|
|
46
|
+
content_type "text/json", :charset => "utf-8"
|
47
|
+
puts "#{file}.#{ext}"
|
48
|
+
p = params[:param1]
|
49
|
+
buf = File.read "history/#{file}.#{ext}"
|
50
|
+
data = eval(buf)
|
51
|
+
if data != nil
|
52
|
+
if p != ""
|
53
|
+
JSON.generate data.find_all { |d| d =~ Regexp.new(p) }
|
54
|
+
else
|
55
|
+
JSON.generate data
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
33
60
|
get "/open_dialog" do
|
34
61
|
dialog_html = <<'EOS'
|
35
62
|
<!DOCTYPE html>
|
@@ -65,7 +92,7 @@ end
|
|
65
92
|
|
66
93
|
configure do
|
67
94
|
set :DoNotReverseLookup, true
|
68
|
-
set :logging,
|
95
|
+
set :logging, true
|
69
96
|
set :default_encoding, "utf-8"
|
70
97
|
set :server, :thin
|
71
98
|
|
@@ -74,6 +101,6 @@ configure do
|
|
74
101
|
|
75
102
|
end
|
76
103
|
|
77
|
-
#\ --port
|
104
|
+
#\ --port 36809
|
78
105
|
|
79
106
|
run Sinatra::Application
|
data/lib/template/css/index.css
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
body {
|
2
2
|
color: #000000;
|
3
|
-
|
3
|
+
background-color: #cac3ec4f;
|
4
4
|
overflow: hidden;
|
5
5
|
font-size: 12px;
|
6
6
|
}
|
@@ -8,9 +8,12 @@ body {
|
|
8
8
|
hr {
|
9
9
|
color: #ffffff;
|
10
10
|
background-color: #000000;
|
11
|
-
height: 1px;
|
12
|
-
|
13
|
-
border
|
11
|
+
height: 1px;
|
12
|
+
/* 線の太さ */
|
13
|
+
border: 1px;
|
14
|
+
/* 枠の太さ */
|
15
|
+
border-style: solid;
|
16
|
+
/* 枠の種類 */
|
14
17
|
}
|
15
18
|
|
16
19
|
.error {
|
@@ -19,7 +22,7 @@ hr {
|
|
19
22
|
|
20
23
|
.outarea {
|
21
24
|
background-color: #FFFFFF;
|
22
|
-
margin: 5px;
|
25
|
+
margin: 5px;
|
23
26
|
padding: 5px;
|
24
27
|
width: 95vw;
|
25
28
|
height: 50vh;
|
@@ -28,15 +31,15 @@ hr {
|
|
28
31
|
|
29
32
|
.inarea {
|
30
33
|
border: thin solid #000000;
|
31
|
-
margin: 5px;
|
34
|
+
margin: 5px;
|
32
35
|
padding: 5px;
|
33
36
|
width: 95%;
|
34
37
|
}
|
35
38
|
|
36
39
|
input.long {
|
37
40
|
width: 90%;
|
38
|
-
|
39
|
-
margin: 5px;
|
41
|
+
background-color: #FAFAFA;
|
42
|
+
margin: 5px;
|
40
43
|
padding: 5px;
|
41
44
|
}
|
42
45
|
|
@@ -63,12 +66,21 @@ textarea.long {
|
|
63
66
|
color: black;
|
64
67
|
}
|
65
68
|
|
69
|
+
.ui-autocomplete.ui-front {
|
70
|
+
max-height: 250px;
|
71
|
+
overflow-y: auto;
|
72
|
+
/* prevent horizontal scrollbar */
|
73
|
+
overflow-x: hidden;
|
74
|
+
/* add padding to account for vertical scrollbar */
|
75
|
+
z-index: 1000 !important;
|
76
|
+
}
|
77
|
+
|
66
78
|
.ui-dialog {
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
79
|
+
position: absolute;
|
80
|
+
top: 0;
|
81
|
+
left: 0;
|
82
|
+
padding: .2em;
|
83
|
+
outline: 0;
|
72
84
|
}
|
73
85
|
|
74
86
|
.long {
|
@@ -77,28 +89,36 @@ textarea.long {
|
|
77
89
|
|
78
90
|
#setting_dialog {
|
79
91
|
color: #796fe9;
|
80
|
-
|
92
|
+
background-color: #000000;
|
81
93
|
}
|
82
94
|
|
83
95
|
.setting_name {
|
84
96
|
width: 200px;
|
85
97
|
color: #796fe9;
|
86
|
-
|
98
|
+
background-color: #000000;
|
87
99
|
}
|
88
100
|
|
89
101
|
.setting_value {
|
90
102
|
width: 300px;
|
91
103
|
color: #796fe9;
|
92
|
-
|
104
|
+
background-color: #000000;
|
93
105
|
}
|
94
106
|
|
95
107
|
.setting_checkbox {
|
96
108
|
color: #796fe9;
|
97
|
-
|
109
|
+
background-color: #000000;
|
98
110
|
}
|
99
111
|
|
100
112
|
ul.log {
|
101
|
-
list-style-type: decimal;
|
113
|
+
list-style-type: decimal;
|
102
114
|
font-size: 12px;
|
103
115
|
color: #5d0a94;
|
116
|
+
}
|
117
|
+
|
118
|
+
input[type="search"] {
|
119
|
+
-webkit-appearance: searchfield;
|
120
|
+
}
|
121
|
+
|
122
|
+
input[type="search"]::-webkit-search-cancel-button {
|
123
|
+
-webkit-appearance: searchfield-cancel-button;
|
104
124
|
}
|
File without changes
|
@@ -11,12 +11,15 @@
|
|
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:36809/js/main.js"></script>
|
15
|
+
<link rel="stylesheet" href="http://localhost:36809/css/index.css" type="text/css">
|
16
16
|
</head>
|
17
17
|
|
18
18
|
<body>
|
19
|
-
<
|
19
|
+
<div id="msg_dialog" style="display:none;">
|
20
|
+
<div id="msg_text">message</div>
|
21
|
+
</div>
|
22
|
+
<h4>RubyAppBase</h4>
|
20
23
|
<hr>
|
21
24
|
<table>
|
22
25
|
<tr>
|
@@ -36,21 +39,21 @@
|
|
36
39
|
</table>
|
37
40
|
|
38
41
|
<div id="dialog1" style="display:none;">
|
39
|
-
<input class="inarea" type="
|
42
|
+
<input class="inarea" type="search" name="search_str" id="search_str">
|
40
43
|
</div>
|
41
44
|
<table>
|
42
45
|
<tr>
|
43
|
-
<td class="long"><input class="inarea" type="
|
46
|
+
<td class="long"><input class="inarea" type="search" id="upFile" name="upFile"></td>
|
44
47
|
<td><input type="button" id="select_file" value="ファイル選択" /></td>
|
45
48
|
</tr>
|
46
49
|
</table>
|
47
50
|
|
48
51
|
<div id="dialog2" style="display:none;">
|
49
|
-
<input class="inarea" type="
|
52
|
+
<input class="inarea" type="search" name="search_str2" id="search_str2">
|
50
53
|
</div>
|
51
54
|
<table>
|
52
55
|
<tr>
|
53
|
-
<td class="long"><input class="inarea" type="
|
56
|
+
<td class="long"><input class="inarea" type="search" id="upDir" name="upDir"></td>
|
54
57
|
<td><input type="button" id="select_dir" value="フォルダ選択" /></td>
|
55
58
|
</tr>
|
56
59
|
</table>
|
@@ -0,0 +1,85 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html lang="ja">
|
3
|
+
|
4
|
+
<head>
|
5
|
+
<meta charset="UTF-8">
|
6
|
+
<title>modalをcomponentで作る</title>
|
7
|
+
</head>
|
8
|
+
|
9
|
+
<style>
|
10
|
+
#content {
|
11
|
+
z-index: 10;
|
12
|
+
width: 50%;
|
13
|
+
padding: 1em;
|
14
|
+
background: #fff;
|
15
|
+
}
|
16
|
+
|
17
|
+
#overlay {
|
18
|
+
/* 要素を重ねた時の順番 */
|
19
|
+
|
20
|
+
z-index: 1;
|
21
|
+
|
22
|
+
/* 画面全体を覆う設定 */
|
23
|
+
position: fixed;
|
24
|
+
top: 0;
|
25
|
+
left: 0;
|
26
|
+
width: 100%;
|
27
|
+
height: 100%;
|
28
|
+
background-color: rgba(0, 0, 0, 0.5);
|
29
|
+
|
30
|
+
/* 画面の中央に要素を表示させる設定 */
|
31
|
+
display: flex;
|
32
|
+
align-items: center;
|
33
|
+
justify-content: center;
|
34
|
+
|
35
|
+
}
|
36
|
+
</style>
|
37
|
+
|
38
|
+
<body>
|
39
|
+
<div id="app">
|
40
|
+
|
41
|
+
<button v-on:click="openModal">Click</button>
|
42
|
+
|
43
|
+
<open-modal v-show="showContent" v-on:from-child="closeModal">slotからモーダルウィンドウへ</open-modal>
|
44
|
+
|
45
|
+
</div>
|
46
|
+
|
47
|
+
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
|
48
|
+
<script>
|
49
|
+
Vue.component('open-modal', {
|
50
|
+
template: `
|
51
|
+
<div id="overlay" v-on:click="clickEvent">
|
52
|
+
<div id="content" v-on:click="stopEvent">
|
53
|
+
<p><slot></slot></p>
|
54
|
+
<button v-on:click="clickEvent">close</button>
|
55
|
+
</div>
|
56
|
+
</div>
|
57
|
+
`,
|
58
|
+
methods: {
|
59
|
+
clickEvent: function () {
|
60
|
+
this.$emit('from-child')
|
61
|
+
},
|
62
|
+
stopEvent: function () {
|
63
|
+
event.stopPropagation()
|
64
|
+
}
|
65
|
+
}
|
66
|
+
})
|
67
|
+
|
68
|
+
new Vue({
|
69
|
+
el: '#app',
|
70
|
+
data: {
|
71
|
+
showContent: false
|
72
|
+
},
|
73
|
+
methods: {
|
74
|
+
openModal: function () {
|
75
|
+
this.showContent = true
|
76
|
+
},
|
77
|
+
closeModal: function () {
|
78
|
+
this.showContent = false
|
79
|
+
},
|
80
|
+
}
|
81
|
+
})
|
82
|
+
</script>
|
83
|
+
</body>
|
84
|
+
|
85
|
+
</html>
|
data/lib/template/js/main.js
CHANGED
@@ -3,8 +3,38 @@
|
|
3
3
|
var $ws = null;
|
4
4
|
var $auto_scroll = true;
|
5
5
|
var dialog = null;
|
6
|
+
var dialog_timeout = null;
|
6
7
|
|
7
|
-
function open_dialog(msg) {
|
8
|
+
function open_dialog(msg, timeout = 0) {
|
9
|
+
console.log("msg=" + msg);
|
10
|
+
$("#msg_text").html(msg);
|
11
|
+
d = $("#msg_dialog").dialog({
|
12
|
+
modal: true
|
13
|
+
, show: "slide" //表示時のアニメーション
|
14
|
+
, hide: "slide" //閉じた時のアニメーション
|
15
|
+
, title: "Message" //ダイアログのタイトル
|
16
|
+
, width: 500 //ダイアログの横幅
|
17
|
+
, height: 300 //ダイアログの高さ
|
18
|
+
, resizable: true //リサイズ可
|
19
|
+
, closeOnEscape: false //[ESC]キーで閉じられなくする
|
20
|
+
, draggable: true //ダイアログの移動を可に
|
21
|
+
, buttons: {
|
22
|
+
"OK": function () { //Cancelボタン
|
23
|
+
if (dialog_timeout != null) {
|
24
|
+
clearTimeout(dialog_timeout);
|
25
|
+
}
|
26
|
+
$(this).dialog("close");
|
27
|
+
}
|
28
|
+
}
|
29
|
+
});
|
30
|
+
if (timeout != 0) {
|
31
|
+
dialog_timeout = setTimeout(function () {
|
32
|
+
d.dialog("close");
|
33
|
+
}, timeout);
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
function open_dialog_org(msg) {
|
8
38
|
var top = window.screenTop + 10;
|
9
39
|
var left = window.screenLeft + 10;
|
10
40
|
if (dialog != null) {
|
@@ -37,13 +67,18 @@ function server_connect(url) {
|
|
37
67
|
|
38
68
|
if (evt.data.match(/^startup:/)) {
|
39
69
|
file_name = evt.data.replace(/^startup:/, "");
|
40
|
-
//alert(file_name);
|
41
70
|
}
|
42
71
|
else if (evt.data.match(/^app_end:normal/)) {
|
43
72
|
open_dialog("終了しました");
|
44
73
|
}
|
74
|
+
else if (evt.data.match(/^app_end:stop/)) {
|
75
|
+
open_dialog("中止しました");
|
76
|
+
}
|
45
77
|
else if (evt.data.match(/^app_end:error/)) {
|
46
78
|
open_dialog("<font color='red'>エラーが発生しました</font>");
|
79
|
+
}
|
80
|
+
else if (evt.data.match(/^popup:/)) {
|
81
|
+
open_dialog(evt.data.replace(/^popup:/, ""), 3000);
|
47
82
|
} else {
|
48
83
|
var log = "<li>" + evt.data + "</li>";
|
49
84
|
$('#log').append(log);
|
@@ -80,7 +115,7 @@ function autocomp(id, file_kind) {
|
|
80
115
|
},
|
81
116
|
source: function (req, resp) {
|
82
117
|
$.ajax({
|
83
|
-
url: "http://localhost:
|
118
|
+
url: "http://localhost:36809/search?path=" + $("#" + id).val() + "&kind=" + file_kind,
|
84
119
|
type: "GET",
|
85
120
|
cache: false,
|
86
121
|
dataType: "json",
|
@@ -102,11 +137,44 @@ function autocomp(id, file_kind) {
|
|
102
137
|
});
|
103
138
|
}
|
104
139
|
|
140
|
+
function autocomp_history(id, file_name) {
|
141
|
+
$("#" + id).autocomplete({
|
142
|
+
autoFocus: true,
|
143
|
+
minLength: 0,
|
144
|
+
delay: 0,
|
145
|
+
select: function (event, ui) {
|
146
|
+
jQuery("#" + id).val(ui.item.value);
|
147
|
+
$(this).keydown();
|
148
|
+
},
|
149
|
+
source: function (req, resp) {
|
150
|
+
$.ajax({
|
151
|
+
url: "http://localhost:36809/history/" + file_name,
|
152
|
+
type: "POST",
|
153
|
+
cache: false,
|
154
|
+
dataType: "json",
|
155
|
+
data: {
|
156
|
+
param1: req.term
|
157
|
+
},
|
158
|
+
success: function (o) {
|
159
|
+
resp(o);
|
160
|
+
},
|
161
|
+
error: function (xhr, ts, err) {
|
162
|
+
resp(['']);
|
163
|
+
}
|
164
|
+
});
|
165
|
+
|
166
|
+
}
|
167
|
+
}).focus(function () {
|
168
|
+
$(this).keydown();
|
169
|
+
});
|
170
|
+
}
|
171
|
+
|
105
172
|
function select_file_dialog(search_id, file_kind, dialog_id, select_file, file_name) {
|
106
173
|
$("#" + select_file).click(function () {
|
107
174
|
autocomp(search_id, file_kind);
|
108
175
|
$(".ui-autocomplete").css("z-index", 1000);
|
109
|
-
$("#" +
|
176
|
+
console.log("name=" + $("#" + file_name).val());
|
177
|
+
$("#" + search_id).val($("#" + file_name).val());
|
110
178
|
$("#" + dialog_id).dialog({
|
111
179
|
modal: true
|
112
180
|
, show: "slide" //表示時のアニメーション
|
@@ -141,7 +209,7 @@ function setting_dialog(open_id, dialog_id, json_file) {
|
|
141
209
|
if (s[i].type == "input") {
|
142
210
|
var h = "<table><tr>"
|
143
211
|
+ "<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 + ">"
|
212
|
+
+ "<td><input class='setting_value' type='text' " + "id=" + s[i].name + "_value " + "value=" + "'" + s[i].value + "'" + ">"
|
145
213
|
+ "</td></tr></table>"
|
146
214
|
$("dl#wrap").append(h);
|
147
215
|
} else if (s[i].type == "checkbox") {
|
@@ -254,20 +322,25 @@ function openFile(file) {
|
|
254
322
|
|
255
323
|
// 起動時の処理
|
256
324
|
$(document).ready(function () {
|
257
|
-
|
258
|
-
|
325
|
+
|
326
|
+
window.onload = function (e) {
|
327
|
+
console.log("onload");
|
328
|
+
// サーバに接続
|
329
|
+
server_connect("ws://localhost:36809/wsserver")
|
330
|
+
}
|
331
|
+
|
259
332
|
// ウインドウサイズ
|
260
333
|
var width = 800;
|
261
334
|
var height = 600;
|
262
|
-
$(window).resize(function() {
|
263
|
-
$(".outarea").height(
|
335
|
+
$(window).resize(function () {
|
336
|
+
$(".outarea").height($(window).height() - 220);
|
264
337
|
});
|
265
338
|
// ウインドウの位置
|
266
339
|
$(function () {
|
267
340
|
window.resizeTo(width, height);
|
268
341
|
window.moveTo((window.screen.width / 2) - (width / 2), (screen.height / 2) - (height / 2));
|
269
342
|
//window.moveTo(0,0);
|
270
|
-
$(".outarea").height(
|
343
|
+
$(".outarea").height($(window).height() - 220);
|
271
344
|
});
|
272
345
|
|
273
346
|
$('.outarea').scroll(function () {
|
@@ -300,5 +373,7 @@ $(document).ready(function () {
|
|
300
373
|
|
301
374
|
setting_dialog("setting", "setting_dialog", "config/setting.json");
|
302
375
|
|
376
|
+
autocomp_history("upFile", "history.json")
|
377
|
+
|
303
378
|
});
|
304
379
|
|
@@ -10,8 +10,16 @@ class MyApp < AppMainBase
|
|
10
10
|
argv.each do |v|
|
11
11
|
yield v if block_given?
|
12
12
|
end
|
13
|
+
|
14
|
+
# Browserにメッセージ送信
|
15
|
+
app_send("popup:start app #{argv[0]}")
|
16
|
+
|
17
|
+
# 履歴の保存
|
18
|
+
add_history("history.json", argv[0])
|
19
|
+
|
13
20
|
while true
|
14
21
|
yield Time.now.to_s if block_given?
|
22
|
+
puts Time.now.to_s
|
15
23
|
yield @config["name1"]
|
16
24
|
sleep 1
|
17
25
|
break if @abort
|
@@ -5,6 +5,17 @@ class AppMainBase
|
|
5
5
|
@aboet = false
|
6
6
|
@exec = false
|
7
7
|
@suspend = false
|
8
|
+
@ws = nil
|
9
|
+
end
|
10
|
+
|
11
|
+
def app_send(str)
|
12
|
+
if @ws != nil
|
13
|
+
@ws.send(str)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def set_ws(ws)
|
18
|
+
@ws = ws
|
8
19
|
end
|
9
20
|
|
10
21
|
def set_config(config)
|
@@ -27,6 +38,22 @@ class AppMainBase
|
|
27
38
|
def resume()
|
28
39
|
@suspend = false
|
29
40
|
end
|
41
|
+
|
42
|
+
# 履歴の保存
|
43
|
+
def add_history(file, history_data, max = 10)
|
44
|
+
buf = File.read "history/#{file}"
|
45
|
+
data = eval(buf)
|
46
|
+
if data == nil
|
47
|
+
data = []
|
48
|
+
end
|
49
|
+
if history_data.to_s != ""
|
50
|
+
data.prepend history_data
|
51
|
+
end
|
52
|
+
data = data.uniq[0..max - 1]
|
53
|
+
File.open("history/#{file}", "w") do |f|
|
54
|
+
f.write JSON.pretty_generate data
|
55
|
+
end
|
56
|
+
end
|
30
57
|
end
|
31
58
|
|
32
59
|
require "app_load.rb"
|
data/lib/template/start.rb
CHANGED
@@ -10,6 +10,52 @@ require "kconv"
|
|
10
10
|
require "json"
|
11
11
|
require "facter"
|
12
12
|
|
13
|
+
# ログ出力
|
14
|
+
module Output
|
15
|
+
def self.console_and_file(output_file, stdout = true)
|
16
|
+
begin
|
17
|
+
defout = File.new(output_file, "a+")
|
18
|
+
rescue
|
19
|
+
puts $!
|
20
|
+
puts $@
|
21
|
+
return nil
|
22
|
+
end
|
23
|
+
class << defout
|
24
|
+
alias_method :write_org, :write
|
25
|
+
|
26
|
+
def initialize(stdout)
|
27
|
+
@stdout = false
|
28
|
+
end
|
29
|
+
|
30
|
+
attr_accessor :stdout
|
31
|
+
|
32
|
+
def puts(str)
|
33
|
+
STDOUT.write(str.to_s + "\n") if @stdout
|
34
|
+
self.write_org(str.to_s + "\n")
|
35
|
+
self.flush
|
36
|
+
end
|
37
|
+
|
38
|
+
def write(str)
|
39
|
+
STDOUT.write(str) if @stdout
|
40
|
+
self.write_org(str)
|
41
|
+
self.flush
|
42
|
+
end
|
43
|
+
end
|
44
|
+
$stdout = defout
|
45
|
+
$stdout.stdout = stdout
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# ディレクトリ移動
|
50
|
+
dir = File.dirname(File.expand_path(__FILE__))
|
51
|
+
FileUtils.cd dir
|
52
|
+
|
53
|
+
temp_dir = ENV["temp"]
|
54
|
+
temp_dir = "/tmp" if temp_dir == nil
|
55
|
+
puts "temp_dir=#{temp_dir}"
|
56
|
+
FileUtils.mkdir_p("#{temp_dir}/logs")
|
57
|
+
Output.console_and_file("#{temp_dir}/logs/app.log", true)
|
58
|
+
|
13
59
|
# 空きポートを取得
|
14
60
|
def get_unused_port
|
15
61
|
s = TCPServer.open(0)
|
@@ -33,26 +79,45 @@ buf.gsub!(/localhost:[0-9]+\//, "localhost:#{port}/")
|
|
33
79
|
File.binwrite("js/main.js", buf)
|
34
80
|
|
35
81
|
# index.htaの編集
|
36
|
-
buf = File.binread("index.html").toutf8
|
82
|
+
buf = File.binread("html/index.html").toutf8
|
37
83
|
buf.gsub!(/localhost:[0-9]+\//, "localhost:#{port}/")
|
38
|
-
File.binwrite("index.html", buf)
|
39
|
-
|
40
|
-
Thread.start {
|
41
|
-
puts "start browser"
|
42
|
-
json_file = File.dirname(File.expand_path(__FILE__)) + "/config/browser.json"
|
43
|
-
json = JSON.parse(File.read json_file)
|
44
|
-
puts json
|
45
|
-
kernel = Facter.value(:kernel)
|
46
|
-
if kernel == "windows"
|
47
|
-
browser = json["chrome_win"]
|
48
|
-
elsif kernel == "Linux"
|
49
|
-
browser = json["chrome_linux"]
|
50
|
-
else
|
51
|
-
browser = json["chrome_win"]
|
52
|
-
end
|
53
|
-
browser += " -app=http://localhost:#{port}"
|
54
|
-
puts browser
|
55
|
-
system browser
|
56
|
-
}
|
84
|
+
File.binwrite("html/index.html", buf)
|
57
85
|
|
58
|
-
|
86
|
+
begin
|
87
|
+
Thread.start {
|
88
|
+
puts "wait start web server"
|
89
|
+
while true
|
90
|
+
begin
|
91
|
+
s = TCPSocket.open("localhost", port)
|
92
|
+
s.close
|
93
|
+
break
|
94
|
+
rescue
|
95
|
+
puts $!
|
96
|
+
sleep 0.1
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
puts "start browser"
|
101
|
+
json_file = File.dirname(File.expand_path(__FILE__)) + "/config/browser.json"
|
102
|
+
json = JSON.parse(File.read json_file)
|
103
|
+
puts json
|
104
|
+
kernel = Facter.value(:kernel)
|
105
|
+
if kernel == "windows"
|
106
|
+
browser = json["chrome_win"]
|
107
|
+
elsif kernel == "Linux"
|
108
|
+
browser = json["chrome_linux"]
|
109
|
+
else
|
110
|
+
browser = json["chrome_win"]
|
111
|
+
end
|
112
|
+
browser += " -app=http://localhost:#{port}"
|
113
|
+
puts browser
|
114
|
+
system browser
|
115
|
+
}
|
116
|
+
|
117
|
+
# start web server
|
118
|
+
Rack::Server.start
|
119
|
+
rescue
|
120
|
+
puts $!
|
121
|
+
puts $@
|
122
|
+
exit
|
123
|
+
end
|
data/lib/template/wsserver.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require "./server_app_base"
|
2
2
|
require "json"
|
3
3
|
require "cgi"
|
4
|
+
require "thread"
|
4
5
|
|
5
6
|
def config_json_hash(json)
|
6
7
|
config = {}
|
@@ -10,8 +11,23 @@ def config_json_hash(json)
|
|
10
11
|
return config
|
11
12
|
end
|
12
13
|
|
14
|
+
$ws_exit_thread = nil
|
15
|
+
|
13
16
|
class WsServer < Sinatra::Base
|
14
|
-
|
17
|
+
def initialize
|
18
|
+
super
|
19
|
+
@ws_list = []
|
20
|
+
@ws_lock = Mutex.new
|
21
|
+
end
|
22
|
+
|
23
|
+
def ws_send(str)
|
24
|
+
@ws_lock.synchronize do
|
25
|
+
if @ws_list[0] != nil
|
26
|
+
@ws_list[0].send(str)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
15
31
|
json_config = nil
|
16
32
|
exec_thread = nil
|
17
33
|
get "" do
|
@@ -20,28 +36,38 @@ class WsServer < Sinatra::Base
|
|
20
36
|
else
|
21
37
|
request.websocket do |ws|
|
22
38
|
ws.onopen do
|
23
|
-
ws.
|
24
|
-
|
39
|
+
puts "ws.open"
|
40
|
+
@ws_lock.synchronize do
|
41
|
+
@ws_list << ws
|
42
|
+
$app.set_ws(ws)
|
43
|
+
pp "ws=#{ws}"
|
44
|
+
end
|
45
|
+
ws_send("startup:#{$startup_file}")
|
46
|
+
puts "ws_exit_thread=#{$ws_exit_thread}"
|
47
|
+
if $ws_exit_thread != nil
|
48
|
+
puts "ws_exit_thread kill"
|
49
|
+
Thread.kill $ws_exit_thread
|
50
|
+
end
|
25
51
|
end
|
26
52
|
ws.onmessage do |msg|
|
27
53
|
puts msg
|
54
|
+
json = JSON.parse(File.read("config/setting.json"))
|
55
|
+
json_config = config_json_hash(json)
|
56
|
+
$app.set_config(json_config)
|
28
57
|
if msg =~ /^exec:/
|
29
58
|
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
59
|
argv = msg.gsub(/^exec:/, "")
|
34
60
|
exec_thread = Thread.new {
|
35
61
|
begin
|
36
62
|
$app.start(argv.split(",")) do |out|
|
37
|
-
|
63
|
+
ws_send(out)
|
38
64
|
end
|
39
|
-
|
65
|
+
ws_send("app_end:normal")
|
40
66
|
rescue
|
41
67
|
puts $!
|
42
68
|
puts $@
|
43
69
|
puts "app_end:err"
|
44
|
-
|
70
|
+
ws_send("app_end:error")
|
45
71
|
ensure
|
46
72
|
puts "exit thread"
|
47
73
|
exec_thread = nil
|
@@ -49,11 +75,13 @@ class WsServer < Sinatra::Base
|
|
49
75
|
}
|
50
76
|
else
|
51
77
|
puts "app_end:err"
|
52
|
-
|
78
|
+
ws_send("app_end:error")
|
53
79
|
end
|
54
80
|
end
|
55
81
|
if msg =~ /^stop/
|
56
82
|
if exec_thread
|
83
|
+
Thread.kill exec_thread
|
84
|
+
ws_send("app_end:stop")
|
57
85
|
$app.stop
|
58
86
|
end
|
59
87
|
end
|
@@ -83,23 +111,27 @@ class WsServer < Sinatra::Base
|
|
83
111
|
}
|
84
112
|
end
|
85
113
|
|
114
|
+
# アプリケーション終了
|
86
115
|
if msg == "exit"
|
87
|
-
|
88
|
-
|
89
|
-
#exit
|
90
|
-
end
|
116
|
+
#halt
|
117
|
+
exit
|
91
118
|
end
|
92
119
|
end
|
120
|
+
|
121
|
+
# close websocket
|
93
122
|
ws.onclose do
|
94
123
|
puts "websocket closed"
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
124
|
+
@ws_lock.synchronize do
|
125
|
+
@ws_list.delete(ws)
|
126
|
+
end
|
127
|
+
puts @ws_list.size
|
128
|
+
if @ws_list.size == 0
|
129
|
+
$ws_exit_thread = Thread.start {
|
130
|
+
sleep 1
|
100
131
|
#halt
|
101
132
|
exit
|
102
|
-
|
133
|
+
}
|
134
|
+
puts "ws_exit_thread=#{$ws_exit_thread}"
|
103
135
|
end
|
104
136
|
end
|
105
137
|
end
|
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.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- masataka kuwayama
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-01-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sinatra
|
@@ -99,6 +99,7 @@ email:
|
|
99
99
|
- masataka.kuwayama@gmail.com
|
100
100
|
executables:
|
101
101
|
- create_browser_app.rb
|
102
|
+
- start_sample.rb
|
102
103
|
extensions: []
|
103
104
|
extra_rdoc_files: []
|
104
105
|
files:
|
@@ -110,6 +111,7 @@ files:
|
|
110
111
|
- README.md
|
111
112
|
- Rakefile
|
112
113
|
- bin/create_browser_app.rb
|
114
|
+
- bin/start_sample.rb
|
113
115
|
- browser_app_base.gemspec
|
114
116
|
- lib/browser_app_base.rb
|
115
117
|
- lib/browser_app_base/version.rb
|
@@ -118,7 +120,9 @@ files:
|
|
118
120
|
- lib/template/config/browser.json
|
119
121
|
- lib/template/config/setting.json
|
120
122
|
- lib/template/css/index.css
|
121
|
-
- lib/template/
|
123
|
+
- lib/template/history/history.json
|
124
|
+
- lib/template/html/index.html
|
125
|
+
- lib/template/html/test.html
|
122
126
|
- lib/template/js/main.js
|
123
127
|
- lib/template/my_app_sample.rb
|
124
128
|
- lib/template/server.rb
|