calatrava 0.0.1
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.
- data/.gitignore +9 -0
- data/.rvmrc +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +202 -0
- data/Plans.md +20 -0
- data/README.md +73 -0
- data/Rakefile +26 -0
- data/bin/calatrava +6 -0
- data/calatrava.gemspec +35 -0
- data/features/cli.feature +14 -0
- data/features/project.feature +48 -0
- data/features/step_definitions/template_steps.rb +8 -0
- data/features/support/env.rb +5 -0
- data/lib/calatrava/app.rb +30 -0
- data/lib/calatrava/manifest.rb +44 -0
- data/lib/calatrava/project.rb +218 -0
- data/lib/calatrava/resources_build_phase.rb +19 -0
- data/lib/calatrava/tasks/apache.rb +44 -0
- data/lib/calatrava/tasks/artifact.rb +24 -0
- data/lib/calatrava/tasks/assets.rb +6 -0
- data/lib/calatrava/tasks/automation.rb +38 -0
- data/lib/calatrava/tasks/bootstrap.rb +10 -0
- data/lib/calatrava/tasks/build.rb +1 -0
- data/lib/calatrava/tasks/configuration.rb +41 -0
- data/lib/calatrava/tasks/droid.rb +83 -0
- data/lib/calatrava/tasks/haml.rb +71 -0
- data/lib/calatrava/tasks/ios.rb +73 -0
- data/lib/calatrava/tasks/kernel.rb +52 -0
- data/lib/calatrava/tasks/precommit.rb +22 -0
- data/lib/calatrava/tasks/release.rb +17 -0
- data/lib/calatrava/tasks/shell.rb +17 -0
- data/lib/calatrava/tasks/web.rb +82 -0
- data/lib/calatrava/tasks.rb +93 -0
- data/lib/calatrava/template.rb +44 -0
- data/lib/calatrava/templates/.rvmrc.calatrava +2 -0
- data/lib/calatrava/templates/Gemfile.calatrava +4 -0
- data/lib/calatrava/templates/Rakefile +1 -0
- data/lib/calatrava/templates/assets/lib/ICanHaz.js +542 -0
- data/lib/calatrava/templates/assets/lib/underscore.js +1059 -0
- data/lib/calatrava/templates/assets/lib/zepto.js +1355 -0
- data/lib/calatrava/templates/build_env.sh +2 -0
- data/lib/calatrava/templates/config/environments.yml +17 -0
- data/lib/calatrava/templates/config/templates/env.coffee.erb +7 -0
- data/lib/calatrava/templates/config/templates/httpd.conf.erb +33 -0
- data/lib/calatrava/templates/droid/app/bridge.coffee +130 -0
- data/lib/calatrava/templates/droid/calatrava/ant/calatrava.xml +48 -0
- data/lib/calatrava/templates/droid/calatrava/calatrava-build.xml +91 -0
- data/lib/calatrava/templates/droid/calatrava/ivy.xml +8 -0
- data/lib/calatrava/templates/droid/calatrava/ivysettings.xml +12 -0
- data/lib/calatrava/templates/droid/calatrava/src/com/CALATRAVA_TMPL/AndroidManifest.xml.calatrava +20 -0
- data/lib/calatrava/templates/droid/calatrava/src/com/CALATRAVA_TMPL/ConversionForm.java.calatrava +27 -0
- data/lib/calatrava/templates/droid/calatrava/src/com/CALATRAVA_TMPL/Title.java.calatrava +23 -0
- data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/CalatravaPage.java +13 -0
- data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/bridge/AjaxRequestManager.java +166 -0
- data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/bridge/AssetRepository.java +17 -0
- data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/bridge/KernelBridge.java +25 -0
- data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/bridge/Launcher.java +85 -0
- data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/bridge/PageRegistry.java +225 -0
- data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/bridge/RegisteredActivity.java +86 -0
- data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/bridge/RequestLoader.java +31 -0
- data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/bridge/RhinoService.java +212 -0
- data/lib/calatrava/templates/droid/calatrava/src/com/calatrava/shell/WebViewActivity.java +247 -0
- data/lib/calatrava/templates/droid/manifest.yml +1 -0
- data/lib/calatrava/templates/ios/Podfile.calatrava +5 -0
- data/lib/calatrava/templates/ios/manifest.yml +1 -0
- data/lib/calatrava/templates/ios/res/js/bridge.js +249 -0
- data/lib/calatrava/templates/ios/res/xibs/ProgressViewController.xib +334 -0
- data/lib/calatrava/templates/ios/res/xibs/WebViewController.xib +173 -0
- data/lib/calatrava/templates/ios/src/AppDelegate.h +8 -0
- data/lib/calatrava/templates/ios/src/AppDelegate.m +56 -0
- data/lib/calatrava/templates/ios/src/CALATRAVA_TMPL-Info.plist +45 -0
- data/lib/calatrava/templates/ios/src/CALATRAVA_TMPL-Prefix.pch +14 -0
- data/lib/calatrava/templates/ios/src/ConversionFormViewController.h +16 -0
- data/lib/calatrava/templates/ios/src/ConversionFormViewController.m +179 -0
- data/lib/calatrava/templates/ios/src/ConversionFormViewController.xib +357 -0
- data/lib/calatrava/templates/ios/src/en.lproj/InfoPlist.strings +2 -0
- data/lib/calatrava/templates/ios/src/main.m +10 -0
- data/lib/calatrava/templates/ios/test/AJAXConnectionTest.m +21 -0
- data/lib/calatrava/templates/ios/test/AppTests-Prefix.pch +8 -0
- data/lib/calatrava/templates/ios/test/CalatravaiOSTests-Info.plist +22 -0
- data/lib/calatrava/templates/ios/test/TWBridgePageRegistryTest.m +15 -0
- data/lib/calatrava/templates/ios/test/en.lproj/InfoPlist.strings +2 -0
- data/lib/calatrava/templates/kernel/.gitignore +1 -0
- data/lib/calatrava/templates/kernel/app/calatrava.coffee +8 -0
- data/lib/calatrava/templates/kernel/app/converter/controller.converter.coffee +50 -0
- data/lib/calatrava/templates/kernel/app/converter/init.converter.coffee +11 -0
- data/lib/calatrava/templates/kernel/app/pageHelper.coffee +17 -0
- data/lib/calatrava/templates/kernel/features/support/bridge.coffee +124 -0
- data/lib/calatrava/templates/kernel/features/support/spec_helper.js +49 -0
- data/lib/calatrava/templates/kernel/spec/converter/controller.converter.spec.coffee +37 -0
- data/lib/calatrava/templates/kernel/spec/environment.spec_helper.coffee +25 -0
- data/lib/calatrava/templates/kernel/spec/spec_helper.js +49 -0
- data/lib/calatrava/templates/kernel/spec/stubView.coffee +18 -0
- data/lib/calatrava/templates/kernel/watchr.rb +17 -0
- data/lib/calatrava/templates/package.json +20 -0
- data/lib/calatrava/templates/shell/layouts/single_page.haml +23 -0
- data/lib/calatrava/templates/shell/pages/converter/conversionForm.haml +12 -0
- data/lib/calatrava/templates/shell/pages/converter/page.conversionForm.coffee +42 -0
- data/lib/calatrava/templates/shell/shell.scss +1 -0
- data/lib/calatrava/templates/shell/support/shell.coffee +21 -0
- data/lib/calatrava/templates/web/apache/conf/mime.types +1357 -0
- data/lib/calatrava/templates/web/app/source/bridge.coffee +158 -0
- data/lib/calatrava/templates/web/app/source/init.coffee +14 -0
- data/lib/calatrava/templates/web/app/views/index.haml +18 -0
- data/lib/calatrava/templates/web/deploy/instance.sh +10 -0
- data/lib/calatrava/templates/web/manifest.yml +1 -0
- data/lib/calatrava/version.rb +3 -0
- data/lib/calatrava.rb +5 -0
- metadata +302 -0
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
package com.calatrava.shell;
|
|
2
|
+
|
|
3
|
+
import android.content.BroadcastReceiver;
|
|
4
|
+
import android.content.Context;
|
|
5
|
+
import android.content.Intent;
|
|
6
|
+
import android.content.IntentFilter;
|
|
7
|
+
import android.graphics.Color;
|
|
8
|
+
import android.util.Log;
|
|
9
|
+
import android.webkit.JsResult;
|
|
10
|
+
import android.webkit.WebChromeClient;
|
|
11
|
+
import android.webkit.WebView;
|
|
12
|
+
import android.webkit.WebViewClient;
|
|
13
|
+
|
|
14
|
+
import com.calatrava.bridge.RegisteredActivity;
|
|
15
|
+
import com.calatrava.bridge.RhinoService;
|
|
16
|
+
import com.calatrava.bridge.PageRegistry;
|
|
17
|
+
|
|
18
|
+
import java.util.HashMap;
|
|
19
|
+
import java.util.List;
|
|
20
|
+
import java.util.Map;
|
|
21
|
+
import java.util.concurrent.Callable;
|
|
22
|
+
import java.util.concurrent.FutureTask;
|
|
23
|
+
import java.util.concurrent.Semaphore;
|
|
24
|
+
|
|
25
|
+
public abstract class WebViewActivity extends RegisteredActivity {
|
|
26
|
+
private String TAG = WebViewActivity.class.getSimpleName();
|
|
27
|
+
|
|
28
|
+
private JSContainer jsContainer;
|
|
29
|
+
private WebView webView;
|
|
30
|
+
private boolean pageReady = false;
|
|
31
|
+
private RhinoService rhino;
|
|
32
|
+
|
|
33
|
+
private BroadcastReceiver receiver = new BroadcastReceiver() {
|
|
34
|
+
@Override
|
|
35
|
+
public void onReceive(Context context, Intent intent) {
|
|
36
|
+
if ("com.calatrava.dialog".equals(intent.getAction())) {
|
|
37
|
+
String name = intent.getExtras().getString("name");
|
|
38
|
+
webView.loadUrl("javascript:window." + getPageName() + "View.showDialog('" + name + "');");
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
@Override
|
|
44
|
+
protected void onRhinoConnected(RhinoService rhino) {
|
|
45
|
+
this.rhino = rhino;
|
|
46
|
+
jsContainer = new JSContainer(rhino, getPageName());
|
|
47
|
+
loadPage();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@Override
|
|
51
|
+
protected void onResume() {
|
|
52
|
+
super.onResume();
|
|
53
|
+
|
|
54
|
+
onPageLoadCompleted();
|
|
55
|
+
|
|
56
|
+
if (rhino != null) {
|
|
57
|
+
pageHasOpened();
|
|
58
|
+
}
|
|
59
|
+
registerReceiver(receiver, new IntentFilter("com.calatrava.dialog"));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
@Override
|
|
63
|
+
protected void onPause() {
|
|
64
|
+
super.onPause();
|
|
65
|
+
|
|
66
|
+
PageRegistry.sharedRegistry().pageOffscreen(getPageName());
|
|
67
|
+
unregisterReceiver(receiver);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
@Override
|
|
71
|
+
public void onDestroy() {
|
|
72
|
+
super.onDestroy();
|
|
73
|
+
|
|
74
|
+
PageRegistry.sharedRegistry().unregisterPage(getPageName());
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
public String getFieldValue(final String field) {
|
|
78
|
+
assert (getFields().contains(field));
|
|
79
|
+
|
|
80
|
+
Log.d(TAG, "Get value for field: " + field + " on page '" + getPageName() + "'");
|
|
81
|
+
|
|
82
|
+
FutureTask<String> fieldValue = new FutureTask<String>(new Callable<String>() {
|
|
83
|
+
public String call() throws Exception {
|
|
84
|
+
webView.loadUrl("javascript:container.provideValueFor('" + field + "', window." + getPageName() + "View.get('" + field + "'));");
|
|
85
|
+
return jsContainer.retrieveValueFor(field);
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
runOnUiThread(fieldValue);
|
|
90
|
+
|
|
91
|
+
String value;
|
|
92
|
+
try {
|
|
93
|
+
value = fieldValue.get();
|
|
94
|
+
} catch (Exception e) {
|
|
95
|
+
e.printStackTrace();
|
|
96
|
+
// TODO: Signal failure to the UI thread
|
|
97
|
+
return "";
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
Log.d(TAG, "(getFieldValue) : Got the field [" + field + "] value = " + value);
|
|
101
|
+
return value;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
public void render(final String json) {
|
|
105
|
+
runOnUiThread(new Runnable() {
|
|
106
|
+
public void run() {
|
|
107
|
+
jsContainer.setJsObject(json);
|
|
108
|
+
Log.d(TAG, "render page: " + getPageName());
|
|
109
|
+
|
|
110
|
+
webView.loadUrl("javascript:container.onRenderComplete(window." + getPageName() + "View.render(JSON.parse(container.getJsObject())));");
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
protected abstract String getPageName();
|
|
116
|
+
|
|
117
|
+
protected abstract List<String> getEvents();
|
|
118
|
+
|
|
119
|
+
protected abstract List<String> getFields();
|
|
120
|
+
|
|
121
|
+
protected int getBackgroundColor(){
|
|
122
|
+
return Color.TRANSPARENT;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
protected void loadPage() {
|
|
126
|
+
PageRegistry.sharedRegistry().registerPage(getPageName(), this);
|
|
127
|
+
|
|
128
|
+
webView = new WebView(this);
|
|
129
|
+
setContentView(webView);
|
|
130
|
+
|
|
131
|
+
webView.getSettings().setJavaScriptEnabled(true);
|
|
132
|
+
webView.getSettings().setDomStorageEnabled(true);
|
|
133
|
+
webView.setScrollBarStyle(webView.SCROLLBARS_OUTSIDE_OVERLAY);
|
|
134
|
+
webView.setScrollbarFadingEnabled(true);
|
|
135
|
+
webView.setBackgroundColor(0xffffffff);
|
|
136
|
+
webView.addJavascriptInterface(jsContainer, "container");
|
|
137
|
+
|
|
138
|
+
webView.setWebViewClient(new WebViewClient() {
|
|
139
|
+
@Override
|
|
140
|
+
public void onPageFinished(WebView view, String url) {
|
|
141
|
+
super.onPageFinished(view, url);
|
|
142
|
+
Log.d(TAG, "Webview finished loading a URL");
|
|
143
|
+
|
|
144
|
+
pageReady = true;
|
|
145
|
+
onPageLoadCompleted();
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
webView.setWebChromeClient(new WebChromeClient() {
|
|
150
|
+
@Override
|
|
151
|
+
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
|
|
152
|
+
Log.d(TAG, "Received JS alert: '" + message + "'");
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
webView.loadUrl("file:///android_asset/hybrid/views/" + getPageName() + ".html");
|
|
158
|
+
pageHasOpened();
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
private void pageHasOpened() {
|
|
162
|
+
rhino.triggerEvent(getPageName(), "pageOpened", new String[] {});
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
private void onPageLoadCompleted() {
|
|
166
|
+
if (jsContainer != null && pageReady) {
|
|
167
|
+
jsContainer.onRenderComplete(null);
|
|
168
|
+
|
|
169
|
+
for (String field : getFields()) {
|
|
170
|
+
jsContainer.hasField(field);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
PageRegistry.sharedRegistry().pageOnscreen(getPageName());
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
public class JSContainer {
|
|
178
|
+
private String TAG = JSContainer.class.getSimpleName();
|
|
179
|
+
|
|
180
|
+
private Map<String, String> lastValue = new HashMap<String, String>();
|
|
181
|
+
private Map<String, Semaphore> valueAvailable = new HashMap<String, Semaphore>();
|
|
182
|
+
private RhinoService rhino;
|
|
183
|
+
private String pageName;
|
|
184
|
+
private String jsObject;
|
|
185
|
+
|
|
186
|
+
public JSContainer(RhinoService rhino, String pageName) {
|
|
187
|
+
this.rhino = rhino;
|
|
188
|
+
this.pageName = pageName;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
public void setJsObject(String jsObject) {
|
|
192
|
+
this.jsObject = jsObject;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
public String getJsObject() {
|
|
196
|
+
return jsObject;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
public void hasField(String field) {
|
|
200
|
+
valueAvailable.put(field, new Semaphore(0));
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
public void provideValueFor(String field, String value) {
|
|
204
|
+
Log.d(TAG, "Got value '" + value + "' for field '" + field + "'");
|
|
205
|
+
lastValue.put(field, value);
|
|
206
|
+
valueAvailable.get(field).release();
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
public String retrieveValueFor(String field) {
|
|
210
|
+
try {
|
|
211
|
+
valueAvailable.get(field).acquire();
|
|
212
|
+
} catch (InterruptedException e) {
|
|
213
|
+
return retrieveValueFor(field);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
String value = lastValue.remove(field);
|
|
217
|
+
Log.d(TAG, "Reading value '" + value + "' for field '" + field + "'");
|
|
218
|
+
return value;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
public void handleEvent(String event, String... extraArgs) {
|
|
222
|
+
Log.d(TAG, "User clicked");
|
|
223
|
+
Log.d(TAG, "Current thread is " + Thread.currentThread().getId());
|
|
224
|
+
|
|
225
|
+
if (extraArgs != null) {
|
|
226
|
+
Log.d(TAG, "extraArgs = " + extraArgs.length);
|
|
227
|
+
for (String arg : extraArgs) {
|
|
228
|
+
Log.d(TAG, "arg = '" + arg + "'");
|
|
229
|
+
}
|
|
230
|
+
} else {
|
|
231
|
+
Log.d(TAG, "extraArgs were null!");
|
|
232
|
+
}
|
|
233
|
+
rhino.triggerEvent(pageName, event, extraArgs);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
public void onRenderComplete(Object ignored) {
|
|
237
|
+
runOnUiThread(new Runnable() {
|
|
238
|
+
public void run() {
|
|
239
|
+
for (String event : getEvents()) {
|
|
240
|
+
Log.d(TAG, "About to bind event '" + event + "'");
|
|
241
|
+
webView.loadUrl("javascript:window." + getPageName() + "View.bind('" + event + "', function() { container.handleEvent('" + event + "', _.toArray(arguments)); });");
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
- converter
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
- converter
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
var tw = tw || {};
|
|
2
|
+
tw.bridge = tw.bridge || {};
|
|
3
|
+
|
|
4
|
+
// json.js does stupid things to the Object prototype
|
|
5
|
+
Object.prototype.toJSONString = "";
|
|
6
|
+
Object.prototype.parseJSON = "";
|
|
7
|
+
|
|
8
|
+
function generateRandomString(){
|
|
9
|
+
var str = '';
|
|
10
|
+
var i;
|
|
11
|
+
for (i = 0; i < 32; ++i) {
|
|
12
|
+
var r = Math.floor(Math.random() * 16);
|
|
13
|
+
str = str + r.toString(16);
|
|
14
|
+
}
|
|
15
|
+
return str.toUpperCase();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function bridgeDispatch(proxyId) {
|
|
19
|
+
var extraArgs = _.map(_.toArray(arguments).slice(1), function(obj) { return obj.valueOf(); });
|
|
20
|
+
var proxyPage = tw.bridge.pages.pageByProxyId(proxyId);
|
|
21
|
+
proxyPage.dispatch.apply(proxyPage, extraArgs);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function bridgeSuccessfulResponse(requestId, response) {
|
|
25
|
+
tw.bridge.requests.successfulResponse(requestId, response);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function bridgeFailureResponse(requestId, errorCode, response) {
|
|
29
|
+
tw.bridge.requests.failureResponse(requestId, errorCode, response);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function bridgeFireTimer(timerId) {
|
|
33
|
+
tw.bridge.timers.fireTimer(timerId);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function bridgeInvokeCallback(widgetName) {
|
|
37
|
+
var extraArgs = _.map(_.toArray(arguments).slice(1), function(obj) { return obj.valueOf(); });
|
|
38
|
+
tw.bridge.widgets.callback(widgetName).apply(this, extraArgs);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
tw.bridge.changePage = function(target) {
|
|
42
|
+
tw.bridge.runtime.changePage(target);
|
|
43
|
+
return target;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
tw.bridge.widgets = (function() {
|
|
47
|
+
var callbacks;
|
|
48
|
+
callbacks = {};
|
|
49
|
+
return {
|
|
50
|
+
display: function(name, options, callback) {
|
|
51
|
+
TWBridgePageRegistry.sharedRegistry.displayWidget_withOptions(name, options);
|
|
52
|
+
return callbacks[name] = callback;
|
|
53
|
+
},
|
|
54
|
+
callback: function(name) {
|
|
55
|
+
return callbacks[name];
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
})();
|
|
59
|
+
|
|
60
|
+
tw.bridge.alert = function(message) {
|
|
61
|
+
TWBridgePageRegistry.sharedRegistry.alert(message);
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
tw.bridge.openUrl = function(url) {
|
|
65
|
+
tw.bridge.runtime.openUrl(url);
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
tw.bridge.trackEvent = function(event) {
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
tw.bridge.log = function(message) {
|
|
72
|
+
tw.bridge.runtime.log(message);
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
tw.bridge.request = function(options) {
|
|
76
|
+
if (options.contentType) {
|
|
77
|
+
options.customHeaders = options.customHeaders || {};
|
|
78
|
+
options.customHeaders['Content-Type'] = options.contentType;
|
|
79
|
+
}
|
|
80
|
+
tw.bridge.requests.issue(
|
|
81
|
+
options.url,
|
|
82
|
+
options.method,
|
|
83
|
+
options.body,
|
|
84
|
+
options.success,
|
|
85
|
+
options.failure,
|
|
86
|
+
options.customHeaders);
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
tw.bridge.pageObject = function(pageName) {
|
|
90
|
+
var proxyId = generateRandomString(),
|
|
91
|
+
handlerRegistry = {};
|
|
92
|
+
|
|
93
|
+
tw.bridge.runtime.registerProxyForPage(proxyId, pageName);
|
|
94
|
+
|
|
95
|
+
function bind(event, handler) {
|
|
96
|
+
handlerRegistry[event] = handler;
|
|
97
|
+
tw.bridge.runtime.attachProxyEventHandler(proxyId, event);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function dispatch(event) {
|
|
101
|
+
args = _.toArray(arguments).slice(1);
|
|
102
|
+
if (handlerRegistry[event]) {
|
|
103
|
+
handlerRegistry[event].apply(this, args);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function get(field) {
|
|
108
|
+
return tw.bridge.runtime.valueOfProxyField(proxyId, field);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function cleanValues(jsObject) {
|
|
112
|
+
_.each(_.keys(jsObject), function(key) {
|
|
113
|
+
if (jsObject[key] === null || jsObject[key] === undefined) {
|
|
114
|
+
delete jsObject[key];
|
|
115
|
+
} else if (jsObject[key] === false) {
|
|
116
|
+
jsObject[key] = 0;
|
|
117
|
+
} else {
|
|
118
|
+
tw.bridge.log("key = '" + key + "'; value = '" + jsObject[key] + "'");
|
|
119
|
+
if (jsObject[key] instanceof Object) {
|
|
120
|
+
cleanValues(jsObject[key]);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function render(viewObject) {
|
|
127
|
+
// Clean off properties that cause problems when marshalling
|
|
128
|
+
if (viewObject.hasOwnProperty('toJSONString')) {
|
|
129
|
+
viewObject.toJSONString = null;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Delete any keys that have a null value to avoid the Obj-C JSON
|
|
133
|
+
// serialization failure
|
|
134
|
+
if (viewObject != undefined) {
|
|
135
|
+
cleanValues(viewObject);
|
|
136
|
+
}
|
|
137
|
+
if (viewObject.hasOwnProperty('parseJSON')) {
|
|
138
|
+
viewObject.parseJSON = null;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
tw.bridge.runtime.renderProxy(viewObject, proxyId);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return {
|
|
145
|
+
proxyId: proxyId,
|
|
146
|
+
bind: bind,
|
|
147
|
+
dispatch: dispatch,
|
|
148
|
+
get: get,
|
|
149
|
+
render: render
|
|
150
|
+
};
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
tw.bridge.pages = (function() {
|
|
154
|
+
var pagesByName = {},
|
|
155
|
+
pagesByProxyId = {};
|
|
156
|
+
|
|
157
|
+
function pageNamed(pageName) {
|
|
158
|
+
if (!pagesByName[pageName]) {
|
|
159
|
+
var page = tw.bridge.pageObject(pageName);
|
|
160
|
+
pagesByName[pageName] = page;
|
|
161
|
+
pagesByProxyId[page.proxyId] = page;
|
|
162
|
+
}
|
|
163
|
+
return pagesByName[pageName];
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function pageByProxyId(proxyId) {
|
|
167
|
+
return pagesByProxyId[proxyId];
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return {
|
|
171
|
+
pageNamed: pageNamed,
|
|
172
|
+
pageByProxyId: pageByProxyId
|
|
173
|
+
};
|
|
174
|
+
}());
|
|
175
|
+
|
|
176
|
+
tw.bridge.requests = (function() {
|
|
177
|
+
var successHandlersById = {},
|
|
178
|
+
failureHandlersById = {};
|
|
179
|
+
|
|
180
|
+
function issue(url, method, body, success, failure, customHeaders) {
|
|
181
|
+
var requestId = generateRandomString();
|
|
182
|
+
bodyStr = body;
|
|
183
|
+
|
|
184
|
+
if (bodyStr && bodyStr.constructor !== String) {
|
|
185
|
+
bodyStr = JSON.stringify(body);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
successHandlersById[requestId] = success;
|
|
189
|
+
failureHandlersById[requestId] = failure;
|
|
190
|
+
tw.bridge.runtime.issueRequest({
|
|
191
|
+
requestId: requestId,
|
|
192
|
+
url: url,
|
|
193
|
+
method: method,
|
|
194
|
+
body: bodyStr,
|
|
195
|
+
headers: customHeaders
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function successfulResponse(requestId, response) {
|
|
200
|
+
successHandlersById[requestId](response);
|
|
201
|
+
clearHandlers(requestId);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function failureResponse(requestId, errorCode, response) {
|
|
205
|
+
failureHandlersById[requestId](errorCode, response);
|
|
206
|
+
clearHandlers(requestId);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
function clearHandlers(requestId) {
|
|
210
|
+
successHandlersById[requestId] = null;
|
|
211
|
+
failureHandlersById[requestId] = null;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
return {
|
|
215
|
+
successfulResponse: successfulResponse,
|
|
216
|
+
failureResponse: failureResponse,
|
|
217
|
+
issue: issue
|
|
218
|
+
};
|
|
219
|
+
}());
|
|
220
|
+
|
|
221
|
+
tw.bridge.timers = (function () {
|
|
222
|
+
callbacks = {};
|
|
223
|
+
|
|
224
|
+
return {
|
|
225
|
+
start: function(timeout, callback) {
|
|
226
|
+
var timerId = generateRandomString();
|
|
227
|
+
callbacks[timerId] = callback;
|
|
228
|
+
tw.bridge.runtime.startTimerWithTimeout(timerId, timeout);
|
|
229
|
+
return timerId;
|
|
230
|
+
},
|
|
231
|
+
fireTimer: function(timerId) {
|
|
232
|
+
if (callbacks[timerId]) {
|
|
233
|
+
callbacks[timerId]();
|
|
234
|
+
}
|
|
235
|
+
},
|
|
236
|
+
clearTimer: function(timerId) {
|
|
237
|
+
delete callbacks[timerId];
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
}());
|
|
241
|
+
|
|
242
|
+
tw.bridge.dialog = (function() {
|
|
243
|
+
return {
|
|
244
|
+
display: function(name) {
|
|
245
|
+
TWBridgePageRegistry.sharedRegistry.displayDialog(name)
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
}());
|
|
249
|
+
|