calatrava 0.6.3 → 0.6.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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