unageanu-jiji 0.1.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. data/README +1 -0
  2. data/base/agents/moving_average_agent.rb +78 -0
  3. data/base/shared_lib/moving_average.rb +34 -0
  4. data/bin/jiji +5 -0
  5. data/html/css/default.css +7 -0
  6. data/html/img/button_calendar_over.gif +0 -0
  7. data/html/img/button_cancel.gif +0 -0
  8. data/html/img/button_no.gif +0 -0
  9. data/html/img/button_no_gray.gif +0 -0
  10. data/html/img/button_no_over.gif +0 -0
  11. data/html/img/button_save.gif +0 -0
  12. data/html/img/button_save_gray.gif +0 -0
  13. data/html/img/button_save_over.gif +0 -0
  14. data/html/img/button_update_s.gif +0 -0
  15. data/html/img/button_update_s_gray.gif +0 -0
  16. data/html/img/button_update_s_over.gif +0 -0
  17. data/html/img/button_yes.gif +0 -0
  18. data/html/img/button_yes_gray.gif +0 -0
  19. data/html/img/button_yes_over.gif +0 -0
  20. data/html/index.html +29 -33
  21. data/html/js/agent-editor-page.js +178 -88
  22. data/html/js/agent-selector.js +68 -39
  23. data/html/js/bt-create-page.js +24 -11
  24. data/html/js/dialog.js +43 -34
  25. data/html/js/result-page.js +37 -25
  26. data/html/js/rt-setting-page.js +13 -6
  27. data/html/js/sidebar.js +8 -5
  28. data/html/js/templates.js +37 -3
  29. data/html/js/utils.js +47 -9
  30. data/html/swf/chart.swf +0 -0
  31. data/lib/jiji/agent/agent_manager.rb +2 -2
  32. data/lib/jiji/agent/agent_registry.rb +4 -1
  33. data/lib/jiji/command.rb +6 -0
  34. data/lib/jiji/process.rb +32 -10
  35. data/lib/jiji/process_manager.rb +7 -0
  36. data/lib/jiji/registry.rb +6 -4
  37. data/lib/jiji/server.rb +6 -1
  38. data/lib/jiji/service/output_service.rb +10 -6
  39. data/swf/chart/fx/chart/Chart.as +4 -1
  40. data/swf/chart/fx/chart/ui/Constants.as +3 -3
  41. data/swf/chart/fx/chart/ui/InformationWindow.as +45 -41
  42. data/swf/chart/fx/chart/ui/Pointer.as +6 -4
  43. data/swf/chart/fx/chart/ui/Scroll.as +3 -2
  44. data/swf/chart/fx/chart/ui/Stage.as +3 -3
  45. data/swf/chart/fx/chart/ui/TradeDetailWindow.as +9 -8
  46. data/swf/chart/fx/chart/ui/TradeResult.as +3 -17
  47. data/swf/chart/fx/chart/ui/graph/Graph.as +4 -2
  48. data/swf/chart/fx/chart/ui/graph/GraphManager.as +3 -1
  49. data/swf/chart/fx/chart/ui/resource/fixed.gif +0 -0
  50. data/swf/chart/fx/chart/ui/resource/unfixed.gif +0 -0
  51. data/swf/chart/fx/net/StubFactory.as +3 -3
  52. data/test/all_tests.rb +1 -1
  53. data/test/test_AgentManager.rb +4 -4
  54. data/test/{test_AgentRegistory.rb → test_AgentRegistry.rb} +0 -0
  55. data/test/test_Collector.rb +1 -1
  56. data/test/test_Output_registry.rb +7 -3
  57. data/test/test_Process.rb +5 -5
  58. data/test/test_ProcessManager.rb +120 -68
  59. metadata +20 -14
  60. data/bin/jiji.rb +0 -6
  61. data/html/js/W3CDTF.js +0 -131
@@ -28,8 +28,16 @@ fx.ui.pages.AgentEditorPage = function() {
28
28
  }, fx.template.Templates.common.button.del);
29
29
  this.removeButton.setEnable( true );
30
30
 
31
+ this.saveButton = new util.Button("agent-edit_save", "save", function() {
32
+ if ( !self.editingFile ) { return; }
33
+ var newData = agent_editor.getCode();
34
+ newData = newData.strip();
35
+ self.save(true,self.editingFile, self.target, newData);
36
+ }, fx.template.Templates.common.button.save);
37
+ this.saveButton.setEnable( false );
38
+
31
39
  // 自動保存するためのタイマー
