Skip to content

Instantly share code, notes, and snippets.

@ryanhanwu
Last active August 29, 2015 14:17
Show Gist options
  • Save ryanhanwu/442a5a8bd0ad7868fdbb to your computer and use it in GitHub Desktop.
Save ryanhanwu/442a5a8bd0ad7868fdbb to your computer and use it in GitHub Desktop.
FBAppKit.bundle/bridge.js
(function() {
if (!window.__fbNative) {
var e = {
_iframe: null,
callNative: function(a, b) {
e._iframe && document.body.removeChild(e._iframe);
var c = document.createElement("iframe");
c.style.width = c.style.height = "1px";
c.style.position = "absolute";
c.style.borderStyle = "none";
for (var d = 0; d < b.length; ++d) "undefined" === typeof b[d] && (b[d] = null);
d = "fbrpc://call?payload=" + encodeURIComponent(JSON.stringify({
method: a,
parameters: b || []
}));
c.src = d;
document.body.appendChild(c);
e._iframe = c
}
},
f = {
"dialog.open": function(a) {
var b = "fbwid_" +
("" + Math.random()).substr(2);
e.callNative("openURL:windowID:", [a.url, b]);
return b
},
"dialog.close": function(a) {
e.callNative("closeWindowWithID:", [a.wid]);
return null
},
"dialog.postMessage": function(a) {
e.callNative("postMessage:targetOrigin:windowID:", [a.message, a.targetOrigin, a.wid]);
return null
},
"toolbar.setCancelAction": function(a) {
e.callNative("setCancelAction:handleCancelEvent:", [a.label, a.handleCancelEvent]);
return null
}
};
window.__fbNative = {
invoke: function(a) {
if ("string" !== typeof a || 0 !== a.indexOf("FB_RPC:")) return !1;
a = JSON.parse(a.substr(7));
if ("2.0" !== a.jsonrpc) return !1;
var b = f[a.method];
if (!b) return !1;
b = b(a.params);
"id" in a && (a = {
id: a.id,
jsonrpc: "2.0",
result: b,
error: null
}, b = document.createEvent("Event"), b.initEvent("message", !0, !1), b.data = "FB_RPC:" + JSON.stringify(a), document.dispatchEvent(b));
return !0
},
getFeatures: function() {
return {
dialog: 1
}
},
open: function(a) {
var b = f["dialog.open"]({
url: a
});
return window.__fbNative.dialog = {
close: function() {
window.__fbNative.close(b);
this.closed = !0
},
closed: !1,
postMessage: function(a,
d) {
window.__fbNative.postMessage(a, d, b)
}
}
},
close: function(a) {
f["dialog.close"]({
wid: a
})
},
postMessage: function(a, b, c) {
f["dialog.postMessage"]({
message: a,
targetOrigin: b,
wid: c
})
},
setCancelAction: function(a, b) {
f["toolbar.setCancelAction"]({
label: a,
handleCancelEvent: b
})
}
}
}
})();
/**
* JavaScript to be used with the simple JavaScript->native bridge
* included in Wilde v1 for Mobile Canvas support.
*
* @provides wilde-mobile-canvas-bridge
*/
// The only thing this code actually exposes in the global namespace
// is window.__fbNative; scroll to the bottom to see the explicit
// export.
//
// WARNING: Wilde injects a local copy of this file! Don't expect your
// changes in the www tree to affect the app unless you've recompiled it!
(function() {
if (window.__fbNative) {
return;
}
var Bridge = {
_iframe: null,
// Method is an Objective-C selector name
// and parameters must be an array of strings (all current methods
// use strings, and technical details of Objective-C make it
// easier to check argument types if we don't have to do with more
// than one of strings, dictionaries, and arrays).
callNative: function(method, parameters) {
// Make a new iframe for this call.
if (Bridge._iframe) {
document.body.removeChild(Bridge._iframe);
}
var iframe = document.createElement('iframe');
iframe.style.width = iframe.style.height = '1px';
iframe.style.position = 'absolute';
iframe.style.borderStyle = 'none';
// Coerce undefined parameters to null.
for (var ii = 0; ii < parameters.length; ++ii) {
if (typeof parameters[ii] === 'undefined') {
parameters[ii] = null;
}
}
// Assemble the call URL.
var call = {
method: method,
parameters: parameters || []
};
var href = 'fbrpc://call?payload=' +
encodeURIComponent(JSON.stringify(call));
// Insert the new iframe.
iframe.src = href;
document.body.appendChild(iframe);
Bridge._iframe = iframe;
}
};
var FB_RPC_PREFIX = 'FB_RPC:';
var _dispatchMessageEventWithData = function(data) {
var ev = document.createEvent('Event');
ev.initEvent('message', true, false); // Bubbles, can't be cancelled.
ev.data = FB_RPC_PREFIX + JSON.stringify(data);
document.dispatchEvent(ev);
};
// Supported RPCs.
var rpcs = {
'dialog.open': function(params) {
var wid = 'fbwid_' + ('' + Math.random()).substr(2);
Bridge.callNative('openURL:windowID:', [params.url, wid]);
return wid;
},
'dialog.close': function(params) {
Bridge.callNative('closeWindowWithID:', [params.wid]);
return null;
},
'dialog.postMessage': function(params) {
Bridge.callNative('postMessage:targetOrigin:windowID:',
[params.message, params.targetOrigin, params.wid]);
return null;
},
'toolbar.setCancelAction': function(params) {
Bridge.callNative('setCancelAction:handleCancelEvent:',
[params.label, params.handleCancelEvent]);
return null;
}
};
var fbNative = {
// Send a JSON-RPC message to the native application via the
// native bridge transport layer.
//
// rpc_s is a JSON-encoded JSON-RPC object, prefixed with
// FB_RPC_PREFIX. See http://jsonrpc.org/specification for
// the format and semantics.
//
// Returns false if there was an error parsing or dispatching the
// message itself, true otherwise.
//
// TODO(#1008855): support batching.
invoke: function(rpc_s) {
if (typeof rpc_s !== 'string' || rpc_s.indexOf(FB_RPC_PREFIX) !== 0) {
return false;
}
var rpc = JSON.parse(rpc_s.substr(FB_RPC_PREFIX.length));
if (rpc.jsonrpc !== '2.0') {
return false;
}
var impl = rpcs[rpc.method];
if (!impl) {
return false;
}
var result = impl(rpc.params);
// RPCs are synchronous for now, so fire the callback.
if ('id' in rpc) {
_dispatchMessageEventWithData({id: rpc.id,
jsonrpc: '2.0',
result: result,
error: null});
}
return true;
},
getFeatures: function() {
// Map feature name to version.
return {dialog: 1};
},
// Pre-RPC compatibility functions.
open: function(url) {
var wid = rpcs['dialog.open']({url:url});
var dialog = window.__fbNative.dialog = {
close: function() {
window.__fbNative.close(wid);
this.closed = true;
},
closed: false,
postMessage: function(message, targetOrigin) {
window.__fbNative.postMessage(message, targetOrigin, wid);
}
};
return dialog;
},
close: function(wid) {
rpcs['dialog.close']({wid:wid});
},
postMessage: function(message, targetOrigin, wid) {
rpcs['dialog.postMessage'](
{
message: message,
targetOrigin: targetOrigin,
wid: wid
}
);
},
setCancelAction: function(label, handleCancelEvent) {
rpcs['toolbar.setCancelAction'](
{
label: label,
handleCancelEvent: handleCancelEvent
}
);
}
};
window.__fbNative = fbNative;
}());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment