rhodes 3.3.3.beta.1 → 3.3.3.beta.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (146) hide show
  1. data/CHANGELOG +3 -0
  2. data/Manifest.txt +23 -9
  3. data/Rakefile +13 -2
  4. data/doc/build.txt +18 -11
  5. data/doc/device-caps.txt +4 -68
  6. data/doc/rhom.txt +33 -0
  7. data/doc/test-log-debug.txt +18 -42
  8. data/lib/framework/rho/render.rb +1 -1
  9. data/lib/framework/rho/rho.rb +31 -1
  10. data/lib/framework/rho/rhocontroller.rb +2 -2
  11. data/lib/framework/rhodes.rb +1 -1
  12. data/lib/framework/rhoframework.rb +4 -0
  13. data/lib/framework/rholang/localization_simplified.rb +1 -1
  14. data/lib/framework/rhom/rhom_object_factory.rb +22 -1
  15. data/lib/framework/version.rb +1 -1
  16. data/lib/rhodes.rb +1 -1
  17. data/platform/android/Rhodes/AndroidManifest.xml +2 -2
  18. data/platform/android/Rhodes/jni/include/rhodes/jni/com_rhomobile_rhodes_RhodesService.h +25 -9
  19. data/platform/android/Rhodes/jni/include/rhodes/jni/com_rhomobile_rhodes_extmanager_RhoExtManagerImpl.h +21 -0
  20. data/platform/android/Rhodes/jni/src/extmanager.cpp +36 -0
  21. data/platform/android/Rhodes/jni/src/nativeview.cpp +1 -1
  22. data/platform/android/Rhodes/jni/src/rhodesapp.cpp +14 -5
  23. data/platform/android/Rhodes/jni/src/rhodessystem.cpp +5 -0
  24. data/platform/android/Rhodes/jni/src/signature.cpp +29 -3
  25. data/platform/android/Rhodes/src/com/rhomobile/rhodes/NativeBar.java +3 -3
  26. data/platform/android/Rhodes/src/com/rhomobile/rhodes/RhodesActivity.java +4 -0
  27. data/platform/android/Rhodes/src/com/rhomobile/rhodes/RhodesService.java +42 -7
  28. data/platform/android/Rhodes/src/com/rhomobile/rhodes/WebView.java +61 -10
  29. data/platform/android/Rhodes/src/com/rhomobile/rhodes/extmanager/IRhoExtData.java +6 -0
  30. data/platform/android/Rhodes/src/com/rhomobile/rhodes/extmanager/IRhoExtManager.java +39 -0
  31. data/platform/android/Rhodes/src/com/rhomobile/rhodes/extmanager/IRhoExtension.java +18 -0
  32. data/platform/android/Rhodes/src/com/rhomobile/rhodes/extmanager/RhoExtDataImpl.java +18 -0
  33. data/platform/android/Rhodes/src/com/rhomobile/rhodes/extmanager/RhoExtManagerImpl.java +142 -0
  34. data/platform/android/Rhodes/src/com/rhomobile/rhodes/extmanager/RhoExtManagerSingleton.java +15 -0
  35. data/platform/android/Rhodes/src/com/rhomobile/rhodes/mainview/MainView.java +6 -3
  36. data/platform/android/Rhodes/src/com/rhomobile/rhodes/mainview/SimpleMainView.java +25 -13
  37. data/platform/android/Rhodes/src/com/rhomobile/rhodes/mainview/SplashScreen.java +15 -9
  38. data/platform/android/Rhodes/src/com/rhomobile/rhodes/mainview/TabbedMainView.java +15 -5
  39. data/platform/android/Rhodes/src/com/rhomobile/rhodes/nativeview/RhoNativeViewManager.java +3 -3
  40. data/platform/android/Rhodes/src/com/rhomobile/rhodes/signature/ImageCapture.java +14 -8
  41. data/platform/android/Rhodes/src/com/rhomobile/rhodes/signature/Signature.java +218 -51
  42. data/platform/android/Rhodes/src/com/rhomobile/rhodes/signature/SignatureProperties.java +94 -0
  43. data/platform/android/Rhodes/src/com/rhomobile/rhodes/signature/SignatureView.java +122 -37
  44. data/platform/android/Rhodes/src/com/rhomobile/rhodes/webview/GoogleWebView.java +6 -2
  45. data/platform/android/Rhodes/src/com/rhomobile/rhodes/webview/{WebView.java → IRhoWebView.java} +2 -1
  46. data/platform/android/Rhodes/src/com/rhomobile/rhodes/webview/RhoWebViewClient.java +4 -0
  47. data/platform/android/build/RhodesSRC_build.files +8 -1
  48. data/platform/android/build/android.rake +5 -1
  49. data/platform/android/build/librhodes_build.files +1 -0
  50. data/platform/bb/RubyVM/src/com/rho/RhodesApp.java +22 -1
  51. data/platform/bb/RubyVM/src/com/rho/sync/SyncSource.java +15 -0
  52. data/platform/bb/RubyVM/src/com/xruby/runtime/lang/RhoSupport.java +4 -0
  53. data/platform/bb/RubyVM/src/com/xruby/runtime/lang/RubyRuntime.java +4 -2
  54. data/platform/bb/build/rhodes_build.files +2 -0
  55. data/platform/bb/rhodes/src/com/rho/RhoRubyHelper.java +1 -1
  56. data/platform/bb/rhodes/src/com/rho/rubyext/PNGEncoder.java +613 -0
  57. data/platform/bb/rhodes/src/com/rho/rubyext/SignatureCapture.java +314 -0
  58. data/platform/bb/rhodes/src/com/rho/rubyext/WebView.java +1 -1
  59. data/platform/iphone/Classes/AppManager/AppManager.m +11 -0
  60. data/platform/iphone/Classes/Rhodes.m +1 -1
  61. data/platform/iphone/Classes/Signature/SignatureDelegate.h +5 -1
  62. data/platform/iphone/Classes/Signature/SignatureDelegate.m +186 -5
  63. data/platform/iphone/Classes/Signature/SignatureView.h +12 -0
  64. data/platform/iphone/Classes/Signature/SignatureView.m +11 -3
  65. data/platform/iphone/Classes/SimpleMainView.m +4 -0
  66. data/platform/iphone/Classes/rho/net/NetRequestImpl.m +98 -3
  67. data/platform/iphone/Info.plist +1 -1
  68. data/platform/iphone/rbuild/iphone.rake +18 -5
  69. data/platform/shared/RhoConnectClient/RhoConnectClient.cpp +1 -1
  70. data/platform/shared/common/ExtManager.h +64 -9
  71. data/platform/shared/common/RhoSimConf.h +1 -0
  72. data/platform/shared/common/RhodesApp.cpp +77 -28
  73. data/platform/shared/common/RhodesApp.h +9 -4
  74. data/platform/shared/common/RhodesAppBase.cpp +4 -3
  75. data/platform/shared/common/RhodesAppBase.h +5 -3
  76. data/platform/shared/net/HttpServer.cpp +4 -4
  77. data/platform/shared/net/HttpServer.h +2 -2
  78. data/platform/shared/qt/rhodes/impl/MainWindowImpl.cpp +1 -1
  79. data/platform/shared/qt/rhodes/main.cpp +1 -1
  80. data/platform/shared/ruby/ext/rho/rhoruby.c +12 -2
  81. data/platform/shared/ruby/ext/rho/rhosupport.c +11 -1
  82. data/platform/shared/ruby/thread_win32.c +2 -1
  83. data/platform/shared/rubyext/System.cpp +6 -0
  84. data/platform/shared/sync/SyncSource.cpp +15 -0
  85. data/platform/wm/RhoLib/RhoLib.vcproj +0 -4
  86. data/platform/wm/build/build_inf.js +34 -4
  87. data/platform/wm/build/wm.rake +75 -25
  88. data/platform/wm/rhodes/AppManager.cpp +14 -3
  89. data/platform/wm/rhodes/IBrowserEngine.h +7 -0
  90. data/platform/wm/rhodes/IEBrowserEngine.cpp +43 -0
  91. data/platform/wm/rhodes/IEBrowserEngine.h +7 -0
  92. data/platform/wm/rhodes/LogOptionsDlg.cpp +1 -1
  93. data/platform/wm/rhodes/MainWindow.cpp +92 -7
  94. data/platform/wm/rhodes/MainWindow.h +28 -1
  95. data/platform/wm/rhodes/MapView/MapViewManager.cpp +4 -4
  96. data/platform/wm/rhodes/Rhodes.cpp +149 -10
  97. data/platform/wm/rhodes/resource.h +5 -1
  98. data/platform/wm/rhodes/rho/common/ExtManager.cpp +307 -0
  99. data/platform/wm/rhodes/rho/rubyext/NativeToolbar.cpp +1 -1
  100. data/platform/wm/rhodes/rho/rubyext/RhoSignature.cpp +1 -1
  101. data/platform/wm/rhodes/rho/rubyext/RhoSignature.h +1 -1
  102. data/platform/wm/rhodes/rho/rubyext/SystemImpl.cpp +14 -2
  103. data/platform/wm/rhodes/rho/rubyext/WebView.cpp +6 -3
  104. data/platform/wm/rhodes/rhodes.vcproj +5 -1
  105. data/platform/wm/rhodes/simulator/MainWindowQt.cpp +22 -1
  106. data/platform/wm/rhodes/simulator/MainWindowQt.h +4 -0
  107. data/platform/wp7/RhoRubyExtGen/RhoWebView.cs +1 -1
  108. data/platform/wp7/RhoRubyLib/Initializers.Generated.cs +1 -1
  109. data/platform/wp7/RhoRubyLib/common/RhodesApp.cs +33 -38
  110. data/platform/wp7/RhoRubyLib/net/HttpServer.cs +134 -29
  111. data/platform/wp7/RhoRubyLib/rubyext/RhoWebView.cs +12 -2
  112. data/platform/wp7/RhoRubyLib/sync/SyncSource.cs +17 -1
  113. data/platform/wp7/RhoRubyLib/views/RhoTabHeader.xaml +3 -3
  114. data/platform/wp7/RhoRubyLib/views/RhoView.xaml.cs +48 -8
  115. data/rakefile.rb +13 -2
  116. data/res/build-tools/iphonesim/build/Release/iphonesim_43 +0 -0
  117. data/res/build-tools/iphonesim/iphonesim.xcodeproj/project.pbxproj +158 -0
  118. data/res/generators/rhogen.rb +33 -28
  119. data/res/generators/templates/application/app/layout.erb +6 -5
  120. data/res/generators/templates/application/public/css/android.css +21 -315
  121. data/res/generators/templates/application/public/css/iphone.css +1 -499
  122. data/res/generators/templates/application/public/css/jqmobile-patch.css +18 -5
  123. data/res/generators/templates/application/public/css/windows_phone7.css +378 -0
  124. data/res/generators/templates/application/public/jqmobile/images/icons-18-black.png +0 -0
  125. data/res/generators/templates/application/public/jqmobile/images/icons-36-black.png +0 -0
  126. data/res/generators/templates/application/public/jqmobile/{jquery.mobile-1.0.css → jquery.mobile-1.0.1.css} +33 -11
  127. data/res/generators/templates/application/public/jqmobile/{jquery.mobile-1.0.js → jquery.mobile-1.0.1.js} +249 -125
  128. data/res/generators/templates/application/public/jqmobile/jquery.mobile-1.0.1.min.css +2 -0
  129. data/res/generators/templates/application/public/jqmobile/jquery.mobile-1.0.1.min.js +177 -0
  130. data/res/generators/templates/application/public/jqmobile/{jquery.mobile.structure-1.0.css → jquery.mobile.structure-1.0.1.css} +33 -11
  131. data/res/generators/templates/application/public/jqmobile/jquery.mobile.structure-1.0.1.min.css +2 -0
  132. data/res/generators/templates/application/public/jquery/jquery.json-2.3.js +193 -0
  133. data/res/generators/templates/application/public/jquery/jquery.json-2.3.min.js +23 -0
  134. data/res/generators/templates/application/public/js/jquery-wp7-patch.js +68 -20
  135. data/spec/phone_spec/app/Case/case.rb +22 -0
  136. data/spec/phone_spec/app/Customer/customer.rb +16 -0
  137. data/spec/phone_spec/app/spec/rhom_object_spec.rb +108 -11
  138. data/spec/phone_spec/app/spec/syncengine_spec.rb +43 -1
  139. data/spec/phone_spec/build.yml +2 -1
  140. data/version +1 -1
  141. metadata +27 -13
  142. data/platform/shared/common/ExtManager.cpp +0 -103
  143. data/res/generators/templates/application/public/jqmobile/jquery-mobile-iphone.css +0 -9
  144. data/res/generators/templates/application/public/jqmobile/jquery.mobile-1.0.min.css +0 -2
  145. data/res/generators/templates/application/public/jqmobile/jquery.mobile-1.0.min.js +0 -172
  146. data/res/generators/templates/application/public/jqmobile/jquery.mobile.structure-1.0.min.css +0 -2
