calatrava 0.5.0 → 0.6.0

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 (61) hide show
  1. data/CHANGES.markdown +40 -0
  2. data/README.md +5 -0
  3. data/calatrava.gemspec +2 -3
  4. data/lib/calatrava/apache.rb +126 -0
  5. data/lib/calatrava/app.rb +2 -2
  6. data/lib/calatrava/app_builder.rb +68 -0
  7. data/lib/calatrava/configuration.rb +73 -0
  8. data/lib/calatrava/droid_app.rb +46 -0
  9. data/lib/calatrava/ios_app.rb +40 -0
  10. data/lib/calatrava/kernel.rb +79 -0
  11. data/lib/calatrava/manifest.rb +34 -11
  12. data/lib/calatrava/mobile_web_app.rb +74 -0
  13. data/lib/calatrava/project.rb +7 -191
  14. data/lib/calatrava/project_script.rb +186 -0
  15. data/lib/calatrava/shell.rb +43 -0
  16. data/lib/calatrava/tasks/assets.rb +4 -0
  17. data/lib/calatrava/tasks/automation.rb +4 -10
  18. data/lib/calatrava/tasks/haml.rb +9 -10
  19. data/lib/calatrava/tasks.rb +9 -85
  20. data/lib/calatrava/templates/config/templates/httpd.conf.erb +9 -9
  21. data/lib/calatrava/templates/droid/app/bridge.coffee +3 -0
  22. data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/CalatravaPlugin.java +13 -0
  23. data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/bridge/AlertPlugin.java +61 -0
  24. data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/bridge/AnnotationRegistrar.java +71 -0
  25. data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/bridge/KernelBridge.java +3 -4
  26. data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/bridge/Launcher.java +2 -1
  27. data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/bridge/PageRegistry.java +8 -29
  28. data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/bridge/PluginCommand.java +8 -0
  29. data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/bridge/PluginRegistry.java +112 -0
  30. data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/bridge/RegisteredActivity.java +3 -14
  31. data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/bridge/RegisteredPlugin.java +10 -0
  32. data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/bridge/Registration.java +8 -0
  33. data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/bridge/RhinoService.java +1 -0
  34. data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/shell/WebViewActivity.java +1 -1
  35. data/lib/calatrava/templates/ios/Podfile.calatrava +6 -1
  36. data/lib/calatrava/templates/ios/src/ConversionFormViewController.m +1 -1
  37. data/lib/calatrava/templates/kernel/app/calatrava.coffee +32 -5
  38. data/lib/calatrava/templates/kernel/app/converter/controller.converter.coffee +11 -4
  39. data/lib/calatrava/templates/kernel/plugins/alert.coffee +9 -0
  40. data/lib/calatrava/templates/shell/layouts/single_page.haml +3 -3
  41. data/lib/calatrava/templates/web/app/source/alert.web.coffee +13 -0
  42. data/lib/calatrava/templates/web/app/source/bridge.coffee +10 -0
  43. data/lib/calatrava/templates/web/app/views/index.haml +5 -5
  44. data/lib/calatrava/version.rb +1 -1
  45. data/lib/calatrava.rb +15 -1
  46. data/spec/app_builder_spec.rb +46 -0
  47. data/spec/kernel_spec.rb +51 -0
  48. data/spec/manifest_spec.rb +62 -0
  49. data/spec/mobile_web_app_spec.rb +49 -0
  50. data/spec/shell_spec.rb +54 -0
  51. data/spec/spec_helper.rb +4 -0
  52. metadata +60 -49
  53. data/Plans.md +0 -20
  54. data/lib/calatrava/tasks/apache.rb +0 -54
  55. data/lib/calatrava/tasks/build.rb +0 -1
  56. data/lib/calatrava/tasks/configuration.rb +0 -41
  57. data/lib/calatrava/tasks/droid.rb +0 -83
  58. data/lib/calatrava/tasks/ios.rb +0 -73
  59. data/lib/calatrava/tasks/kernel.rb +0 -52
  60. data/lib/calatrava/tasks/shell.rb +0 -17
  61. data/lib/calatrava/tasks/web.rb +0 -87
