calatrava 0.6.3 → 0.6.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. data/.gitignore +1 -1
  2. data/.ruby-gemset +1 -0
  3. data/.ruby-version +1 -0
  4. data/.travis.yml +4 -0
  5. data/CHANGES.markdown +67 -0
  6. data/Gemfile +1 -1
  7. data/Gemfile.lock +100 -0
  8. data/README.md +39 -3
  9. data/Rakefile +4 -0
  10. data/Vagrantfile +106 -0
  11. data/calatrava.gemspec +9 -4
  12. data/features/cli.feature +9 -0
  13. data/features/project.feature +15 -3
  14. data/features/sample_app.feature +5 -1
  15. data/features/support/calatrava_app.rb +1 -1
  16. data/features/support/env.rb +1 -1
  17. data/lib/calatrava/apache.rb +10 -31
  18. data/lib/calatrava/app.rb +7 -3
  19. data/lib/calatrava/app_builder.rb +11 -12
  20. data/lib/calatrava/configuration.rb +23 -6
  21. data/lib/calatrava/droid_app.rb +11 -2
  22. data/lib/calatrava/ios_app.rb +8 -1
  23. data/lib/calatrava/manifest.rb +0 -20
  24. data/lib/calatrava/mobile_web_app.rb +13 -9
  25. data/lib/calatrava/output_file.rb +53 -0
  26. data/lib/calatrava/platform.rb +12 -0
  27. data/lib/calatrava/project.rb +31 -3
  28. data/lib/calatrava/project_script.rb +15 -6
  29. data/lib/calatrava/tasks/assets.rb +2 -1
  30. data/lib/calatrava/tasks/bootstrap.rb +2 -3
  31. data/lib/calatrava/tasks/rake.rb +24 -0
  32. data/lib/calatrava/tasks.rb +1 -9
  33. data/lib/calatrava/templates/.ruby-gemset.calatrava +1 -0
  34. data/lib/calatrava/templates/.ruby-version +1 -0
  35. data/lib/calatrava/templates/droid/app/bridge.coffee +1 -1
  36. data/lib/calatrava/templates/droid/calatrava/CALATRAVA_TMPL/AndroidManifest.xml.calatrava +3 -4
  37. data/lib/calatrava/templates/droid/calatrava/CALATRAVA_TMPL/build.xml.calatrava +0 -4
  38. data/lib/calatrava/templates/droid/calatrava/ant/calatrava.xml +7 -3
  39. data/lib/calatrava/templates/droid/calatrava/{ivy.xml → ivy/ivy.xml} +0 -0
  40. data/lib/calatrava/templates/droid/calatrava/{ivysettings.xml → ivy/ivysettings.xml} +0 -0
  41. data/lib/calatrava/templates/droid/calatrava/src/com/CALATRAVA_TMPL/Bootstrap.java.calatrava +21 -0
  42. data/lib/calatrava/templates/droid/calatrava/src/com/CALATRAVA_TMPL/Title.java.calatrava +8 -15
  43. data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/bridge/CalatravaApplication.java +87 -0
  44. data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/bridge/PageRegistry.java +12 -9
  45. data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/bridge/PluginRegistry.java +11 -5
  46. data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/bridge/RegisteredActivity.java +6 -15
  47. data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/bridge/RegisteredPlugin.java +1 -1
  48. data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/bridge/RhinoService.java +27 -41
  49. data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/shell/WebViewActivity.java +7 -8
  50. data/lib/calatrava/templates/ios/Podfile.calatrava +1 -1
  51. data/lib/calatrava/templates/ios/src/AppDelegate.h +6 -1
  52. data/lib/calatrava/templates/ios/src/AppDelegate.m +20 -0
  53. data/lib/calatrava/templates/kernel/app/calatrava.coffee +13 -5
  54. data/lib/calatrava/templates/kernel/plugins/alert.coffee +4 -1
  55. data/lib/calatrava/templates/kernel/spec/converter/controller.converter.spec.coffee +1 -1
  56. data/lib/calatrava/templates/kernel/spec/stubView.coffee +17 -3
  57. data/lib/calatrava/templates/package.json +0 -1
  58. data/lib/calatrava/templates/shell/pages/converter/page.conversionForm.coffee +7 -2
  59. data/lib/calatrava/templates/web/app/source/bridge.coffee +7 -7
  60. data/lib/calatrava/templates/web/app/source/init.coffee +1 -1
  61. data/lib/calatrava/version.rb +1 -1
  62. data/lib/calatrava.rb +4 -0
  63. data/spec/app_builder_spec.rb +2 -2
  64. data/spec/mobile_web_app_spec.rb +1 -1
  65. data/spec/output_file_spec.rb +33 -0
  66. metadata +104 -35
  67. data/.rvmrc +0 -2
  68. data/lib/calatrava/templates/.rvmrc.calatrava +0 -2
  69. data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/bridge/Launcher.java +0 -86
  70. data/lib/calatrava/templates/ios/res/xibs/ProgressViewController.xib +0 -334
  71. data/lib/calatrava/templates/ios/res/xibs/WebViewController.xib +0 -173
  72. data/lib/calatrava/templates/web/deploy/instance.sh +0 -10