@@ -118,6 +118,8 @@ public:
118
118
  void tabbarSwitch(int index);
119
119
  void tabbarBadge(int index, char* badge);
120
120
  int tabbarGetCurrent();
121
+ bool isExistJavascript(const wchar_t* szJSFunction, int index){return true;}
122
+
121
123
 
122
124
  BEGIN_MSG_MAP(CMainWindow)
123
125
  MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
@@ -130,6 +132,7 @@ public:
130
132
  COMMAND_ID_HANDLER(IDM_REFRESH, OnRefreshCommand)
131
133
  COMMAND_ID_HANDLER(IDM_NAVIGATE, OnNavigateCommand)
132
134
  COMMAND_ID_HANDLER(ID_SETCOOKIE, OnSetCookieCommand)
135
+ COMMAND_ID_HANDLER(IDM_EXECUTEJS, OnExecuteJS)
133
136
  MESSAGE_HANDLER(WM_TAKEPICTURE, OnTakePicture)
134
137
  MESSAGE_HANDLER(WM_SELECTPICTURE, OnSelectPicture)
135
138
  MESSAGE_HANDLER(WM_ALERT_SHOW_POPUP, OnAlertShowPopup)
@@ -153,6 +156,7 @@ private:
153
156
  LRESULT OnRefreshCommand(WORD /*wNotifyCode*/, WORD /*wID*/, HWND hWndCtl, BOOL& /*bHandled*/);