32
- this.autoSave = new util.Timer( 1000*10, function(){ self.save(); }, false );
40
+ // this.autoSave = new util.Timer( 1000*10, function(){ self.save(); }, false );
33
41
  }
34
42
  fx.ui.pages.AgentEditorPage.prototype = {
35
43
 
@@ -38,11 +46,15 @@ fx.ui.pages.AgentEditorPage.prototype = {
38
46
  * 戻り値としてfalseを返すと遷移をキャンセルする。
39
47
  */
40
48
  from : function(toId) {
41
- // 変更を強制的に反映するため、一旦保存
42
- this.save();
43
49
  // 自動更新タイマーを停止
44
- this.autoSave.stop();
45
-
50
+ // this.autoSave.stop();
51
+
52
+ // 変更を強制的に反映するため、一旦保存
53
+ var self = this;
54
+ this.saveIfNotSaved(function(){
55
+ self.clearEdit();
56
+ });
57
+
46
58
  // ページを非表示
47
59
  document.getElementById(this.elementId).style.display = "none";
48
60
  this.topicPath.set("");
@@ -66,25 +78,34 @@ fx.ui.pages.AgentEditorPage.prototype = {
66
78
  ? fx.template.Templates.agentEditor.topicPath.agent
67
79
  : fx.template.Templates.agentEditor.topicPath.sharedLib );
68
80
 
81
+ document.getElementById("agent_edit_desc").innerHTML =
82
+ this.target == "agent" ? fx.template.Templates.agentEditor.desc.agent : fx.template.Templates.agentEditor.desc.sharedLib;
83
+
84
+ this.clearEdit();
85
+
69
86
  // ファイル一覧を更新
70
87
  this.initialize();
71
- // 自動更新タイマーを開始
72
- this.autoSave.start();
73
88
  },
74
89
 
75
90
  initialize: function( ) {
76
91
  var self = this;
92
+ self.editingFile = null;
93
+ agent_editor.setCode("\n");
77
94
  this.agentFileListTable.initialize();
78
95
  this.agentFileListTable.table.subscribe("rowSelectEvent", function(ev){
79
- self.selectionChanged();
96
+ self.selectionChanged();
80
97
  });
81
98
  this.agentFileListTable.table.subscribe("rowUnselectEvent", function(ev){
82
- self.selectionChanged();
99
+ self.selectionChanged();
83
100
  });
101
+ this.agentFileListTable.loading(true);
84
102
  this.listAgentFiles( true, function( data ) {
85
103
  self.agentFiles = data;
86
104
  self.agentFileListTable.setData(data);
105
+ self.agentFileListTable.loading(false);
87
106
  self.selectionChanged();
107
+ // 自動更新タイマーを開始
108
+ // self.autoSave.start();
88
109
  }, null ); // TODO
89
110
  },
90
111
 
@@ -96,23 +117,24 @@ fx.ui.pages.AgentEditorPage.prototype = {
96
117
  this.dialog.show( "input", {
97
118
  message : fx.template.Templates.agentEditor.add.body.evaluate({ "text" : "" }),
98
119
  init: function() {
99
- document.file_name_input_form.file_name_input.focus();
120
+ document.file_name_input_form.file_name_input.focus();
100
121
  if ( !agent_editor.textarea.readOnly ) {
101
- agent_editor.toggleReadOnly();
122
+ agent_editor.toggleReadOnly();
102
123
  }
103
- },
124
+ },
104
125
  buttons : [
105
126
  { type:"ok",
106
- alt: "ok",
107
- key: "Enter",
108
- action: function(dialog){
127
+ alt: fx.template.Templates.common.button.ok,
128
+ key: "Enter",
129
+ action: function(dialog){
109
130
  var text = document.getElementById("file_name_input").value;
110
- // 文字列をチェック
131
+
132
+ // 文字列をチェック
111
133
  var error = null;
112
134
  if ( !text ) {
113
135
  error = fx.template.Templates.agentEditor.add.errormsgs.no;
114
136
  }
115
- if ( !error && !text.match( /^[A-Za-z0-9_\*\+\-\#\"\'\!\~\(\)\[\]\?\.]+$/ ) ) {
137
+ if ( !error && !text.match( /^[A-Za-z0-9_\*\+\-\#\"\'\!\~\(\)\[\]\?\.]+$/ ) ) {
116
138
  error = fx.template.Templates.agentEditor.add.errormsgs.illegalChar;
117
139
  }
118
140
  // 重複チェック
@@ -130,31 +152,31 @@ fx.ui.pages.AgentEditorPage.prototype = {
130
152
  }
131
153
  if (error) {
132
154
  dialog.content.innerHTML =
133
- fx.template.Templates.agentEditor.add.error.evaluate({ "error" : error })
134
- + fx.template.Templates.agentEditor.add.body.evaluate({ "text" : text })
155
+ fx.template.Templates.agentEditor.add.error.evaluate({ "error" : error.escapeHTML() })
156
+ + fx.template.Templates.agentEditor.add.body.evaluate({ "text" : text.escapeHTML() })
135
157
  return false;
136
158
  } else {
137
- self.saveFile( text, "", function(){
159
+ self.saveFile( text, self.target, "", function(){
138
160
  self.listAgentFiles( true, function( data ) {
139
161
  self.agentFiles = data;
140
162
  self.agentFileListTable.setData(data);
141
163
  self.selectionChanged();
142
164
  }, null ); // TODO
143
165
  }, null ); // TODO
144
- if ( old != agent_editor.textarea.readOnly ) {
145
- agent_editor.toggleReadOnly();
146
- }
166
+ if ( old != agent_editor.textarea.readOnly ) {
167
+ agent_editor.toggleReadOnly();
168
+ }
147
169
  return true;
148
170
  }
149
171
  } },
150
172
  { type:"cancel",
151
- alt: fx.template.Templates.common.button.cancel,
152
- key: "Esc",
153
- action: function(dialog){
154
- if ( old != agent_editor.textarea.readOnly ) {
155
- agent_editor.toggleReadOnly();
156
- }
157
- return true;
173
+ alt: fx.template.Templates.common.button.cancel,
174
+ key: "Esc",
175
+ action: function(dialog){
176
+ if ( old != agent_editor.textarea.readOnly ) {
177
+ agent_editor.toggleReadOnly();
178
+ }
179
+ return true;
158
180
  }}
159
181
  ]
160
182
  } );
@@ -168,7 +190,7 @@ fx.ui.pages.AgentEditorPage.prototype = {
168
190
  }
169
191
  var names = [];
170
192
  for( var i=0,s=selectedRowIds.length;i<s;i++ ) {
171
- names.push( this.agentFileListTable.table.getRecord( selectedRowIds[i] ).getData().name);
193
+ names.push( this.agentFileListTable.table.getRecord( selectedRowIds[i] ).getData().name);
172
194
  }
173
195
  // 確認
174
196
  var self = this;
@@ -177,14 +199,17 @@ fx.ui.pages.AgentEditorPage.prototype = {
177
199
  message : fx.template.Templates.agentEditor.remove.body,
178
200
  init: function() {
179
201
  if ( !agent_editor.textarea.readOnly ) {
180
- agent_editor.toggleReadOnly();
202
+ agent_editor.toggleReadOnly();
181
203
  }
182
- },
204
+ },
183
205
  buttons : [
184
- { type:"ok", action: function(dialog){
185
- if ( old != agent_editor.textarea.readOnly ) {
186
- agent_editor.toggleReadOnly();
187
- }
206
+ { type:"ok",
207
+ alt: fx.template.Templates.common.button.ok,
208
+ key: "Enter",
209
+ action: function(dialog){
210
+ if ( old != agent_editor.textarea.readOnly ) {
211
+ agent_editor.toggleReadOnly();
212
+ }
188
213
  // 行のデータを削除
189
214
  self.deleteFile( names, function(){
190
215
  self.listAgentFiles( true, function( data ) {
@@ -193,79 +218,142 @@ fx.ui.pages.AgentEditorPage.prototype = {
193
218
  self.selectionChanged();
194
219
  }, null ); // TODO
195
220
  }, null ); // TODO
221
+ return true;
196
222
  }},
197
223
  { type:"cancel",
198
- alt: fx.template.Templates.common.button.cancel,
199
- key: "Esc",
200
- action: function(dialog){
201
- if ( old != agent_editor.textarea.readOnly ) {
202
- agent_editor.toggleReadOnly();
203
- }
204
- return true;
224
+ alt: fx.template.Templates.common.button.cancel,
225
+ key: "Esc",
226
+ action: function(dialog){
227
+ if ( old != agent_editor.textarea.readOnly ) {
228
+ agent_editor.toggleReadOnly();
229
+ }
230
+ return true;
205
231
  }}
206
232
  ]
207
233
  });
208
234
  },
209
- save: function(){
210
- if ( !this.editingFile ) { return; }
211
- var newData = agent_editor.getCode();
235
+ save: function( showResult, editingFile, mode, newData ){
212
236
  var self = this;
213
- if ( self.prevCode == newData ) { return; }
214
- this.saveFile( this.editingFile, newData, function(){
237
+ this.saveFile( editingFile, mode, newData, function(result){
238
+ // 結果を表示しない == 別画面に移動する場合は、前のコードは不要なので変更しない。
239
+ if (!showResult) { return; }
215
240
  self.prevCode = newData;
241
+ if ( result == "success" ) {
242
+ document.getElementById("agent_edit_msg").innerHTML =
243
+ fx.template.Templates.agentEditor.saved.success.evaluate({ "now" : util.formatDate( new Date() ) });
244
+ } else {
245
+ document.getElementById("agent_edit_msg").innerHTML =
246
+ fx.template.Templates.agentEditor.saved.error.evaluate({ "now" : util.formatDate( new Date() ), "result":result.escapeHTML()} );
247
+ }
216
248
  }, null ); // TODO
217
249
  },
218
-
250
+ /**
251
+ * 未保存かどうかチェックして、未保存でかつtrueであれば保存を実行する。
252
+ */
253
+ saveIfNotSaved: function( callback ){
254
+ // 編集中でない
255
+ if ( !this.editingFile ) {
256
+ if (callback) { callback(); }
257
+ return true;
258
+ }
259
+ var editingFile = this.editingFile;
260
+ var target = this.target;
261
+
262
+ // コードが変更されていない
263
+ var newData = agent_editor.getCode();
264
+ newData = newData.strip();
265
+ var self = this;
266
+ if ( self.prevCode == newData ) {
267
+ if (callback) { callback(); }
268
+ return true;
269
+ }
270
+
271
+ // 確認ダイアログを表示
272
+ this.dialog.show( "input", {
273
+ message : fx.template.Templates.agentEditor.dosave,
274
+ buttons : [
275
+ { type:"yes",
276
+ alt: fx.template.Templates.common.button.yes,
277
+ key: "Enter",
278
+ action: function(dialog){
279
+ self.save(false, editingFile, target, newData);
280
+ if (callback) { callback(); }
281
+ return true;
282
+ }},
283
+ { type:"no",
284
+ alt: fx.template.Templates.common.button.no,
285
+ key: "Esc",
286
+ action: function(dialog){
287
+ if (callback) { callback(); }
288
+ return true;
289
+ }
290
+ }
291
+ ]
292
+ });
293
+ },
294
+ /**
295
+ * 編集なし状態にします。
296
+ */
297
+ clearEdit : function(){
298
+ this.editingFile = null;
299
+ agent_editor.setCode("\n");
300
+ this.saveButton.setEnable( false );
301
+ document.getElementById("agent_edit_msg").innerHTML = "";
302
+ },
219
303
  selectionChanged: function() {
220
304
 
221
305
  // 選択されている行を取得
222
- var self = this;
306
+ var self = this;
223
307
  var selectedRowIds = this.agentFileListTable.table.getSelectedTrEls();
224
308
  var data = null;
225
309
  var removeEnable = false;
226
310
  if ( selectedRowIds.length <= 0 ) {
227
- // 選択なし
228
- removeEnable = false;
229
- document.getElementById("agent-editor-file-name").innerHTML=
230
- fx.template.Templates.agentEditor.defaultFileName;
311
+ // 選択なし
312
+ removeEnable = false;
313
+ document.getElementById("agent-editor-file-name").innerHTML=
314
+ fx.template.Templates.agentEditor.defaultFileName;
231
315
  } else if ( selectedRowIds.length == 1 ) {
232
- removeEnable = true;
233
- // エディタも更新する。
234
- data = this.agentFileListTable.table.getRecord( selectedRowIds[0] ).getData();
316
+ removeEnable = true;
317
+ // エディタも更新する。
318
+ data = this.agentFileListTable.table.getRecord( selectedRowIds[0] ).getData();
235
319
  } else {
236
- removeEnable = true;
237
- // エディタは初期化
238
- document.getElementById("agent-editor-file-name").innerHTML= "---";
320
+ removeEnable = true;
321
+ // エディタは初期化
322
+ document.getElementById("agent-editor-file-name").innerHTML= "---";
239
323
  }
240
324
  // 削除の状態更新
241
325
  this.removeButton.setEnable(removeEnable);
326
+ this.saveButton.setEnable(false);
242
327
 
243
328
  // エディタのデータを更新
244
- self.save();
245
- if ( data ) {
246
- // 変更を強制的に反映するため、一旦保存
247
- self.editingFile = null;
248
- document.getElementById("agent-editor-file-name").innerHTML=
249
- fx.template.Templates.common.loading;
250
- self.getFile( data.name, function( body) {
251
- self.editingFile = data.name;
252
- self.prevCode = body;
253
- if ( agent_editor.textarea.readOnly ) {
254
- agent_editor.toggleReadOnly();
255
- }
256
- agent_editor.setCode(body);
257
- agent_editor.editor.syntaxHighlight('init');
258
- document.getElementById("agent-editor-file-name").innerHTML= data.name;
259
- }, null ); // TODO
260
- } else {
261
- self.save();
262
- self.editingFile = null;
263
- agent_editor.setCode("");
264
- agent_editor.editor.syntaxHighlight('init');
265
- if ( !agent_editor.textarea.readOnly ) {
266
- agent_editor.toggleReadOnly();
329
+ // 保存確認
330
+ self.saveIfNotSaved( function(){
331
+ if ( data ) {
332
+ self.editingFile = null;
333
+ document.getElementById("agent-editor-file-name").innerHTML=
334
+ fx.template.Templates.common.loading;
335
+ self.getFile( data.name, function( body ) {
336
+ body = body.strip();
337
+ self.editingFile = data.name;
338
+ self.prevCode = body;
339
+ if ( agent_editor.textarea.readOnly ) {
340
+ agent_editor.toggleReadOnly();
341
+ }
342
+ if( body == "" ) body = "\n" // 空文字をcodePressに設定するとバグるので対策。
343
+ agent_editor.setCode(body);
344
+ agent_editor.editor.syntaxHighlight('init');
345
+ document.getElementById("agent-editor-file-name").innerHTML= data.name;
346
+ document.getElementById("agent_edit_msg").innerHTML = "";
347
+ self.saveButton.setEnable( true );
348
+ }, null ); // TODO
349
+ } else {
350
+ self.clearEdit();
351
+ agent_editor.editor.syntaxHighlight('init');
352
+ if ( !agent_editor.textarea.readOnly ) {
353
+ agent_editor.toggleReadOnly();
354
+ }
267
355
  }
268
- }
356
+ });
269
357
  },
270
358
 
271
359
  /**
@@ -301,8 +389,8 @@ fx.ui.pages.AgentEditorPage.prototype = {
301
389
  * @param {Function} success 成功時のコールバック
302
390
  * @param {Function} fail 失敗時のコールバック
303
391
  */
304
- saveFile : function( file, content, success, fail ) {
305
- this.agentServiceStub.put_file( file, content, this.target, success, fail );
392
+ saveFile : function( file, target, content, success, fail ) {
393
+ this.agentServiceStub.put_file( file, content, target, success, fail );
306
394
  },
307
395
  /**
308
396
  * エージェントファイルを削除する。
@@ -327,7 +415,9 @@ fx.ui.AgentFileListTable.prototype = util.merge( util.BasicTable, {
327
415
  var self = this;
328
416
  var columnDefs = [
329
417
  {key:"name", label:fx.template.Templates.agentEditor.fileList.column.name,
330
- sortable:true, resizeable:true, width:122},
418
+ sortable:true, resizeable:true, formatter: function( cell, record, column, data){
419
+ cell.innerHTML = String(data).escapeHTML();
420
+ }, width:122},
331
421
  {key:"update", label:fx.template.Templates.agentEditor.fileList.column.update,
332
422
  sortable:true, resizeable:true, formatter: function( cell, record, column, data){
333
423
  var d = new Date(data*1000);
@@ -44,12 +44,12 @@ fx.agent.ui.AgentSelector.prototype = {
44
44
  if ( !this.readOnly ) {
45
45
  this.addButton = new util.Button(this.id + "__add", "add", function() {
46
46
  self.add();
47
- }, "追加");
47
+ }, fx.template.Templates.common.button.add);
48
48
  this.addButton.setEnable( true );
49
49
 
50
50
  this.removeButton = new util.Button(this.id + "__remove", "remove", function() {
51
51
  self.remove();
52
- }, "削除");
52
+ }, fx.template.Templates.common.button.del);
53
53
  this.removeButton.setEnable( false );
54
54
  }
55
55
  },
@@ -57,6 +57,7 @@ fx.agent.ui.AgentSelector.prototype = {
57
57
  * エージェントを設定する
58
58
  */
59
59
  setAgents : function(data) {
60
+ this.agentListTable.loading(false);
60
61
  if ( data ) {
61
62
  this.agentListTable.setData(data);
62
63
  if ( !this.readOnly ) {
@@ -73,6 +74,7 @@ fx.agent.ui.AgentSelector.prototype = {
73
74
  // 編集中なら、編集を確定
74
75
  if ( this.isEditing() ) {
75
76
  this.edit();
77
+ this.agentListTable.table.unselectAllRows();
76
78
  }
77
79
  var agents = [];
78
80
  var rs = this.agentListTable.table.getRecordSet().getRecords( 0, this.agentListTable.length() );
@@ -112,13 +114,16 @@ fx.agent.ui.AgentSelector.prototype = {
112
114
  self.listAgentClass( false, function( data ) {
113
115
  self.agentClasses = data;
114
116
  self.agentClassListTable.setData(data);
117
+ self.agentClassListTable.loading(false);
115
118
  if ( data.length > 0 ) {
116
119
  self.agentClassListTable.table.selectRow(0);
117
120
  }
118
121
  }, null ); // TODO
119
122
  },
120
123
  buttons : [
121
- { type:"ok", action: function(dialog){
124
+ { type:"ok",
125
+ alt: fx.template.Templates.common.button.ok,
126
+ key: "Enter", action: function(dialog){
122
127
 
123
128
  var selectedRowIds = self.agentClassListTable.table.getSelectedRows();
124
129
  var error = null;
@@ -134,17 +139,19 @@ fx.agent.ui.AgentSelector.prototype = {
134
139
  }
135
140
 
136
141
  if (error) {
137
- dialog.content.innerHTML = '<div class="warn_msg">※'
138
- + error + '</div>' + msg;
142
+ dialog.content.innerHTML = fx.template.Templates.agentSelector.error.evaluate({
143
+ error: error.escapeHTML(),
144
+ msg: msg.escapeHTML()
145
+ });
139
146
  self.agentClassListTable.elementId = "agent_class_list";
140
- self.agentClassListTable.initialize();
141
- self.agentClassListTable.setData(self.agentClasses);
147
+ self.agentClassListTable.initialize();
148
+ self.agentClassListTable.setData(self.agentClasses);
142
149
  return false;
143
150
  } else {
144
151
  self._add( agents );
145
152
  }
146
153
  } },
147
- { type:"cancel" }
154
+ { type:"cancel", alt: fx.template.Templates.common.button.cancel, key: "Esc" }
148
155
  ]
149
156
  } );
150
157
 
@@ -170,11 +177,14 @@ fx.agent.ui.AgentSelector.prototype = {
170
177
  var defs = newAgents[i].properties;
171
178
  var prop = {};
172
179
  var def = {};
180
+ var error = null;
173
181
  for ( var j=0, s=defs.length;j<s;j++ ) {
174
182
  def[defs[j]["id"]] = defs[j];
175
183
  prop[defs[j]["id"]] = defs[j]["default"] || "";
184
+ error = error || this.agentPropertyEditor.validate[defs[j].type].call(
185
+ this.agentPropertyEditor, prop[defs[j]["id"]], defs[j].restrict );
176
186
  }
177
-
187
+
178
188
  var a = {
179
189
  "id": UUID.generate(),
180
190
  "name": "名称未設定エージェント"+k,
@@ -183,7 +193,8 @@ fx.agent.ui.AgentSelector.prototype = {
183
193
  "file_name":newAgents[i].file_name,
184
194
  "description":newAgents[i].description,
185
195
  "property_def":def,
186
- "properties":prop
196
+ "properties":prop,
197
+ "state": error ? "error" : ""
187
198
  };
188
199
  this.agentListTable.add( a ); // テーブルを更新
189
200
  }
@@ -192,10 +203,10 @@ fx.agent.ui.AgentSelector.prototype = {
192
203
  // 削除
193
204
  remove: function(){
194
205
 
195
- // 編集中なら、編集を確定
196
- if ( this.isEditing() ) {
197
- this.edit();
198
- }
206
+ // // 編集中なら、編集を確定
207
+ // if ( this.isEditing() ) {
208
+ // this.edit();
209
+ // }
199
210
 
200
211
  // 選択されている行を取得
201
212
  var selectedRowIds = this.agentListTable.table.getSelectedTrEls();
@@ -208,7 +219,7 @@ fx.agent.ui.AgentSelector.prototype = {
208
219
  this.dialog.show( "input", {
209
220
  message : msg,
210
221
  buttons : [
211
- { type:"ok", action: function(dialog){
222
+ { type:"ok",alt: fx.template.Templates.common.button.ok, key: "Enter", action: function(dialog){
212
223
  // 行のデータを削除
213
224
  for( var j=0,s=selectedRowIds.length;j<s;j++ ) {
214
225
  self.agentListTable.remove( selectedRowIds[j] );
@@ -217,7 +228,7 @@ fx.agent.ui.AgentSelector.prototype = {
217
228
  self.selectionChanged();
218
229
  }},
219
230
  { type:"cancel",
220
- alt: "キャンセル",
231
+ alt: fx.template.Templates.common.button.cancel,
221
232
  key: "Esc"
222
233
  }
223
234
  ]
@@ -246,9 +257,15 @@ fx.agent.ui.AgentSelector.prototype = {
246
257
  removeEnable = true;
247
258
  // エディタも更新する。
248
259
  var selectedEl = this.agentListTable.table.getSelectedTrEls()[0];
249
- this.agentPropertyEditor.target = this.agentListTable.table.getRecord (selectedRowIds[0]);
250
- var data = this.agentListTable.table.getRecord( selectedRowIds[0] ).getData();
251
- self.agentPropertyEditor.set( data );
260
+ var target = this.agentListTable.table.getRecord(selectedRowIds[0]);
261
+ if ( target ) {
262
+ this.agentPropertyEditor.target = target;
263
+ var data = target.getData();
264
+ self.agentPropertyEditor.set( data );
265
+ } else {
266
+ removeEnable = false;
267
+ self.agentPropertyEditor.clear( "エージェントを選択してください。" );
268
+ }
252
269
  } else {
253
270
  removeEnable = true;
254
271
  // エディタは初期化
@@ -263,14 +280,14 @@ fx.agent.ui.AgentSelector.prototype = {
263
280
  /**
264
281
  * プロパティを保存
265
282
  */
266
- edit: function(){
283
+ edit: function( ){
267
284
  if ( this.readOnly ) return;
268
285
  var newData = this.agentPropertyEditor.get();
269
286
  if ( newData ) {
270
287
  this.agentListTable.update( this.agentPropertyEditor.target, newData );
271
288
  this.agentPropertyEditor.target = null;
272
289
  this.agentPropertyEditor.end();
273
-
290
+
274
291
  this.checkDuplicateName();
275
292
  }
276
293
  },
@@ -338,10 +355,14 @@ fx.agent.ui.AgentClassListTable.prototype = util.merge( util.BasicTable, {
338
355
  initialize: function() {
339
356
  var self = this;
340
357
  var columnDefs = [
341
- {key:"class_name", label:"クラス", sortable:true, resizeable:true, width:80 },
342
- {key:"file_name", label:"ファイル", sortable:true, resizeable:true, width:80 },
358
+ {key:"class_name", label:"クラス", sortable:true, resizeable:true, formatter: function( cell, record, column, data){
359
+ cell.innerHTML = String(data).escapeHTML();
360
+ }, width:80 },
361
+ {key:"file_name", label:"ファイル", sortable:true, resizeable:true, formatter: function( cell, record, column, data){
362
+ cell.innerHTML = String(data).escapeHTML();
363
+ }, width:80 },
343
364
  {key:"description", label:"説明", sortable:true, resizeable:true, formatter: function( cell, record, column, data){
344
- cell.innerHTML = "<pre>" + data + "</pre>";
365
+ cell.innerHTML = "<pre>" + String(data).escapeHTML() + "</pre>";
345
366
  }}
346
367
  ];
347
368
  self.ds = new YAHOO.util.DataSource([]);
@@ -374,16 +395,20 @@ fx.agent.ui.AgentListTable.prototype = util.merge( util.BasicTable, {
374
395
  {key:"name", label:"名前", sortable:true, resizeable:true, width:100, formatter: function( cell, record, column, data){
375
396
  var str = data.escapeHTML();
376
397
  if ( record.getData().state === "error" || record.getData().duplicate_name_error ) {
377
- str = '<div class="problem"><span style="padding-right:3px;padding-top:2px;"><img src="./img/problem.gif" alt="問題" /></span>' + str + '</div>';
398
+ str = '<div class="problem"><span style="padding-right:3px;padding-top:2px;"><!--img src="./img/problem.gif" alt="問題" / --></span>' + String(str).escapeHTML() + '</div>';
378
399
  }
379
400
  cell.innerHTML = str;
380
401
  }},
381
- {key:"class_name", label:"クラス", sortable:true, resizeable:true, width:80 },
382
- {key:"file_name", label:"ファイル", sortable:true, resizeable:true,width:80 },
402
+ {key:"class_name", label:"クラス", sortable:true, resizeable:true, formatter: function( cell, record, column, data){
403
+ cell.innerHTML = String(data).escapeHTML();
404
+ }, width:80 },
405
+ {key:"file_name", label:"ファイル", sortable:true, resizeable:true, formatter: function( cell, record, column, data){
406
+ cell.innerHTML = String(data).escapeHTML();
407
+ }, width:80 },
383
408
  {key:"properties", label:"プロパティ", sortable:true, resizeable:true, width:250, formatter: function( cell, record, column, data){
384
409
  var str = "";
385
410
  for( var k in data ) {
386
- str += String(record.getData().property_def[k].name) + "=" + String(data[k]) + ", ";
411
+ str += String(record.getData().property_def[k].name).escapeHTML() + "=" + String(data[k]).escapeHTML() + ", ";
387
412
  if ( str.length > 500 ) { break; }
388
413
  }
389
414
  cell.innerHTML = str;
@@ -433,16 +458,17 @@ fx.agent.ui.AgentPropertyEditor.prototype = {
433
458
  var props = "";
434
459
  for ( var i in agent.property_def ) {
435
460
  props += fx.template.Templates.agentPropertyEditor.property.evaluate({
436
- "name": agent.property_def[i].name,
461
+ "name": agent.property_def[i].name.escapeHTML(),
437
462
  "id": agent.property_def[i].id,
438
- "default": agent.properties[agent.property_def[i].id] || agent.property_def[i]["default"]
463
+ "default": agent.properties[agent.property_def[i].id] != null
464
+ ? agent.properties[agent.property_def[i].id] : agent.property_def[i]["default"]
439
465
  });
440
466
  }
441
467
  var info = {
442
468
  "id": this.elementId,
443
- "class_name":agent.class_name,
444
- "name": agent.name,
445
- "desc": agent.description,
469
+ "class_name":agent.class_name.escapeHTML(),
470
+ "name": agent.name.escapeHTML(),
471
+ "desc": agent.description.escapeHTML(),
446
472
  "properties":props
447
473
  };
448
474
  document.getElementById( this.elementId ).innerHTML =
@@ -496,7 +522,7 @@ fx.agent.ui.AgentPropertyEditor.prototype = {
496
522
  } else if ( input["name"].match(/^property\_(.+)$/) ) {
497
523
  var id = RegExp.$1;
498
524
  var def = this.validators["property_" + id];
499
- error = error || this.validate[def.type].call( this, this.editing["properties"][id], def );
525
+ error = error || this.validate[def.type].call( this, value, def );
500
526
  this.editing["properties"][id] = !error ? this.convert[def.type].call( this, value ) : value ;
501
527
  }
502
528
  }
@@ -505,6 +531,7 @@ fx.agent.ui.AgentPropertyEditor.prototype = {
505
531
  },
506
532
  end : function() {
507
533
  this.editing = null;
534
+ this.clear( "エージェントを選択してください。" );
508
535
  },
509
536
  /**
510
537
  * 何も編集していない状態にする。
@@ -607,17 +634,19 @@ fx.agent.ui.AgentPropertyEditorReadOnly.prototype = {
607
634
  this.editing = util.merge({}, agent);
608
635
  var props = "";
609
636
  for ( var i in agent.property_def ) {
637
+ var value = agent.properties[agent.property_def[i].id] || agent.property_def[i]["default"];
638
+ if (value && Object.isFunction(value.escapeHTML )) { value = value.escapeHTML(); }
610
639
  props += fx.template.Templates.agentPropertyEditor.propertyReadOnly.evaluate({
611
- "name": agent.property_def[i].name,
640
+ "name": agent.property_def[i].name.escapeHTML(),
612
641
  "id": agent.property_def[i].id,
613
- "default": agent.properties[agent.property_def[i].id] || agent.property_def[i]["default"]
642
+ "default": value
614
643
  });
615
644
  }
616
645
  var info = {
617
646
  "id": this.elementId,
618
- "class_name":agent.class_name,
619
- "name": agent.name,
620
- "desc": agent.description,
647
+ "class_name":agent.class_name.escapeHTML(),
648
+ "name": agent.name.escapeHTML(),
649
+ "desc": agent.description.escapeHTML(),
621
650
  "properties":props
622
651
  };
623
652
  document.getElementById( this.elementId ).innerHTML =