@@ -0,0 +1,87 @@
1
+ package com.calatrava.bridge;
2
+
3
+ import android.app.Application;
4
+ import android.content.Context;
5
+ import android.content.pm.PackageManager;
6
+ import android.util.Log;
7
+
8
+ import java.io.BufferedReader;
9
+ import java.io.IOException;
10
+ import java.io.InputStream;
11
+ import java.io.InputStreamReader;
12
+ import java.net.URISyntaxException;
13
+
14
+ public class CalatravaApplication extends Application
15
+ {
16
+ private static String TAG = CalatravaApplication.class.getSimpleName();
17
+ private RhinoService rhino;
18
+
19
+ public void bootCalatrava(String appName)
20
+ {
21
+ rhino = new RhinoService(this);
22
+ try
23
+ {
24
+ PageRegistry.setSharedRegistry(new PageRegistry(appName, this, rhino));
25
+ PluginRegistry.setSharedRegistry(new PluginRegistry(appName, this, rhino));
26
+ AjaxRequestManager.setSharedManager(new AjaxRequestManager(this, rhino));
27
+
28
+ initBridge();
29
+ } catch (Exception e)
30
+ {
31
+ Log.wtf(TAG, "Unable to boot Calatrava.", e);
32
+ }
33
+ }
34
+
35
+ public void provideActivityContext(Context activityContext)
36
+ {
37
+ PageRegistry.sharedRegistry().updateContext(activityContext);
38
+ PluginRegistry.sharedRegistry().updateContext(activityContext);
39
+ }
40
+
41
+ public void launchFlow(String flow)
42
+ {
43
+ rhino.callJsFunction(flow);
44
+ }
45
+
46
+ private void initBridge()
47
+ {
48
+ AssetRepository assets = new AssetRepository(this);
49
+
50
+ BufferedReader loadFileReader = null;
51
+ try
52
+ {
53
+ rhino.initRhino(this);
54
+ // Load all the application JS
55
+ InputStream inputStream = this.getAssets().open("calatrava/load_file.txt");
56
+ loadFileReader = new BufferedReader(new InputStreamReader(inputStream), 8192);
57
+ KernelBridge bridge = new KernelBridge(assets, rhino);
58
+ String line;
59
+ while ((line = loadFileReader.readLine()) != null)
60
+ {
61
+ bridge.loadLibrary(line);
62
+ }
63
+
64
+ } catch (IOException e) {
65
+ Log.d(TAG, "LauncherActivity failed to start", e);
66
+ }
67
+ finally
68
+ {
69
+ if (loadFileReader != null)
70
+ {
71
+ try
72
+ {
73
+ loadFileReader.close();
74
+ }
75
+ catch(IOException e)
76
+ {
77
+ Log.e(TAG, "Unable to close load_file.txt", e);
78
+ }
79
+ }
80
+ }
81
+ }
82
+
83
+ public RhinoService getRhino()
84
+ {
85
+ return rhino;
86
+ }
87
+ }
@@ -1,6 +1,5 @@
1
1
  package com.calatrava.bridge;
2
2
 
