calatrava 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.markdown +40 -0
- data/README.md +5 -0
- data/calatrava.gemspec +2 -3
- data/lib/calatrava/apache.rb +126 -0
- data/lib/calatrava/app.rb +2 -2
- data/lib/calatrava/app_builder.rb +68 -0
- data/lib/calatrava/configuration.rb +73 -0
- data/lib/calatrava/droid_app.rb +46 -0
- data/lib/calatrava/ios_app.rb +40 -0
- data/lib/calatrava/kernel.rb +79 -0
- data/lib/calatrava/manifest.rb +34 -11
- data/lib/calatrava/mobile_web_app.rb +74 -0
- data/lib/calatrava/project.rb +7 -191
- data/lib/calatrava/project_script.rb +186 -0
- data/lib/calatrava/shell.rb +43 -0
- data/lib/calatrava/tasks/assets.rb +4 -0
- data/lib/calatrava/tasks/automation.rb +4 -10
- data/lib/calatrava/tasks/haml.rb +9 -10
- data/lib/calatrava/tasks.rb +9 -85
- data/lib/calatrava/templates/config/templates/httpd.conf.erb +9 -9
- data/lib/calatrava/templates/droid/app/bridge.coffee +3 -0
- data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/CalatravaPlugin.java +13 -0
- data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/bridge/AlertPlugin.java +61 -0
- data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/bridge/AnnotationRegistrar.java +71 -0
- data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/bridge/KernelBridge.java +3 -4
- data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/bridge/Launcher.java +2 -1
- data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/bridge/PageRegistry.java +8 -29
- data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/bridge/PluginCommand.java +8 -0
- data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/bridge/PluginRegistry.java +112 -0
- data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/bridge/RegisteredActivity.java +3 -14
- data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/bridge/RegisteredPlugin.java +10 -0
- data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/bridge/Registration.java +8 -0
- data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/bridge/RhinoService.java +1 -0
- data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/shell/WebViewActivity.java +1 -1
- data/lib/calatrava/templates/ios/Podfile.calatrava +6 -1
- data/lib/calatrava/templates/ios/src/ConversionFormViewController.m +1 -1
- data/lib/calatrava/templates/kernel/app/calatrava.coffee +32 -5
- data/lib/calatrava/templates/kernel/app/converter/controller.converter.coffee +11 -4
- data/lib/calatrava/templates/kernel/plugins/alert.coffee +9 -0
- data/lib/calatrava/templates/shell/layouts/single_page.haml +3 -3
- data/lib/calatrava/templates/web/app/source/alert.web.coffee +13 -0
- data/lib/calatrava/templates/web/app/source/bridge.coffee +10 -0
- data/lib/calatrava/templates/web/app/views/index.haml +5 -5
- data/lib/calatrava/version.rb +1 -1
- data/lib/calatrava.rb +15 -1
- data/spec/app_builder_spec.rb +46 -0
- data/spec/kernel_spec.rb +51 -0
- data/spec/manifest_spec.rb +62 -0
- data/spec/mobile_web_app_spec.rb +49 -0
- data/spec/shell_spec.rb +54 -0
- data/spec/spec_helper.rb +4 -0
- metadata +60 -49
- data/Plans.md +0 -20
- data/lib/calatrava/tasks/apache.rb +0 -54
- data/lib/calatrava/tasks/build.rb +0 -1
- data/lib/calatrava/tasks/configuration.rb +0 -41
- data/lib/calatrava/tasks/droid.rb +0 -83
- data/lib/calatrava/tasks/ios.rb +0 -73
- data/lib/calatrava/tasks/kernel.rb +0 -52
- data/lib/calatrava/tasks/shell.rb +0 -17
- 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
|
+
}
|
data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/bridge/AnnotationRegistrar.java
ADDED
@@ -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("
|
15
|
+
loadLibrary("calatrava/scripts/underscore.js");
|
16
16
|
|
17
17
|
//load bridge
|
18
|
-
loadLibrary("
|
19
|
-
loadLibrary("
|
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("
|
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
|
-
|
60
|
-
|
61
|
-
|
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
|
-
|
75
|
-
for (Annotation annotation : annotations)
|
58
|
+
if (annotation instanceof CalatravaPage)
|
76
59
|
{
|
77
|
-
|
78
|
-
|
79
|
-
|
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,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
|
+
}
|
data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/bridge/RegisteredActivity.java
CHANGED
@@ -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
|
-
|
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.
|
51
|
+
registerReceiver(receiver, new IntentFilter("com.calatrava.command"));
|
63
52
|
}
|
64
53
|
|
65
54
|
@Override
|
@@ -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/
|
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
|
-
|
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 [
|
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
|
-
|
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
|
-
|
31
|
-
|
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.
|
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
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
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="
|
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="
|
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="
|
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{
|
4
|
+
-%w{zepto ICanHaz underscore}.each do |filename|
|
5
5
|
%script(type="text/javascript" src="scripts/#{filename}.js")
|
6
6
|
|
7
|
-
|
8
|
-
|
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
|
-
|
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(){
|
data/lib/calatrava/version.rb
CHANGED
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/
|
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'
|