calatrava 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. data/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'