3
- import android.app.Application;
4
3
  import android.content.Context;
5
4
  import android.content.Intent;
6
5
  import android.net.Uri;
@@ -22,7 +21,7 @@ public class PageRegistry {
22
21
  public static String TAG = PageRegistry.class.getSimpleName();
23
22
  private static PageRegistry sharedRegistry;
24
23
 
25
- private Context appContext;
24
+ private Context activityContext;
26
25
  private RhinoService rhino;
27
26
  private Map<String, Class<?>> pageFactories = new HashMap<String, Class<?>>();
28
27
  private Map<String, RegisteredPage> registeredPages = new HashMap<String, RegisteredPage>();
@@ -37,10 +36,9 @@ public class PageRegistry {
37
36
  sharedRegistry = shared;
38
37
  }
39
38
 
40
- public PageRegistry(String appName, Context appContext, Application app, RhinoService rhino)
39
+ public PageRegistry(String appName, Context appContext, RhinoService rhino)
41
40
  throws IOException, URISyntaxException, ClassNotFoundException, NameNotFoundException
42
41
  {
43
- this.appContext = appContext;
44
42
  this.rhino = rhino;
45
43
 
46
44
  // Find all the logical page classes in the app
@@ -48,6 +46,11 @@ public class PageRegistry {
48
46
  addPages(appName, appContext);
49
47
  }
50
48
 
49
+ public void updateContext(Context activityContext)
50
+ {
51
+ this.activityContext = activityContext;
52
+ }
53
+
51
54
  private void addPages(String packageName, Context context)
52
55
  throws IOException, URISyntaxException, ClassNotFoundException, NameNotFoundException
53
56
  {
@@ -74,7 +77,7 @@ public class PageRegistry {
74
77
  Log.d(TAG, "changePage('" + target + "')");
75
78
  Class activityClass = pageFactories.get(target);
76
79
  Log.d(TAG, "Activity to be started: " + activityClass.getSimpleName());
77
- appContext.startActivity(new Intent(appContext, activityClass));
80
+ activityContext.startActivity(new Intent(activityContext, activityClass));
78
81
  }
79
82
 
80
83
  public void triggerEvent(String pageName, String event, String... extraArgs) {
@@ -84,21 +87,21 @@ public class PageRegistry {
84
87
  }
85
88
 
86
89
  public void displayWidget(String name, String options) {
87
- appContext.sendBroadcast(new Intent("com.calatrava.widget").putExtra("name", name).putExtra("options", options));
90
+ activityContext.sendBroadcast(new Intent("com.calatrava.widget").putExtra("name", name).putExtra("options", options));
88
91
  }
89
92
 
90
93
  public void displayDialog(String dialogName) {
91
- appContext.sendBroadcast(new Intent("com.calatrava.dialog").putExtra("name", dialogName));
94
+ activityContext.sendBroadcast(new Intent("com.calatrava.dialog").putExtra("name", dialogName));
92
95
  }
93
96
 
94
97
  public void alert(String message) {
95
98
  Log.d(TAG, "Broadcasting alert message: '" + message + "'");
96
- appContext.sendBroadcast(new Intent("com.calatrava.alert").putExtra("message", message));
99
+ activityContext.sendBroadcast(new Intent("com.calatrava.alert").putExtra("message", message));
97
100
  }
98
101
 
99
102
  public void openUrl(String url) {
100
103
  Intent browser = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
101
- appContext.startActivity(browser);
104
+ activityContext.startActivity(browser);
102
105
  }
103
106
 
104
107
  public void track(String pageName, String channel, String eventName, Object variables, Object properties) {
@@ -19,7 +19,7 @@ public class PluginRegistry {
19
19
  public static String TAG = PluginRegistry.class.getSimpleName();
20
20
  private static PluginRegistry sharedRegistry;
21
21
 
22
- private Context appContext;
22
+ private Context activityContext;
23
23
  private RhinoService rhino;
24
24
  private Map<String, RegisteredPlugin> registeredPlugins = new HashMap<String, RegisteredPlugin>();
25
25
  private Map<String, PluginCommand> installedCmds = new HashMap<String, PluginCommand>();
@@ -37,7 +37,6 @@ public class PluginRegistry {
37
37
  public PluginRegistry(String packageName, Context appContext, RhinoService rhino)
38
38
  throws IOException, URISyntaxException, ClassNotFoundException, NameNotFoundException
39
39
  {
40
- this.appContext = appContext;
41
40
  this.rhino = rhino;
42
41
 
43
42
  // Find all the plugins to register in the app
@@ -58,9 +57,7 @@ public class PluginRegistry {
58
57
  Log.d(TAG, "Registering Calatrava plugin: " + pluginName);
59
58
  try
60
59
  {
61
- RegisteredPlugin plugin = (RegisteredPlugin)toRegister.newInstance();
62
- plugin.setContext(PluginRegistry.this, appContext);
63
- registeredPlugins.put(pluginName, plugin);
60
+ registeredPlugins.put(pluginName, (RegisteredPlugin)toRegister.newInstance());
64
61
  }
65
62
  catch (Exception e)
66
63
  {
@@ -109,4 +106,13 @@ public class PluginRegistry {
109
106
  {
110
107
  rhino.callJsFunction("calatrava.inbound.invokePluginCallback", new String[] {callbackHandle, data.toString()});
111
108
  }
109
+
110
+ public void updateContext(Context activityContext)
111
+ {
112
+ this.activityContext = activityContext;
113
+ for (RegisteredPlugin plugin : registeredPlugins.values())
114
+ {
115
+ plugin.setContext(PluginRegistry.this, activityContext);
116
+ }
117
+ }
112
118
  }
@@ -11,16 +11,6 @@ public abstract class RegisteredActivity extends Activity {
11
11
 
12
12
  private RhinoService rhino;
13
13
  private RequestLoader spinner = new RequestLoader(this);
14
- private ServiceConnection connection = new ServiceConnection() {
15
- public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
16
- rhino = ((RhinoService.LocalBinder) iBinder).getService();
17
- RegisteredActivity.this.onRhinoConnected(rhino);
18
- }
19
-
20
- public void onServiceDisconnected(ComponentName componentName) {
21
-
22
- }
23
- };
24
14
 
25
15
  private BroadcastReceiver receiver = new BroadcastReceiver() {
26
16
  @Override
@@ -39,8 +29,7 @@ public abstract class RegisteredActivity extends Activity {
39
29
  @Override
40
30
  protected void onCreate(Bundle availableData) {
41
31
  super.onCreate(availableData);
42
- Intent serviceIntent = new Intent(this, RhinoService.class);
43
- bindService(serviceIntent, connection, Context.BIND_AUTO_CREATE);
32
+ rhino = ((CalatravaApplication)getApplication()).getRhino();
44
33
  }
45
34
 
46
35
  @Override
@@ -60,7 +49,6 @@ public abstract class RegisteredActivity extends Activity {
60
49
  @Override
61
50
  public void onDestroy() {
62
51
  super.onDestroy();
63
- unbindService(connection);
64
52
  }
65
53
 
66
54
  public void triggerEvent(String event, String... extraArgs) {
@@ -71,11 +59,14 @@ public abstract class RegisteredActivity extends Activity {
71
59
  rhino.callJsFunction("calatrava.inbound.invokeCallback", args);
72
60
  }
73
61
 
74
- protected abstract void onRhinoConnected(RhinoService rhino);
75
-
76
62
  protected abstract String getPageName();
77
63
 
78
64
  public abstract String getFieldValue(String field);
79
65
 
80
66
  public abstract void render(final String json);
67
+
68
+ public RhinoService getRhino()
69
+ {
70
+ return rhino;
71
+ }
81
72
  }
@@ -3,7 +3,7 @@ package com.calatrava.bridge;
3
3
  import android.content.Context;
4
4
  import java.util.Map;
5
5
 
6
- interface RegisteredPlugin
6
+ public interface RegisteredPlugin
7
7
  {
8
8
  void setContext(PluginRegistry registry, Context ctxt);
9
9
  void call(String method, Map<String, Object> args);
@@ -1,8 +1,9 @@
1
1
  package com.calatrava.bridge;
2
2
 
3
- import android.app.Service;
4
- import android.content.Intent;
5
- import android.os.*;
3
+ import android.app.Activity;
4
+ import android.content.AbstractThreadedSyncAdapter;
5
+ import android.os.Handler;
6
+ import android.os.Looper;
6
7
  import android.util.Log;
7
8
  import org.mozilla.javascript.Context;
8
9
  import org.mozilla.javascript.Scriptable;
@@ -14,46 +15,43 @@ import java.lang.String;
14
15
  import java.lang.ThreadGroup;
15
16
  import java.util.concurrent.CountDownLatch;
16
17
 
17
- public class RhinoService extends Service {
18
+ public class RhinoService {
18
19
  public static String TAG = RhinoService.class.getSimpleName();
19
20
 
20
21
  private Scriptable mScope;
21
22
  private JSEvalThread evaller = new JSEvalThread();
22
23
 
23
- private final IBinder mBinder = new LocalBinder();
24
-
25
24
  CountDownLatch countDownLatch = new CountDownLatch(1);
26
25
 
27
- @Override
28
- public IBinder onBind(Intent intent) {
29
- return mBinder;
26
+ public RhinoService(android.content.Context activity) {
27
+ initRhino(activity);
30
28
  }
31
29
 
32
- @Override
33
- public void onCreate() {
34
- super.onCreate();
35
- Log.d(TAG, "RhinoService created.");
36
- }
37
-
38
- public void initRhino() {
30
+ public void initRhino(android.content.Context homeContext) {
39
31
  Context ctxt = enterContext();
40
32
  try {
41
33
  mScope = ctxt.initStandardObjects();
42
34
 
43
- Object wrappedRegistry = Context.javaToJS(PageRegistry.sharedRegistry(), mScope);
44
- ScriptableObject.putProperty(mScope, "pageRegistry", wrappedRegistry);
45
- ScriptableObject.putProperty(mScope, "pluginRegistry", Context.javaToJS(PluginRegistry.sharedRegistry(), mScope));
46
- ScriptableObject.putProperty(mScope, "androidRuntime", this);
47
-
48
- Object wrappedAjaxRequestManagerRegistry = Context.javaToJS(AjaxRequestManager.sharedManager(), mScope);
49
- ScriptableObject.putProperty(mScope, "ajaxRequestManagerRegistry", wrappedAjaxRequestManagerRegistry);
50
-
51
- evaller.start();
52
- try {
35
+ ScriptableObject.putProperty(mScope,
36
+ "pageRegistry",
37
+ Context.javaToJS(PageRegistry.sharedRegistry(), mScope));
38
+ ScriptableObject.putProperty(mScope,
39
+ "pluginRegistry",
40
+ Context.javaToJS(PluginRegistry.sharedRegistry(), mScope));
41
+ ScriptableObject.putProperty(mScope,
42
+ "ajaxRequestManagerRegistry",
43
+ Context.javaToJS(AjaxRequestManager.sharedManager(), mScope));
44
+ ScriptableObject.putProperty(mScope,
45
+ "androidRuntime",
46
+ this);
47
+
48
+ if (!evaller.isAlive())
49
+ evaller.start();
50
+ try
51
+ {
53
52
  countDownLatch.await();
54
53
  } catch (InterruptedException e) {
55
- Log.d(TAG, "Interrupted Exception when waiting for JSEvalThread");
56
- e.printStackTrace();
54
+ Log.d(TAG, "Interrupted Exception when waiting for JSEvalThread", e);
57
55
  }
58
56
  } finally {
59
57
  Context.exit();
@@ -67,12 +65,6 @@ public class RhinoService extends Service {
67
65
  return ctxt;
68
66
  }
69
67
 
70
- @Override
71
- public void onDestroy() {
72
- Log.d(TAG, "RhinoService destroyed.");
73
- super.onDestroy();
74
- }
75
-
76
68
  public void load(Reader source, String name) {
77
69
  evaller.load(source, name);
78
70
  }
@@ -101,12 +93,6 @@ public class RhinoService extends Service {
101
93
  evaller.callJsFunction(function, args);
102
94
  }
103
95
 
104
- public class LocalBinder extends Binder {
105
- public RhinoService getService() {
106
- return RhinoService.this;
107
- }
108
- }
109
-
110
96
  class JSEvalThread extends Thread {
111
97
  private Handler handler;
112
98
  private Context ctxt;
@@ -183,7 +169,7 @@ public class RhinoService extends Service {
183
169
  String js = "calatrava.inbound.failureResponse('{0}', {1}, '{2}');"
184
170
  .replace("{0}", requestId)
185
171
  .replace("{1}", Integer.toString(statusCode))
186
- .replace("{2}", responseBody);
172
+ .replace("{2}", responseBody.replace("'", "\\'"));
187
173
  dispatchJs(js);
188
174
  }
189
175
 
@@ -5,12 +5,14 @@ import android.content.Context;
5
5
  import android.content.Intent;
6
6
  import android.content.IntentFilter;
7
7
  import android.graphics.Color;
8
+ import android.os.Bundle;
8
9
  import android.util.Log;
9
10
  import android.webkit.JsResult;
10
11
  import android.webkit.WebChromeClient;
11
12
  import android.webkit.WebView;
12
13
  import android.webkit.WebViewClient;
13
14
 
15
+ import com.calatrava.bridge.CalatravaApplication;
14
16
  import com.calatrava.bridge.RegisteredActivity;
15
17
  import com.calatrava.bridge.RhinoService;
16
18
  import com.calatrava.bridge.PageRegistry;
@@ -28,7 +30,6 @@ public abstract class WebViewActivity extends RegisteredActivity {
28
30
  private JSContainer jsContainer;
29
31
  private WebView webView;
30
32
  private boolean pageReady = false;
31
- private RhinoService rhino;
32
33
 
33
34
  private BroadcastReceiver receiver = new BroadcastReceiver() {
34
35
  @Override
@@ -41,9 +42,10 @@ public abstract class WebViewActivity extends RegisteredActivity {
41
42
  };
42
43
 
43
44
  @Override
44
- protected void onRhinoConnected(RhinoService rhino) {
45
- this.rhino = rhino;
46
- jsContainer = new JSContainer(rhino, getPageName());
45
+ protected void onCreate(Bundle data)
46
+ {
47
+ super.onCreate(data);
48
+ jsContainer = new JSContainer(getRhino(), getPageName());
47
49
  loadPage();
48
50
  }
49
51
 
@@ -52,10 +54,8 @@ public abstract class WebViewActivity extends RegisteredActivity {
52
54
  super.onResume();
53
55
 
54
56
  onPageLoadCompleted();
57
+ pageHasOpened();
55
58
 
56
- if (rhino != null) {
57
- pageHasOpened();
58
- }
59
59
  registerReceiver(receiver, new IntentFilter("com.calatrava.dialog"));
60
60
  }
61
61
 
@@ -130,7 +130,6 @@ public abstract class WebViewActivity extends RegisteredActivity {
130
130
  webView.getSettings().setDomStorageEnabled(true);
131
131
  webView.setScrollBarStyle(webView.SCROLLBARS_OUTSIDE_OVERLAY);
132
132
  webView.setScrollbarFadingEnabled(true);
133
- webView.setBackgroundColor(0xffffffff);
134
133
  webView.addJavascriptInterface(jsContainer, "container");
135
134
 
136
135
  webView.setWebViewClient(new WebViewClient() {
@@ -3,7 +3,7 @@ platform :ios, '5.0'
3
3
  xcodeproj '{{ project_name}}.xcodeproj'
4
4
 
5
5
  {{^dev?}}
6
- pod 'calatrava', :git => 'https://github.com/calatrava/calatrava-ios', :commit => 'ba10050a6f565d7ac10b541ffe6164174db11376'
6
+ pod 'calatrava', :git => 'https://github.com/calatrava/calatrava-ios', :commit => '308c74a580e3408785be5fb50ac9254926c2654e'
7
7
  {{/dev?}}
8
8
  {{#dev?}}
9
9
  pod 'calatrava', :local => '../../../calatrava-ios'
@@ -1,6 +1,11 @@
1
1
  #import <UIKit/UIKit.h>
2
2
 
3
- @interface AppDelegate : UIResponder <UIApplicationDelegate>
3
+ #import "CalatravaAppDelegate.h"
4
+
5
+ @interface AppDelegate : UIResponder <UIApplicationDelegate, CalatravaAppDelegate>
6
+ {
7
+ int outstandingAjaxRequests;
8
+ }
4
9
 
5
10
  @property (strong, nonatomic) UIWindow *window;
6
11
  @property (strong, nonatomic) UINavigationController *rootNavController;
@@ -18,6 +18,8 @@
18
18
  self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
19
19
  [self.window addSubview:self.rootNavController.view];
20
20
  [self.window makeKeyAndVisible];
21
+
22
+ outstandingAjaxRequests = 0;
21
23
 
22
24
  KernelBridge *kernel = [KernelBridge sharedKernel];
23
25
  [kernel startWith:self.rootNavController];
@@ -53,4 +55,22 @@
53
55
  // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
54
56
  }
55
57
 
58
+ - (void)ajaxRequestStarted:(AJAXConnection *)request
59
+ {
60
+ ++outstandingAjaxRequests;
61
+ if (outstandingAjaxRequests == 1)
62
+ {
63
+ [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
64
+ }
65
+ }
66
+
67
+ - (void)ajaxRequestCompleted:(AJAXConnection *)request
68
+ {
69
+ --outstandingAjaxRequests;
70
+ if (outstandingAjaxRequests == 0)
71
+ {
72
+ [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
73
+ }
74
+ }
75
+
56
76
  @end
@@ -75,6 +75,15 @@ calatrava.bridge.pageObject = (pageName) ->
75
75
 
76
76
  calatrava.bridge.runtime.registerProxyForPage(proxyId, pageName)
77
77
 
78
+ after: (event, handler) ->
79
+ priorHandler = handlerRegistry[event]
80
+ if priorHandler?
81
+ handlerRegistry[event] = (args...) ->
82
+ priorHandler(args...)
83
+ handler(args...)
84
+ else
85
+ @bind(event, handler)
86
+
78
87
  bind: (event, handler) ->
79
88
  handlerRegistry[event] = handler
80
89
  calatrava.bridge.runtime.attachProxyEventHandler(proxyId, event)
@@ -153,11 +162,11 @@ calatrava.bridge.requests = (() ->
153
162
  failure: failure
154
163
 
155
164
  successfulResponse: (requestId, response) ->
156
- successHandlersById[requestId](response)
165
+ successHandlersById[requestId](response) if successHandlersById[requestId]
157
166
  clearHandlers(requestId)
158
167
 
159
168
  failureResponse: (requestId, response) ->
160
- failureHandlersById[requestId](response)
169
+ failureHandlersById[requestId](response) if failureHandlersById[requestId]
161
170
  clearHandlers(requestId)
162
171
  )()
163
172
 
@@ -194,9 +203,8 @@ calatrava.bridge.plugins = (() ->
194
203
  _.tap calatravaId(), (handle) ->
195
204
  callbacks[handle] = callback
196
205
 
197
- invokeCallback: (handle, data) ->
198
- callbacks[handle](data)
199
- delete callbacks[handle]
206
+ invokeCallback: (handle, data) -> callbacks[handle](data)
207
+ deleteCallback: (handle) -> delete callbacks[handle]
200
208
  )()
201
209
 
202
210
  calatrava.bridge.plugin = (name, impl) ->
@@ -3,7 +3,10 @@ calatrava.alert = (message) ->
3
3
  message: message
4
4
 
5
5
  calatrava.confirm = (message, onOkExecute) ->
6
- okCallbackHandle = calatrava.bridge.plugins.rememberCallback(onOkExecute)
6
+ okCallbackHandle = calatrava.bridge.plugins.rememberCallback () ->
7
+ calatrava.bridge.plugins.deleteCallback(okCallbackHandle)
8
+ onOkExecute()
9
+
7
10
  calatrava.bridge.plugins.call 'alert', 'displayConfirm',
8
11
  message: message
9
12
  okHandler: okCallbackHandle
@@ -33,5 +33,5 @@ describe 'converter controller', ->
33
33
  views.conversionForm.trigger 'convert'
34
34
 
35
35
  it 'should render the correctly converted amount', ->
36
- expect(views.conversionForm.render).toHaveBeenCalledWith
36
+ expect(views.conversionForm.lastMessage()).toEqual
37
37
  out_amount: 96
@@ -2,15 +2,29 @@ stubView ?= {}
2
2
 
3
3
  stubView =
4
4
  create: (name) ->
5
+ lastMessage = null
6
+
5
7
  boundEvents: {}
6
8
  fieldValues: {}
7
- trigger: (event) ->
8
- @boundEvents[event]()
9
+ trigger: (event, args...) ->
10
+ @boundEvents[event](args...)
11
+
12
+ after: (event, handler) ->
13
+ priorHandler = @boundEvents[event]
14
+ if priorHandler?
15
+ @boundEvents[event] = (args...) ->
16
+ priorHandler(args...)
17
+ handler(args...)
18
+ else
19
+ @bind(event, handler)
9
20
 
10
21
  bind: (event, handler) ->
11
22
  @boundEvents[event] = handler
12
23
 
13
- render: jasmine.createSpy("#{name} render")
24
+ render: (viewMessage) ->
25
+ lastMessage = viewMessage
26
+
27
+ lastMessage: () -> lastMessage
14
28
 
15
29
  fieldContains: (name, value) -> @fieldValues[name] = value
16
30
  get: (name, callback) ->
@@ -8,7 +8,6 @@
8
8
  , "cucumber" : "latest"
9
9
  , "jsdom" : "latest"
10
10
  , "mime" : "latest"
11
- , "ws" : "0.4.8"
12
11
  , "jasmine-node" : "1.0.26"
13
12
  , "should" : "*"
14
13
  , "jasmine-reporters" : "*"
@@ -32,5 +32,10 @@ calatrava.pageView.conversionForm = ->
32
32
  console.log('getting...', field)
33
33
  $page.find("#" + field).val()
34
34
 
35
- show: -> console.log('showing...')
36
- hide: -> console.log('hiding...')
35
+ show: ->
36
+ console.log('showing...')
37
+ $page.show()
38
+
39
+ hide: ->
40
+ console.log('hiding...')
41
+ $page.hide()
@@ -48,25 +48,25 @@ calatrava.bridge.web.ajax = (options) ->
48
48
  data: options.body
49
49
  contentType: (() ->
50
50
  customHeaderTemp = {}
51
- for key of options.customHeaders
51
+ for key of options.headers
52
52
  if key is "Content-Type"
53
- contentTypeHeader = options.customHeaders[key]
53
+ contentTypeHeader = options.headers[key]
54
54
  else
55
- customHeaderTemp[key] = options.customHeaders[key]
55
+ customHeaderTemp[key] = options.headers[key]
56
56
 
57
- options.customHeaders = customHeaderTemp
57
+ options.headers = customHeaderTemp
58
58
  contentTypeHeader;
59
59
  )()
60
60
  beforeSend: (xhr) ->
61
- if options.customHeaders
62
- setCustomHeaders(xhr, options.customHeaders)
61
+ if options.headers
62
+ setCustomHeaders(xhr, options.headers)
63
63
  showLoader()
64
64
  success: (response) ->
65
65
  goToTop()
66
66
  options.success(response)
67
67
  error: () ->
68
68
  showLoader()
69
- options.failure()
69
+ options.failure() if options.failure?
70
70
  complete: hideLoader
71
71
 
72
72
  calatrava.bridge.web.page = (pageName, proxyId) ->
@@ -3,7 +3,7 @@ root.calatrava ?= {}
3
3
  calatrava = root.calatrava
4
4
 
5
5
  # Hide all the sub-pages when first launching the app
6
- $(document.ready) ->
6
+ $(document).ready ->
7
7
  $('body > .container > .page').hide()
8
8
 
9
9
  window.onpopstate = (event) ->
@@ -1,3 +1,3 @@
1
1
  module Calatrava
2
- Version = "0.6.3"
2
+ Version = "0.6.4"
3
3
  end