@@ -0,0 +1,61 @@
1
+ package com.calatrava.bridge;
2
+
3
+ import com.calatrava.CalatravaPlugin;
4
+
5
+ import android.content.Context;
6
+ import android.content.Intent;
7
+ import android.content.DialogInterface;
8
+ import android.app.AlertDialog;
9
+
10
+ import java.util.Map;
11
+
12
+ @CalatravaPlugin(name = "alert")
13
+ public class AlertPlugin implements RegisteredPlugin
14
+ {
15
+ private PluginRegistry registry;
16
+ private Context ctxt;
17
+ private String currentOkCallbackHandle;
18
+
19
+ public void setContext(PluginRegistry registry, Context ctxt)
20
+ {
21
+ this.registry = registry;
22
+ this.ctxt = ctxt;
23
+ registry.installCommand("alert", new PluginCommand() {
24
+ @Override
25
+ public void execute(Intent action, RegisteredActivity frontmost)
26
+ {
27
+ AlertDialog.Builder builder = new AlertDialog.Builder(frontmost);
28
+ final boolean isConfirmDialog = action.getExtras().getString("method").equals("displayConfirm");
29
+ builder.setMessage(action.getExtras().getString("message"))
30
+ .setCancelable(isConfirmDialog)
31
+ .setPositiveButton("OK", new DialogInterface.OnClickListener() {
32
+ @Override
33
+ public void onClick(DialogInterface dialogInterface, int i) {
34
+ dialogInterface.dismiss();
35
+ if (isConfirmDialog) {
36
+ AlertPlugin.this.registry.invokeCallback(currentOkCallbackHandle, 1);
37
+ }
38
+ }
39
+ });
40
+ if (isConfirmDialog) {
41
+ builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
42
+ @Override
43
+ public void onClick(DialogInterface dialogInterface, int i) {
44
+ dialogInterface.dismiss();
45
+ }
46
+ });
47
+ }
48
+ AlertDialog dialog = builder.create();
49
+ dialog.show();
50
+ }
51
+ });
52
+ }
53
+
54
+ public void call(String method, Map<String, Object> args)
55
+ {
56
+ currentOkCallbackHandle = (String)args.get("okHandler");
57
+ ctxt.sendBroadcast(registry.pluginCommand("alert")
58
+ .putExtra("method", method)
59
+ .putExtra("message", (String)args.get("message")));
60
+ }
61
+ }
@@ -0,0 +1,71 @@
1
+ package com.calatrava.bridge;
2
+
3
+ import android.content.Context;
4
+ import android.content.ContextWrapper;
5
+ import android.content.pm.PackageManager.NameNotFoundException;
6
+
7
+ import dalvik.system.DexFile;
8
+ import dalvik.system.PathClassLoader;
9
+ import dalvik.system.DexClassLoader;
10
+
11
+ import java.lang.annotation.Annotation;
12
+ import java.util.Enumeration;
13
+ import java.util.HashSet;
14
+ import java.util.Iterator;
15
+ import java.io.IOException;
16
+ import java.net.URISyntaxException;
17
+
18
+ public class AnnotationRegistrar
19
+ {
20
+ private String packageName;
21
+ private HashSet<String> searchScope = new HashSet<String>();
22
+ private Context context;
23
+
24
+ public AnnotationRegistrar(String packageName, Context context, String... searchScope)
25
+ {
26
+ this.packageName = packageName;
27
+ this.context = context;
28
+
29
+ this.searchScope.add(this.packageName);
30
+ for (String pkg : searchScope)
31
+ {
32
+ this.searchScope.add(pkg);
33
+ }
34
+ }
35
+
36
+ public void register(Registration receiver)
37
+ throws IOException, URISyntaxException, ClassNotFoundException, NameNotFoundException
38
+ {
39
+ String apkName = context.getPackageManager().getApplicationInfo(packageName, 0).sourceDir;
40
+ DexFile dexFile = new DexFile(apkName);
41
+ PathClassLoader pathBasedLoader = new PathClassLoader(apkName, Thread.currentThread().getContextClassLoader());
42
+ DexClassLoader classLoader = new DexClassLoader(apkName, new ContextWrapper(context).getCacheDir().getAbsolutePath(), null, pathBasedLoader);
43
+
44
+ Enumeration<String> entries = dexFile.entries();
45
+ while (entries.hasMoreElements())
46
+ {
47
+ String entry = entries.nextElement();
48
+ boolean inScope = false;
49
+ Iterator<String> it = searchScope.iterator();
50
+ while (!inScope && it.hasNext())
51
+ {
52
+ if (entry.startsWith(it.next()))
53
+ {
54
+ inScope = true;
55
+ }
56
+ }
57
+ if (inScope)
58
+ {
59
+ Class<?> entryClass = classLoader.loadClass(entry);
60
+ if (entryClass != null)
61
+ {
62
+ Annotation[] annotations = entryClass.getAnnotations();
63
+ for (Annotation annotation : annotations)
64
+ {
65
+ receiver.install(annotation, entryClass);
66
+ }
67
+ }
68
+ }
69
+ }
70
+ }
71
+ }
@@ -12,12 +12,11 @@ public class KernelBridge {
12
12
  this.rhinoService = rhinoService;
13
13
 
14
14
  //load js libraries
15
- loadLibrary("hybrid/scripts/underscore.js");
15
+ loadLibrary("calatrava/scripts/underscore.js");
16
16
 
17
17
  //load bridge
18
- loadLibrary("hybrid/scripts/env.js");
19
- loadLibrary("hybrid/scripts/bridge.js");
20
- loadLibrary("hybrid/scripts/calatrava.js");
18
+ loadLibrary("calatrava/scripts/env.js");
19
+ loadLibrary("calatrava/scripts/bridge.js");
21
20
  }