154
157
  LRESULT OnNavigateCommand(WORD /*wNotifyCode*/, WORD /*wID*/, HWND hWndCtl, BOOL& /*bHandled*/);
155
158
  LRESULT OnSetCookieCommand (WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/);
159
+ LRESULT OnExecuteJS(WORD /*wNotifyCode*/, WORD /*wID*/, HWND hWndCtl, BOOL& /*bHandled*/);
156
160
 
157
161
  LRESULT OnTakePicture(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/);
158
162
  LRESULT OnSelectPicture(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& /*bHandled*/);
@@ -53,7 +53,7 @@ namespace rho.rubyext
53
53
  }
54
54
 
55
55
  [RubyMethodAttribute("execute_js", RubyMethodAttributes.PublicSingleton)]
56
- public static void execute_js(RubyModule/*!*/ self, [NotNull]String/*!*/ strScript, int index = 0)
56
+ public static void execute_js(RubyModule/*!*/ self, [NotNull]String/*!*/ strScript, int index = 0, RubyArray vals = null)
57
57
  {
58
58
  }
59
59
 
@@ -467,7 +467,7 @@ namespace rho.rubyext {
467
467
 
468
468
  DefineLibraryMethod(module, "execute_js", 0x21,
469
469
  0x00000002U,
470
- new Action<IronRuby.Builtins.RubyModule, System.String, System.Int32>(rho.rubyext.RhoWebView.execute_js)
470
+ new Action<IronRuby.Builtins.RubyModule, System.String, System.Int32, IronRuby.Builtins.RubyArray>(rho.rubyext.RhoWebView.execute_js)
471
471
  );
472
472
 
473
473
  DefineLibraryMethod(module, "navigate", 0x21,
@@ -56,7 +56,9 @@ namespace rho.common
56
56
  private PhoneApplicationPage m_appMainPage;
57
57
  public PhoneApplicationPage MainPage { get { return m_appMainPage; } }
58
58
  private Grid m_layoutRoot;
59
- private TabControl m_tabControl;
59
+ //private TabControl m_tabControl;
60
+ private Pivot m_tabControl;
61
+ public Pivot Tab { get { return m_tabControl; } }
60
62
  private Stack<Uri> m_backHistory = new Stack<Uri>();
61
63
  private Stack<Uri> m_forwardHistory = new Stack<Uri>();
62
64
  private Hash m_menuItems = null;
@@ -85,6 +87,11 @@ namespace rho.common
85
87
  public String getBlobsDirPath() { return m_strBlobsDirPath; }
86
88
  public String getHomeUrl() { return m_strHomeUrl; }
87
89
 
90
+ private void Pivot_OnChanged(object sender, RoutedEventArgs e)
91
+ {
92
+ ((RhoView)(((PivotItem)m_tabControl.SelectedItem).Content)).refresh();
93
+ }
94
+
88
95
  public void Init(WebBrowser browser, PhoneApplicationPage appMainPage, Grid layoutRoot, RhoView rhoView)
89
96
  {
90
97
  initAppUrls();
@@ -225,11 +232,11 @@ namespace rho.common
225
232
  {
226
233
  if (m_tabControl != null && m_tabControl.Items.Count > 0)
227
234
  {
228
- ((RhoView)((TabItem)m_tabControl.Items[index]).Content).webBrowser1.IsScriptEnabled = true;
235
+ ((RhoView)((PivotItem)m_tabControl.Items[index]).Content).webBrowser1.IsScriptEnabled = true;
229
236
  if (isExternalUrl(strUrl))
230
- ((RhoView)((TabItem)m_tabControl.Items[index]).Content).webBrowser1.Navigate(new Uri(strUrl, UriKind.Absolute));
237
+ ((RhoView)((PivotItem)m_tabControl.Items[index]).Content).webBrowser1.Navigate(new Uri(strUrl, UriKind.Absolute));
231
238
  else
232
- ((RhoView)((TabItem)m_tabControl.Items[index]).Content).webBrowser1.Navigate(new Uri(strUrl, UriKind.Relative));
239
+ ((RhoView)((PivotItem)m_tabControl.Items[index]).Content).webBrowser1.Navigate(new Uri(strUrl, UriKind.Relative));
233
240
  }
234
241
  }
235
242
  else
@@ -258,7 +265,7 @@ namespace rho.common
258
265
  {
259
266
  if (m_tabControl != null && m_tabControl.Items.Count > 0)
260
267
  {
261
- ((RhoView)((TabItem)m_tabControl.Items[index]).Content).webBrowser1.Navigate(m_webBrowser.Source);
268
+ ((RhoView)((PivotItem)m_tabControl.Items[index]).Content).webBrowser1.Navigate(m_webBrowser.Source);
262
269
  }
263
270
  }
264
271
  else
@@ -273,37 +280,21 @@ namespace rho.common
273
280
  });
274
281
  }
