browser_app_base 0.0.2 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 63c1acfb3f65ae7519a6f74b1a0b2b138fd04f129585070c11e4211850c0a880
4
- data.tar.gz: df7982ee9fe63c7442ac7f53404921aec97bd83fce49a36888df10b6dd58be8b
3
+ metadata.gz: ee14b20cd2c842b0c470d9b96f31549ae576912a5e79afcbb4b44b35d3cfc740
4
+ data.tar.gz: 746081592fef24334ae14f50fbcddb672fa29103b800ea8bd84048711ff0ec9e
5
5
  SHA512:
6
- metadata.gz: 9610604a065b31f377798eb211b13ac92b50770d353058d7ad9a969b4b2071c82e9f927725ca3c76fe494b09edb6842ff98323991a126f50ca2dfe51fda2aa3d
7
- data.tar.gz: 4db1d41f410dc0f546d4db93895118821530d955cb0b098506b823c2906538c6a131460afea3b156773253e8ca6c8c98bd3564e5ed8a952b2dffefbc7fd3b56d
6
+ metadata.gz: a0360895d392e1fdbf2930c73c82ba09a8551ea15014ee30f5e71393b4b04d48ea52773f174cc4eb884eea85574e338bf0d8661362c3c4f1cda8512429466f4c
7
+ data.tar.gz: a48af4eeb30f310d5f601e19a212fb2c4e4239b61952ab33b2cc50d9e2392dc14b7fec672abc64507aadf55d415831cb194048af9c8903e7fb7e604476895441
@@ -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
- create app templat
31
+ ## Create app templat
31
32
 
32
- $ create_browser_app -d ~/test/
33
+ $ create_browser_app -d ~/test/ -a MyApp
33
34
 
34
- start application
35
+ ## add application code
36
+ $ cd ~/test/
37
+ $ vi my_app.rb
35
38
 
36
- $ cd ~/test/app
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
@@ -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[:dir]
24
+ BrowserAppBase.create o
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BrowserAppBase
4
- VERSION = "0.0.2"
4
+ VERSION = "0.0.6"
5
5
  end
@@ -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
- # Your code goes here...
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(dir)
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
- FileUtils.cp_r "#{path}/template", "#{dir}/app"
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,2 @@
1
+ require "my_app_sample.rb"
2
+ $app = MyApp.new
@@ -1,4 +1,4 @@
1
1
  {
2
- "chrome_win": "\"C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe\"",
2
+ "chrome_win": "start chrome",
3
3
  "chrome_linux": "/bin/google-chrome"
4
4
  }
@@ -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
+ ]
@@ -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 61820
77
+ #\ --port 54068
50
78
 
51
79
  run Sinatra::Application
@@ -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
+ }
@@ -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:61820/js/main.js"></script>
15
- <link rel="stylesheet" href="http://localhost:61820/css/index.css" type="text/css">
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
- <h3>サンプル</h3>
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
- <textarea name="log" id="log" class="outarea"></textarea><br/>
58
+ <div class="outarea">
59
+ <ul name="log" id="log" class="log">
60
+ </ul>
61
+ </div>
36
62
 
37
63
  </body>
38
64
 
@@ -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
- var fs = new ActiveXObject("Scripting.FileSystemObject");
17
- var file = fs.CreateTextFile(file_name);
18
- file.Close();
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 = $('#log').val() + evt.data + "\n";
21
- $('#log').val(log);
22
- var psconsole = $('#log');
23
- psconsole.scrollTop(
24
- psconsole[0].scrollHeight - psconsole.height()
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, url) {
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: 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:61820/wsserver")
258
+ server_connect("ws://localhost:54068/wsserver")
100
259
  // ウインドウサイズ
101
- var width = 600;
102
- var height = 700;
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
- var getUrl = function () {
112
- var url = "http://localhost:61820/search?path=" + $("#search_str").val();
113
- return url;
114
- };
115
- autocomp("search_str", getUrl);
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
- $("#file").click(function () {
119
- select_file("search_str");
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
- $("#stop").click(function () {
125
- send_message("stop");
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
- class AppMain
3
- def initialize
4
- @aboet = false
5
- end
2
+ require "server_app_base.rb"
6
3
 
7
- def start(file)
4
+ class MyApp < AppMainBase
5
+ def start(argv)
6
+ super
8
7
  begin
9
8
  @abort = false
10
- puts file
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
- @abort = true
26
+ super
24
27
  end
25
28
  end
@@ -1,9 +1,9 @@
1
- require 'json'
2
- require 'kconv'
1
+ require "json"
2
+ require "kconv"
3
3
 
4
4
  class Search < Sinatra::Base
5
5
  helpers Sinatra::Streaming
6
- get '' do
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
- file = "/" if file == nil
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.exists?(path)
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["value"] = file
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"
@@ -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.read("config.ru").toutf8
26
+ buf = File.binread("config.ru").toutf8
26
27
  buf.gsub!(/port [0-9]+/, "port #{port}")
27
- File.write("config.ru", buf)
28
+ File.binwrite("config.ru", buf)
28
29
 
29
30
  # main.jsの編集
30
- buf = File.read("js/main.js").toutf8
31
+ buf = File.binread("js/main.js").toutf8
31
32
  buf.gsub!(/localhost:[0-9]+\//, "localhost:#{port}/")
32
- File.write("js/main.js", buf)
33
+ File.binwrite("js/main.js", buf)
33
34
 
34
35
  # index.htaの編集
35
- buf = File.read("index.html").toutf8
36
+ buf = File.binread("index.html").toutf8
36
37
  buf.gsub!(/localhost:[0-9]+\//, "localhost:#{port}/")
37
- File.write("index.html", buf)
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
@@ -1,8 +1,19 @@
1
- require "./server_app"
2
- $app = AppMain.new
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
- fname = msg.gsub(/^exec:/, "")
19
- Thread.new {
20
- $app.start fname do |out|
21
- ws.send(out)
22
- end
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
- $app.stop
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.2
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-08-15 00:00:00.000000000 Z
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/server_app.rb
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