22
21
 
23
22
  public void loadLibrary(String libraryName) throws IOException {
@@ -28,6 +28,7 @@ public class Launcher {
28
28
  {
29
29
  rhino = ((RhinoService.LocalBinder) iBinder).getService();
30
30
  PageRegistry.setSharedRegistry(new PageRegistry(appName, appContext, application, rhino));
31
+ PluginRegistry.setSharedRegistry(new PluginRegistry(appName, appContext, rhino));
31
32
  AjaxRequestManager.setSharedManager(new AjaxRequestManager(appContext, rhino));
32
33
  initBridge();
33
34
  startUp.run();
@@ -71,7 +72,7 @@ public class Launcher {
71
72
  Log.d(TAG, "About to load and start kernel");
72
73
  // Load all the application JS
73
74
  KernelBridge bridge = new KernelBridge(assets, rhino);
74
- BufferedReader loadFileReader = new BufferedReader(new InputStreamReader(appContext.getAssets().open("hybrid/load_file.text")), 8192);
75
+ BufferedReader loadFileReader = new BufferedReader(new InputStreamReader(appContext.getAssets().open("calatrava/load_file.txt")), 8192);
75
76
  String line = null;
76
77
  while ((line = loadFileReader.readLine()) != null)
77
78
  {
@@ -3,7 +3,6 @@ package com.calatrava.bridge;
3
3
  import android.app.Application;
4
4
  import android.content.Context;
5
5
  import android.content.Intent;
6
- import android.content.ContextWrapper;
7
6
  import android.net.Uri;
8
7
  import android.util.Log;
9
8
  import android.content.pm.PackageManager.NameNotFoundException;
@@ -17,10 +16,6 @@ import java.util.*;
17
16
  import java.io.IOException;
18
17
  import java.net.URISyntaxException;
19
18
 
20
- import dalvik.system.DexFile;
21
- import dalvik.system.PathClassLoader;
22
- import dalvik.system.DexClassLoader;
23
-
24
19
  import java.lang.annotation.Annotation;
25
20
 
26
21
  public class PageRegistry {
@@ -56,34 +51,18 @@ public class PageRegistry {
56
51
  private void addPages(String packageName, Context context)
57
52
  throws IOException, URISyntaxException, ClassNotFoundException, NameNotFoundException
58
53
  {
59
- String apkName = context.getPackageManager().getApplicationInfo(packageName, 0).sourceDir;
60
- DexFile dexFile = new DexFile(apkName);
61
- PathClassLoader classLoader2 = new PathClassLoader(apkName, Thread.currentThread().getContextClassLoader());
62
- DexClassLoader classLoader = new DexClassLoader(apkName, new ContextWrapper(context).getCacheDir().getAbsolutePath(), null, classLoader2);
63
-
64
- Enumeration<String> entries = dexFile.entries();
65
- while (entries.hasMoreElements())
66
- {
67
- String entry = entries.nextElement();
68
- // only check items that exist in source package and not in libraries, etc.
69
- if (entry.startsWith(packageName))
70
- {
71
- Class<?> entryClass = classLoader.loadClass(entry);
72
- if (entryClass != null)
54
+ AnnotationRegistrar registrar = new AnnotationRegistrar(packageName, context);
55
+ registrar.register(new Registration() {
56
+ public void install(Annotation annotation, Class<?> toRegister)
73
57
  {
74
- Annotation[] annotations = entryClass.getAnnotations();
75
- for (Annotation annotation : annotations)
58
+ if (annotation instanceof CalatravaPage)
76
59
  {
77
- if (annotation instanceof CalatravaPage)
78
- {
79
- String pageName = ((CalatravaPage)annotation).name();
80
- Log.d(TAG, "Registering Calatrava page: " + pageName);
81
- pageFactories.put(pageName, entryClass);
82
- }
60
+ String pageName = ((CalatravaPage)annotation).name();
61
+ Log.d(TAG, "Registering Calatrava page: " + pageName);
62
+ pageFactories.put(pageName, toRegister);
83
63
  }
84
64
  }
85
- }
86
- }
65
+ });
87
66
  }
88
67
 
89
68
  public void registerProxyForPage(String pageName, String proxyId) {
@@ -0,0 +1,8 @@
1
+ package com.calatrava.bridge;
2
+
3
+ import android.content.Intent;
4
+
5
+ public interface PluginCommand
6
+ {
7
+ void execute(Intent action, RegisteredActivity frontmost);
8
+ }
@@ -0,0 +1,112 @@
1
+ package com.calatrava.bridge;
2
+
3
+ import android.content.Context;
4
+ import android.content.Intent;
5
+ import android.util.Log;
6
+ import android.content.pm.PackageManager.NameNotFoundException;
7
+
8
+ import org.codehaus.jackson.map.ObjectMapper;
9
+
10
+ import java.lang.annotation.Annotation;
11
+ import java.util.Map;
12
+ import java.util.HashMap;
13
+ import java.io.IOException;
14
+ import java.net.URISyntaxException;
15
+
16
+ import com.calatrava.CalatravaPlugin;
17
+
18
+ public class PluginRegistry {
19
+ public static String TAG = PluginRegistry.class.getSimpleName();
20
+ private static PluginRegistry sharedRegistry;
21
+
22
+ private Context appContext;
23
+ private RhinoService rhino;
24
+ private Map<String, RegisteredPlugin> registeredPlugins = new HashMap<String, RegisteredPlugin>();
25
+ private Map<String, PluginCommand> installedCmds = new HashMap<String, PluginCommand>();
26
+ private ObjectMapper jsonMapper = new ObjectMapper();
27
+
28
+ public static PluginRegistry sharedRegistry() {
29
+ return sharedRegistry;
30
+ }
31
+
32
+ public static void setSharedRegistry(PluginRegistry shared)
33
+ {
34
+ sharedRegistry = shared;
35
+ }
36
+
37
+ public PluginRegistry(String packageName, Context appContext, RhinoService rhino)
38
+ throws IOException, URISyntaxException, ClassNotFoundException, NameNotFoundException
39
+ {
40
+ this.appContext = appContext;
41
+ this.rhino = rhino;
42
+
43
+ // Find all the plugins to register in the app
44
+ addPlugins(packageName, appContext);
45
+ }
46
+
47
+ private void addPlugins(String packageName, Context context)
48
+ throws IOException, URISyntaxException, ClassNotFoundException, NameNotFoundException
49
+ {
50
+ Log.d(TAG, "Searching for Calatrava plugins in '" + packageName + "'");
51
+ AnnotationRegistrar registrar = new AnnotationRegistrar(packageName, context, "com.calatrava.bridge");
52
+ registrar.register(new Registration() {
53
+ public void install(Annotation annotation, Class<?> toRegister)
54
+ {
55
+ if (annotation instanceof CalatravaPlugin)
56
+ {
57
+ String pluginName = ((CalatravaPlugin)annotation).name();
58
+ Log.d(TAG, "Registering Calatrava plugin: " + pluginName);
59
+ try
60
+ {
61
+ RegisteredPlugin plugin = (RegisteredPlugin)toRegister.newInstance();
62
+ plugin.setContext(PluginRegistry.this, appContext);
63
+ registeredPlugins.put(pluginName, plugin);
64
+ }
65
+ catch (Exception e)
66
+ {
67
+ Log.e(TAG, "Unable to instantiate plugin: " + pluginName, e);
68
+ }
69
+ }
70
+ }
71
+ });
72
+ }
73
+
74
+ public void installCommand(String cmd, PluginCommand handler)
75
+ {
76
+ installedCmds.put(cmd, handler);
77
+ }
78
+
79
+ public void runCommand(Intent intent, RegisteredActivity frontmost)
80
+ {
81
+ installedCmds.get(intent.getExtras().getString("command")).execute(intent, frontmost);
82
+ }
83
+
84
+ public Intent pluginCommand(String cmd)
85
+ {
86
+ return new Intent("com.calatrava.command").putExtra("command", cmd);
87
+ }
88
+
89
+ public void call(String plugin, String method, String argsJson)
90
+ {
91
+ try
92
+ {
93
+ if (registeredPlugins.get(plugin) != null)
94
+ {
95
+ registeredPlugins.get(plugin).call(method, jsonMapper.readValue(argsJson, Map.class));
96
+ }
97
+ else
98
+ {
99
+ Log.e(TAG, "No plugin registered: " + plugin);
100
+ }
101
+ }
102
+ catch (IOException e)
103
+ {
104
+ Log.e(TAG, "Unable to deserialize JSON for plugin args.", e);
105
+ }
106
+ }
107
+
108
+ public void invokeCallback(String callbackHandle, Object data)
109
+ {
110
+ rhino.callJsFunction("calatrava.inbound.invokePluginCallback", new String[] {callbackHandle, data.toString()});
111
+ }
112
+ }
@@ -1,7 +1,6 @@
1
1
  package com.calatrava.bridge;
2
2
 
3
3
  import android.app.Activity;
4
- import android.app.AlertDialog;
5
4
  import android.content.*;
6
5
  import android.os.Bundle;
7
6
  import android.os.IBinder;
@@ -31,18 +30,8 @@ public abstract class RegisteredActivity extends Activity {
31
30
  spinner.onLoadingStart();
32
31
  } else if (intent.getAction().endsWith("finish")) {
33
32
  spinner.onLoadingFinish();
34
- } else {
35
- AlertDialog.Builder builder = new AlertDialog.Builder(RegisteredActivity.this);
36
- builder.setMessage(intent.getExtras().getString("message"))
37
- .setCancelable(false)
38
- .setPositiveButton("OK", new DialogInterface.OnClickListener() {
39
- @Override
40
- public void onClick(DialogInterface dialogInterface, int i) {
41
- dialogInterface.dismiss();
42
- }
43
- });
44
- AlertDialog dialog = builder.create();
45
- dialog.show();
33
+ } else if (intent.getAction().equals("com.calatrava.command")) {
34
+ PluginRegistry.sharedRegistry().runCommand(intent, RegisteredActivity.this);
46
35
  }
47
36
  }
48
37
  };
@@ -59,7 +48,7 @@ public abstract class RegisteredActivity extends Activity {
59
48
  super.onResume();
60
49
  registerReceiver(receiver, new IntentFilter("com.calatrava.ajax.start"));
61
50
  registerReceiver(receiver, new IntentFilter("com.calatrava.ajax.finish"));
62
- registerReceiver(receiver, new IntentFilter("com.calatrava.alert"));
51
+ registerReceiver(receiver, new IntentFilter("com.calatrava.command"));
63
52
  }
64
53
 
65
54
  @Override
@@ -0,0 +1,10 @@
1
+ package com.calatrava.bridge;
2
+
3
+ import android.content.Context;
4
+ import java.util.Map;
5
+
6
+ interface RegisteredPlugin
7
+ {
8
+ void setContext(PluginRegistry registry, Context ctxt);
9
+ void call(String method, Map<String, Object> args);
10
+ }
@@ -0,0 +1,8 @@
1
+ package com.calatrava.bridge;
2
+
3
+ import java.lang.annotation.Annotation;
4
+
5
+ public interface Registration
6
+ {
7
+ void install(Annotation annotation, Class<?> toRegister);
8
+ }
@@ -42,6 +42,7 @@ public class RhinoService extends Service {
42
42
 
43
43
  Object wrappedRegistry = Context.javaToJS(PageRegistry.sharedRegistry(), mScope);
44
44
  ScriptableObject.putProperty(mScope, "pageRegistry", wrappedRegistry);
45
+ ScriptableObject.putProperty(mScope, "pluginRegistry", Context.javaToJS(PluginRegistry.sharedRegistry(), mScope));
45
46
  ScriptableObject.putProperty(mScope, "androidRuntime", this);
46
47
 
47
48
  Object wrappedAjaxRequestManagerRegistry = Context.javaToJS(AjaxRequestManager.sharedManager(), mScope);
@@ -152,7 +152,7 @@ public abstract class WebViewActivity extends RegisteredActivity {
152
152
  }
153
153
  });
154
154
 
155
- webView.loadUrl("file:///android_asset/hybrid/views/" + getPageName() + ".html");
155
+ webView.loadUrl("file:///android_asset/calatrava/views/" + getPageName() + ".html");
156
156
  pageHasOpened();
157
157
  }
158
158
 
@@ -2,4 +2,9 @@ platform :ios, '5.0'
2
2
 
3
3
  xcodeproj '{{ project_name}}.xcodeproj'
4
4
 
5
- pod 'calatrava', :git => 'https://github.com/calatrava/calatrava-ios'
5
+ {{^dev?}}
6
+ pod 'calatrava', :git => 'https://github.com/calatrava/calatrava-ios', :commit => '7a57332b1bd74726240247f22d48dae89fdfce4a'
7
+ {{/dev?}}
8
+ {{#dev?}}
9
+ pod 'calatrava', :local => '../../../calatrava-ios'
10
+ {{/dev?}}
@@ -73,7 +73,7 @@
73
73
  } else if ([field isEqualToString:@"out_currency"]) {
74
74
  return [[_outCurrencyData objectAtIndex:[outCurrencyPicker selectedRowInComponent:0]] objectForKey:@"code"];
75
75
  } else if ([field isEqualToString:@"in_amount"]) {
76
- return [NSNumber numberWithInt:[[inAmount text] integerValue]];
76
+ return [inAmount text];
77
77
  }
78
78
  }
79
79
 
@@ -18,7 +18,7 @@ calatrava.inbound =
18
18
  proxyPage = calatrava.bridge.pages.pageByProxyId(proxyId)
19
19
  proxyPage.fieldRead(getId, fieldValue)
20
20
 
21
- successfulRespone: (requestId, response) ->
21
+ successfulResponse: (requestId, response) ->
22
22
  calatrava.bridge.requests.successfulResponse(requestId, response)
23
23
 
24
24
  failureResponse: (requestId, errorCode, response) ->
@@ -27,16 +27,16 @@ calatrava.inbound =
27
27
  fireTimer: (timerId) ->
28
28
  calatrava.bridge.timers.fireTimer(timerId)
29
29
 
30
- invokeCallback: (widgetName) ->
31
- extraArgs = _.map(_.toArray(arguments).slice(1), ((obj) -> obj.valueOf() if obj?))
32
- calatrava.bridge.widgets.callback(widgetName).apply(this, extraArgs)
30
+ invokePluginCallback: (handle, data) ->
31
+ calatrava.bridge.plugins.invokeCallback(handle, data)
33
32
 
34
33
  calatrava.bridge.changePage = (target) ->
35
34
  calatrava.bridge.runtime.changePage(target)
36
35
  target
37
36
 
38
37
  calatrava.bridge.alert = (message) ->
39
- calatrava.bridge.runtime.alert(message)
38
+ calatrava.bridge.log("WARN: calatrava.bridge.alert is deprecated. Please use calatrava.alert() instead.")
39
+ calatrava.alert(message)
40
40
 
41
41
  calatrava.bridge.openUrl = (url) ->
42
42
  calatrava.bridge.runtime.openUrl(url)
@@ -149,6 +149,8 @@ calatrava.bridge.requests = (() ->
149
149
  method: method
150
150
  body: bodyStr
151
151
  headers: customHeaders
152
+ success: success
153
+ failure: failure
152
154
 
153
155
  successfulResponse: (requestId, response) ->
154
156
  successHandlersById[requestId](response)
@@ -174,3 +176,28 @@ calatrava.bridge.timers = (() ->
174
176
  clearTimer: (timerId) ->
175
177
  delete callbacks[timerId]
176
178
  )()
179
+
180
+ calatrava.bridge.plugins = (() ->
181
+ registered = {}
182
+ callbacks = {}
183
+
184
+ call: (pluginName, method, argMessage) ->
185
+ calatrava.bridge.runtime.callPlugin(pluginName, method, argMessage)
186
+
187
+ register: (pluginName, callback) ->
188
+ registered[pluginName] = callback
189
+
190
+ run: (pluginName, method, argMessage) ->
191
+ registered[pluginName](method, argMessage)
192
+
193
+ rememberCallback: (callback) ->
194
+ _.tap calatravaId(), (handle) ->
195
+ callbacks[handle] = callback
196
+
197
+ invokeCallback: (handle, data) ->
198
+ callbacks[handle](data)
199
+ delete callbacks[handle]
200
+ )()
201
+
202
+ calatrava.bridge.plugin = (name, impl) ->
203
+ calatrava.bridge.plugins.register(name, impl)
@@ -18,12 +18,19 @@ example.converter.controller = ({views, changePage, ajax}) ->
18
18
  enabled: c != unselectableCurrency
19
19
  selected: c == selectedCurrency
20
20
 
21
+ performConversion = (amount) ->
22
+ outRate = currencyRate[outCurrency]
23
+ inRate = currencyRate[inCurrency]
24
+ views.conversionForm.render
25
+ out_amount: (Math.round(amount * (outRate / inRate) * 100)) / 100
26
+
21
27
  convert = () ->
22
28
  views.conversionForm.get 'in_amount', (inAmount) ->
23
- outRate = currencyRate[outCurrency]
24
- inRate = currencyRate[inCurrency]
25
- views.conversionForm.render
26
- out_amount: (Math.round(inAmount * (outRate / inRate) * 100)) / 100
29
+ if inAmount == ""
30
+ calatrava.confirm "No amount to convert. Convert one instead?", (convertOne) ->
31
+ performConversion(1) if convertOne
32
+ else
33
+ performConversion(inAmount)
27
34
 
28
35
  views.conversionForm.bind 'convert', convert
29
36
 
@@ -0,0 +1,9 @@
1
+ calatrava.alert = (message) ->
2
+ calatrava.bridge.plugins.call 'alert', 'displayAlert',
3
+ message: message
4
+
5
+ calatrava.confirm = (message, onOkExecute) ->
6
+ okCallbackHandle = calatrava.bridge.plugins.rememberCallback(onOkExecute)
7
+ calatrava.bridge.plugins.call 'alert', 'displayConfirm',
8
+ message: message
9
+ okHandler: okCallbackHandle
@@ -2,17 +2,17 @@
2
2
  %html
3
3
  %head
4
4
  -%w{reset app common device}.each do |filename|
5
- %link(type="text/css" rel="stylesheet" media="all" href="file:///android_asset/hybrid/styles/#{filename}.css")
5
+ %link(type="text/css" rel="stylesheet" media="all" href="../styles/#{filename}.css")
6
6
 
7
7
  -%w{env zepto ICanHaz underscore calatrava bridge shell pageHelper}.each do |filename|
8
- %script(type="text/javascript" src="file:///android_asset/hybrid/scripts/#{filename}.js")
8
+ %script(type="text/javascript" src="../scripts/#{filename}.js")
9
9
 
10
10
  :javascript
11
11
  $(document).ready(function() {
12
12
  window.batSignal = tw.batSignal();
13
13
  });
14
14
 
15
- %script(src="file:///android_asset/hybrid/scripts/page.#{page_name}.js" type="text/javascript")
15
+ %script(src="../scripts/page.#{page_name}.js" type="text/javascript")
16
16
  :javascript
17
17
  $(document).ready(function() {
18
18
  window.#{page_name}View = calatrava.pageView.#{page_name}();
@@ -0,0 +1,13 @@
1
+ calatrava.web ?= {}
2
+
3
+ calatrava.web.alert = (method, {message, okHandler}) ->
4
+ if !message?
5
+ console.log("Unable to display alert.")
6
+
7
+ if method == 'displayAlert'
8
+ window.alert(message)
9
+ else if method == 'displayConfirm'
10
+ userPressedOk = window.confirm(message)
11
+ calatrava.bridge.runtime.invokePluginCallback(okHandler, userPressedOk)
12
+
13
+ calatrava.bridge.runtime.registerPlugin 'alert', calatrava.web.alert
@@ -96,6 +96,7 @@ calatrava.bridge.runtime = (() ->
96
96
  pages = {}
97
97
  pagesNamed = {}
98
98
  currentPage = null
99
+ plugins = {}
99
100
 
100
101
  registerProxyForPage: (proxyId, pageName) ->
101
102
  pages[proxyId] = calatrava.bridge.web.page(pageName, proxyId)
@@ -123,4 +124,13 @@ calatrava.bridge.runtime = (() ->
123
124
 
124
125
  startTimerWithTimeout: (timerId, timeout) ->
125
126
  window.setTimeout((() -> calatrava.inbound.fireTimer(timerId)), timeout * 1000)
127
+
128
+ registerPlugin: (pluginName, callback) ->
129
+ plugins[pluginName] = callback
130
+
131
+ callPlugin: (plugin, method, args) ->
132
+ plugins[plugin](method, args)
133
+
134
+ invokePluginCallback: (handle, data) ->
135
+ calatrava.inbound.invokePluginCallback(handle, data)
126
136
  )()
@@ -1,16 +1,16 @@
1
1
  !!!
2
2
  %html
3
3
  %head
4
- -%w{env zepto ICanHaz underscore calatrava bridge pageHelper}.each do |filename|
4
+ -%w{zepto ICanHaz underscore}.each do |filename|
5
5
  %script(type="text/javascript" src="scripts/#{filename}.js")
6
6
 
7
- %script(type="text/javascript" src="scripts/init.js")
8
- -# Load all feature JS files
9
- = render_partial 'web/app/views/load_file'
7
+ - Calatrava::Project.current.mobile_web.scripts.each do |filename|
8
+ %script(type="text/javascript" src="#{filename}")
10
9
 
11
10
  %body
12
11
  %div#app_container.container
13
- = render_page "converter/conversionForm"
12
+ - Calatrava::Project.current.mobile_web.haml_files.each do |hf|
13
+ = render_partial hf
14
14
 
15
15
  :javascript
16
16
  $(document).ready(function(){
@@ -1,3 +1,3 @@
1
1
  module Calatrava
2
- Version = "0.5.0"
2
+ Version = "0.6.0"
3
3
  end
data/lib/calatrava.rb CHANGED
@@ -1,5 +1,19 @@
1
+ require 'rake'
2
+ require 'rake/file_list'
3
+
4
+ require 'calatrava/configuration'
5
+
1
6
  require 'calatrava/version'
7
+ require 'calatrava/apache'
2
8
  require 'calatrava/app'
3
- require 'calatrava/project'
9
+ require 'calatrava/app_builder'
10
+ require 'calatrava/droid_app'
11
+ require 'calatrava/ios_app'
12
+ require 'calatrava/kernel'
4
13
  require 'calatrava/manifest'
14
+ require 'calatrava/mobile_web_app'
15
+ require 'calatrava/project'
16
+ require 'calatrava/project_script'
17
+ require 'calatrava/resources_build_phase'
18
+ require 'calatrava/shell'
5
19
  require 'calatrava/template'