275
282
 
276
- public void processInvokeScript(String strScript, int index)
277
- {
278
- String[] arr = strScript.Split('(');
279
- String[] arrParams = null;
280
- if (arr.Length > 1)
281
- {
282
- arrParams = arr[1].Split(',');
283
- if (arrParams.Length == 1)
284
- {
285
- arrParams[0] = arrParams[0].Replace('"', ' ');
286
- arrParams[0] = arrParams[0].Replace(')', ' ');
287
- arrParams[0] = arrParams[0].Replace(';', ' ');
288
- arrParams[0] = arrParams[0].Trim();
289
- }
290
- }
291
-
292
- processInvokeScriptArgs(arr[0], arrParams, index);
293
- }
294
283
 
295
284
  public void processInvokeScriptArgs(String strFuncName, String[] arrParams, int index)
296
285
  {
286
+ if (null != strFuncName && 0 < strFuncName.Length && (null == arrParams || 0 == arrParams.Length))
287
+ {
288
+ arrParams = new String[]{strFuncName};
289
+ strFuncName = CHttpServer.JS_EVAL_FUNCNAME;
290
+ }
297
291
  m_webBrowser.Dispatcher.BeginInvoke(() =>
298
292
  {
299
293
  try
300
294
  {
301
- if (index > 0)
295
+ if (index >= 0 && m_tabControl != null && m_tabControl.Items.Count > 0)
302
296
  {
303
- if (m_tabControl != null && m_tabControl.Items.Count > 0)
304
- {
305
- ((RhoView)((TabItem)m_tabControl.Items[index]).Content).webBrowser1.InvokeScript(strFuncName, arrParams);
306
- }
297
+ ((RhoView)((PivotItem)m_tabControl.Items[index]).Content).webBrowser1.InvokeScript(strFuncName, arrParams);
307
298
  }
308
299
  else
309
300
  {
@@ -694,16 +685,17 @@ namespace rho.common
694
685
  // continue;
695
686
 
696
687
 
697
- //tabItem.Header = "Test";to do
698
- TabItem tabItem = new TabItem();
699
- tabItem.Header = new RhoTabHeader(label, icon);
688
+ //PivotItem.Header = "Test";to do
689
+ //PivotItem PivotItem = new PivotItem();
690
+ PivotItem PivotItem = new PivotItem();
691
+ PivotItem.Header = new RhoTabHeader(label, icon);
700
692
  //if (i == 0)// && use_current_view_for_tab)
701
- tabItem.Content = new RhoView(m_appMainPage, m_layoutRoot, action, reload, web_bkg_color);
693
+ PivotItem.Content = new RhoView(m_appMainPage, m_layoutRoot, action, reload, web_bkg_color, i);
702
694
  if (values.TryGetValue(CRhoRuby.CreateSymbol("selected_color"), out val))
703
- tabItem.Background = new SolidColorBrush(getColorFromString(val.ToString()));
695
+ PivotItem.Background = new SolidColorBrush(getColorFromString(val.ToString()));
704
696
  if (values.TryGetValue(CRhoRuby.CreateSymbol("disabled"), out val))
705
- tabItem.IsEnabled = !Convert.ToBoolean(val);
706
- m_tabControl.Items.Add(tabItem);
697
+ PivotItem.IsEnabled = !Convert.ToBoolean(val);
698
+ m_tabControl.Items.Add(PivotItem);
707
699
  }
708
700
  }
709
701
  }
@@ -712,11 +704,14 @@ namespace rho.common
712
704
  {
713
705
  m_appMainPage.Dispatcher.BeginInvoke( () =>
714
706
  {
715
- m_tabControl = new TabControl();
707
+ /*m_tabControl = new TabControl();
716
708
  if (tabBarType == 1)
717
709
  m_tabControl.TabStripPlacement = Dock.Top;
718
710
  else if (tabBarType == 3)
719
- m_tabControl.TabStripPlacement = Dock.Left;
711
+ m_tabControl.TabStripPlacement = Dock.Left;*/
712
+
713
+ m_tabControl = new Pivot();
714
+ m_tabControl.SelectionChanged += Pivot_OnChanged;
720
715
 
721
716
  Object[] hashArray = null;
722
717
  Hash paramHash = null;
@@ -770,7 +765,7 @@ namespace rho.common
770
765
  if (m_tabControl != null)
771
766
  {
772
767
  //TO DO
773
- //((TabItem)m_tabControl.Items[index]).Header
768
+ //((PivotItem)m_tabControl.Items[index]).Header
774
769
  }
775
770
  });
776
771
  }
@@ -28,6 +28,8 @@ using System;
28
28
  using rho.common;
29
29
  using rho;
30
30
  using System.Collections.Generic;
31
+ using System.Collections;
32
+ using System.Text;
31
33
 
32
34
  namespace rho.net
33
35
  {
@@ -41,6 +43,17 @@ namespace rho.net
41
43
  static CRhodesApp RHODESAPP() { return CRhodesApp.Instance; }
42
44
  private CRhoRuby RhoRuby { get { return CRhoRuby.Instance; } }
43
45
 
46
+ static public String HTTP_REDIRECT_CODE = "302";
47
+ static public String PARAM_PREFIX_REQ = "request-";
48
+ static public String PARAM_PREFIX_RESP = "response-";
49
+ static public String RESPONSE_BODY_FILEPATH = "response-body-filepath";
50
+ static public String JS_EVAL_FUNCNAME = "_rho_execJsWrapper";
51
+ static public String AJAX_CALLBACK_FUNCNAME = "_rho_ajaxProxyCallback";
52
+ static public String AJAX_PARAM_CALLBACK_ID = "_rho_callbackId";
53
+ static public String AJAX_PARAM_RESPONSE = "response";
54
+ static public String AJAX_PARAM_STATUS = "status";
55
+ static public String AJAX_PARAM_MESSAGE = "message";
56
+
44
57
  class CRoute
45
58
  {
46
59
  public String application = "";
@@ -64,6 +77,7 @@ namespace rho.net
64
77
  class CServerCommand : IQueueCommand
65
78
  {
66
79
  String m_method, m_uri, m_query, m_body;
80
+ Dictionary<String, String> m_headers;
67
81
  CRoute m_route;
68
82
  CHttpServer m_Parent;
69
83
  int m_nCommand;
@@ -72,27 +86,78 @@ namespace rho.net
72
86
  public const int scDispatch = 1, scIndex = 2;
73
87
 
74
88
  public CServerCommand(CHttpServer Parent, CRoute route,
75
- String method, String uri, String query, String body, int nCommand, String strAjaxContext)
89
+ String method, String uri, IDictionary headers, IDictionary data, int nCommand, String strAjaxContext)
76
90
  {
77
91
  m_Parent = Parent;
78
- m_method = method;
79
- m_uri = uri;
80
- m_query = query;
81
- m_body = body;
92
+ m_method = (null != method) ? method.toUpperCase() : "GET";
93
+ m_uri = (0 <= uri.indexOf('?')) ? uri.substring(0, uri.indexOf('?')) : uri;
82
94
  m_route = route;
83
95
  m_nCommand = nCommand;
84
96
  m_strAjaxContext = strAjaxContext;
97
+
98
+ m_body = "";
99
+
100
+ m_headers = new Dictionary<String, String>();
101
+ if (null != headers)
102
+ {
103
+ foreach (object key in headers.Keys)
104
+ {
105
+ m_headers[key.ToString()] = headers[key].ToString();
106
+ }
107
+ }
108
+
109
+ // Query parameters from URL are added first, then data parameters added.
110
+ m_query = (0 <= uri.indexOf('?')) ? uri.substring(uri.indexOf('?') + 1) : "";
111
+ if (null != data)
112
+ {
113
+ StringBuilder sb = new StringBuilder(m_query);
114
+ foreach (object key in data.Keys)
115
+ {
116
+ if (0 < sb.Length) sb.Append("&");
117
+ sb.Append(key.ToString() + "=" + (null != data[key] ? data[key].ToString() : ""));
118
+ }
119
+ m_query = sb.ToString();
120
+ }
121
+ }
122
+
123
+ public boolean isAjaxRequest()
124
+ {
125
+ return (m_strAjaxContext != null && 0 < m_strAjaxContext.length());
85
126
  }
86
127
 
87
128
  public void execute()
88
129
  {
89
130
  String strUrl = "";
90
- if (m_nCommand == scDispatch )
91
- strUrl = m_Parent.processDispatch(m_route, m_method, m_uri, m_query, m_body);
92
- else if ( m_nCommand == scIndex )
93
- strUrl = m_Parent.processIndex(m_route, m_method, m_uri, m_query, m_body);
131
+ IDictionary result = null;
132
+ if (m_nCommand == scDispatch)
133
+ {
134
+ result = m_Parent.processDispatch(m_route, m_method, m_uri, m_headers, m_query, m_body);
135
+ strUrl = result[RESPONSE_BODY_FILEPATH].ToString();
136
+
137
+ if (isAjaxRequest() && result[AJAX_PARAM_STATUS].ToString().equals(HTTP_REDIRECT_CODE))
138
+ {
139
+ IDictionary headers = new Dictionary<String, String>();
140
+ headers["X-Requested-With"] = "XMLHttpRequest";
141
+ if (!RHODESAPP().HttpServer.processBrowserRequest(
142
+ "GET",
143
+ new Uri(strUrl, UriKind.Relative),
144
+ headers,
145
+ new Dictionary<String, String>(),
146
+ m_strAjaxContext
147
+ ))
148
+ {
149
+ LOG.ERROR("Ajax request redirection failed.");
150
+ }
151
+ return;
152
+ }
153
+ }
154
+ else if (m_nCommand == scIndex)
155
+ {
156
+ result = m_Parent.processIndex(m_route, m_method, m_uri, m_headers, m_query, m_body);
157
+ strUrl = result[RESPONSE_BODY_FILEPATH].ToString();
158
+ }
94
159
 
95
- if (m_strAjaxContext == null || m_strAjaxContext.length() == 0)
160
+ if (!isAjaxRequest())
96
161
  {
97
162
  RHODESAPP().processWebNavigate(strUrl, -1);
98
163
  }
@@ -100,13 +165,31 @@ namespace rho.net
100
165
  {
101
166
  String res = CRhoFile.isResourceFileExist(strUrl) ? CRhoFile.readStringFromResourceFile(strUrl) : CRhoFile.readFileToString(strUrl);
102
167
 
103
- String[] args = new String[4];
168
+
169
+ IDictionary headers = new Dictionary<String, String>();
170
+ StringBuilder jsonHeaders = new StringBuilder();
171
+ foreach (object key in result.Keys)
172
+ {
173
+ if (
174
+ key.ToString().startsWith(PARAM_PREFIX_REQ)
175
+ || key.ToString().startsWith(PARAM_PREFIX_RESP)
176
+ || key.ToString().equals(AJAX_PARAM_MESSAGE)
177
+ || key.ToString().equals(AJAX_PARAM_STATUS)
178
+ ) continue;
179
+ headers[key.ToString()] = result[key].ToString();
180
+ jsonHeaders.AppendFormat("{0}\"{1}\": \"{2}\"",
181
+ (0 < jsonHeaders.Length) ? ", " : "",
182
+ key.ToString(), result[key].ToString());
183
+ }
184
+
185
+ String[] args = new String[5];
104
186
  args[0] = m_strAjaxContext;
105
187
  args[1] = res;
106
- args[2] = "ok";
107
- args[3] = "200";
188
+ args[2] = "{" + jsonHeaders + "}";
189
+ args[3] = result[AJAX_PARAM_MESSAGE].ToString();
190
+ args[4] = result[AJAX_PARAM_STATUS].ToString();
108
191
 
109
- RHODESAPP().processInvokeScriptArgs("_rho_ajaxProxyCallback", args, RHODESAPP().getCurrentTab());
192
+ RHODESAPP().processInvokeScriptArgs(AJAX_CALLBACK_FUNCNAME, args, RHODESAPP().getCurrentTab());
110
193
  }
111
194
  }
112
195
 
@@ -140,6 +223,11 @@ namespace rho.net
140
223
  }
141
224
 
142
225
  public boolean processBrowserRequest(Uri uri, String strAjaxContext)
226
+ {
227
+ return processBrowserRequest("get", uri, null, null, strAjaxContext);
228
+ }
229
+
230
+ public boolean processBrowserRequest(String reqType, Uri uri, IDictionary headers, IDictionary data, String strAjaxContext)
143
231
  {
144
232
  boolean bAjaxCall = !(strAjaxContext == null || strAjaxContext.length() == 0);
145
233
 
@@ -168,7 +256,10 @@ namespace rho.net
168
256
  CRoute route = new CRoute();
169
257
  if (dispatch(url, route))
170
258
  {
171
- addQueueCommand(new CServerCommand(this, route, bAjaxCall ? "GET" : "GET", url, query, "", CServerCommand.scDispatch, strAjaxContext));
259
+ addQueueCommand(new CServerCommand(this, route, reqType,
260
+ url + (0 < query.Length ? ("?"+query) : ""),
261
+ headers, data, CServerCommand.scDispatch, strAjaxContext));
262
+ //addQueueCommand(new CServerCommand(this, route, bAjaxCall ? "GET" : "GET", url, query, "", CServerCommand.scDispatch, strAjaxContext));
172
263
 
173
264
  return true;
174
265
  }
@@ -178,7 +269,8 @@ namespace rho.net
178
269
  String strIndexFile = getIndex(fullPath);
179
270
  if (strIndexFile.Length > 0)
180
271
  {
181
- addQueueCommand(new CServerCommand(this, route, bAjaxCall ? "GET" : "GET", url, query, "", CServerCommand.scIndex, strAjaxContext));
272
+ addQueueCommand(new CServerCommand(this, route, reqType, url, headers, data, CServerCommand.scIndex, strAjaxContext));
273
+ //addQueueCommand(new CServerCommand(this, route, bAjaxCall ? "GET" : "GET", url, query, "", CServerCommand.scIndex, strAjaxContext));
182
274
 
183
275
  return true;
184
276
  }
@@ -186,14 +278,17 @@ namespace rho.net
186
278
  return false;
187
279
  }
188
280
 
189
- String processDispatch(CRoute route, String method, String uri, String query, String body)
281
+ IDictionary processDispatch(CRoute route, String method, String uri, Dictionary<String, String> headers, String query, String body)
190
282
  {
191
- Object rhoReq = create_request_hash(route, method, uri, query, null, body);
283
+ Object rhoReq = create_request_hash(route, method, uri, query, headers, body);
192
284
  Object rhoResp = RhoRuby.callServe(rhoReq);
193
285
 
194
286
  String strRedirectUrl = getRedirectUrl(rhoResp);
195
287
  if (strRedirectUrl.Length > 0)
196
- return strRedirectUrl;
288
+ {
289
+ ((IDictionary)rhoResp)[RESPONSE_BODY_FILEPATH] = strRedirectUrl;
290
+ return (IDictionary)rhoResp;
291
+ }
197
292
 
198
293
  String strFilePath = RHODESAPP().canonicalizeRhoPath(uri) + ".gen.html";
199
294
  if (route.id.Length > 0)
@@ -204,12 +299,14 @@ namespace rho.net
204
299
 
205
300
  if (method == "GET")
206
301
  RHODESAPP().keepLastVisitedUrl(uri);
207
-
208
- return strFilePath;
302
+ ((IDictionary)rhoResp)[RESPONSE_BODY_FILEPATH] = strFilePath;
303
+ return (IDictionary)rhoResp;
209
304
  }
210
305
 
211
- String processIndex(CRoute route, String method, String uri, String query, String body)
306
+ IDictionary processIndex(CRoute route, String method, String uri, Dictionary<String, String> headers, String query, String body)
212
307
  {
308
+ Object rhoResp = new Dictionary<String, String>();
309
+
213
310
  String fullPath = uri.StartsWith(m_root) ? uri : CFilePath.join(m_root, uri);
214
311
  String strIndexFile = getIndex(fullPath);
215
312
 
@@ -219,18 +316,25 @@ namespace rho.net
219
316
  String strFilePath = CFilePath.join(m_root, "rhodes_error") + ".gen.html";
220
317
  CRhoFile.recursiveCreateDir(strFilePath);
221
318
  CRhoFile.writeStringToFile(strFilePath, error);
222
- return strFilePath;
319
+ ((IDictionary)rhoResp)[RESPONSE_BODY_FILEPATH] = strFilePath;
320
+ return (IDictionary)rhoResp;
223
321
  }
224
322
 
225
323
  if (CFilePath.getExtension(fullPath).Length > 0)
226
- return strIndexFile;
324
+ {
325
+ ((IDictionary)rhoResp)[RESPONSE_BODY_FILEPATH] = strIndexFile;
326
+ return (IDictionary)rhoResp;
327
+ }
227
328
 
228
- Object rhoReq = create_request_hash(route, method, uri, query, null, body);
229
- Object rhoResp = RhoRuby.callServeIndex(strIndexFile, rhoReq);
329
+ Object rhoReq = create_request_hash(route, method, uri, query, headers, body);
330
+ rhoResp = RhoRuby.callServeIndex(strIndexFile, rhoReq);
230
331
 
231
332
  String strRedirectUrl = getRedirectUrl(rhoResp);
232
333
  if (strRedirectUrl.Length > 0)
233
- return strRedirectUrl;
334
+ {
335
+ ((IDictionary)rhoResp)[RESPONSE_BODY_FILEPATH] = strRedirectUrl;
336
+ return (IDictionary)rhoResp;
337
+ }
234
338
 
235
339
  strIndexFile += ".gen.html";
236
340
  CRhoFile.recursiveCreateDir(strIndexFile);
@@ -239,7 +343,8 @@ namespace rho.net
239
343
  if (method == "GET")
240
344
  RHODESAPP().keepLastVisitedUrl(uri);
241
345
 
242
- return strIndexFile;
346
+ ((IDictionary)rhoResp)[RESPONSE_BODY_FILEPATH] = strIndexFile;
347
+ return (IDictionary)rhoResp;
243
348
  }
244
349
  /*
245
350
  CResponse decide(String method, String uri, String query, String body)
@@ -493,7 +598,7 @@ namespace rho.net
493
598
  }
494
599
  RhoRuby.hashAdd(hash, "headers", hash_headers);
495
600
 
496
- if ( body.Length > 0 )
601
+ if ( null != body && body.Length > 0 )
497
602
  RhoRuby.hashAdd(hash, "request-body", body);
498
603
 
499
604
  return hash;