Skip to content
This repository has been archived by the owner on Oct 12, 2021. It is now read-only.

Commit

Permalink
Merge pull request #100 from mozilla/bug/689792-contentWindow
Browse files Browse the repository at this point in the history
Bug/689792 content window r=anant
  • Loading branch information
mixedpuppy committed Sep 28, 2011
2 parents 865a614 + 5f4b4f4 commit 9fcdc63
Show file tree
Hide file tree
Showing 8 changed files with 211 additions and 223 deletions.
55 changes: 36 additions & 19 deletions addons/jetpack/data/mediatorapi.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
/* -*- Mode: JavaScript; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */

// The mediation API. This script is injected by jetpack into all mediators.
if (!window.navigator.mozApps) window.navigator.mozApps = {}
if (!window.navigator.mozApps.mediation) window.navigator.mozApps.mediation = {}

// Insert the mediator api into unsafeWindow
if (!unsafeWindow.navigator.mozApps)
unsafeWindow.navigator.mozApps = window.navigator.mozApps;
if (!unsafeWindow.navigator.mozApps.mediation) 3
unsafeWindow.navigator.mozApps.mediation = window.navigator.mozApps.mediation;

let allServices = {} // keyed by handler URL.
// This object should look very much like the Service object in repo.js
// with the addition of an 'iframe' attribute and a couple of helper fns.
Expand All @@ -12,6 +19,13 @@ let allServices = {} // keyed by handler URL.
// service: The service name.
// launch_url: The end-point of the service itself.

function S4() {
return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
}
function guid() {
return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());
}
var invokeId = 0;

function Service(svcinfo, activity, iframe) {
for (let name in svcinfo) {
Expand Down Expand Up @@ -40,23 +54,32 @@ Service.prototype = {
return this.iframe.contentWindow
},
call: function(action, args, cb, cberr) {
invokeId++;
let activity = {
action: this.activity.action,
type: this.activity.type,
message: action,
data: args
data: args,
success: 'owa.mediation.success.'+(invokeId),
error: 'owa.mediation.error.'+(invokeId),
origin: this.app.origin
}

function cbshim(result) {
cb(JSON.parse(result));
function postResult(result) {
self.port.removeListener(activity.error, postException);
cb(result);
}

function cberrshim(result) {
function postException(result) {
self.port.removeListener(activity.success, postResult);
if (cberr) {
cberr(JSON.parse(result));
cberr(result);
}
}
unsafeWindow.navigator.mozApps.mediation._invokeService(this._getServiceFrame(), activity, action, cbshim, cberrshim);
self.port.once(activity.success, postResult);
self.port.once(activity.error, postException);

self.port.emit('owa.mediation.invoke', activity);
},

// Get the closest icon that is equal to or larger than the requested size,
Expand Down Expand Up @@ -143,7 +166,14 @@ window.navigator.mozApps.mediation.ready = function(invocationHandler) {

for (var i = 0; i < msg.serviceList.length; i++) {
var svc = msg.serviceList[i];
let id = guid();
// notify our mediator of the guid to watch for
self.port.emit('owa.mediation.frame', {
origin: svc.app.origin,
id: id
});
let iframe = document.createElement("iframe");
iframe.setAttribute('id', id);
iframe.src = svc.url;

let svcob = new Service(svc, msg.activity, iframe);
Expand Down Expand Up @@ -202,17 +232,4 @@ var mPort = {
self.port.removeListener(event, fn);
}
};

unsafeWindow.navigator.mozApps.mediation.port = mPort;

window.navigator.mozApps.mediation.invokeService = function(iframe, activity, message, callback) {//XX error cb?
function callbackShim(result) {
callback(JSON.parse(result));
}
// ideally we could use the port mechanism, but this is stymied by the
// inability to pass iframe or iframe.contentWindow in args to emit().
// Need to use unsafeWindow here for some reason.
unsafeWindow.navigator.mozApps.mediation._invokeService(iframe.contentWindow, activity, message, callbackShim);
};

unsafeWindow.navigator.mozApps.mediation.invokeService = window.navigator.mozApps.mediation.invokeService;
17 changes: 17 additions & 0 deletions addons/jetpack/data/service.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@
/* vim: set ts=2 et sw=2 tw=80: */
var gServiceList;

function S4() {
return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
}
function guid() {
return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());
}

function renderRequestExplanation(activity) {
$("#requestInfo").empty();

Expand Down Expand Up @@ -36,10 +43,20 @@ function handleSetup(activity, serviceList) {
renderRequestExplanation(activity);

addServicesService.url = "http://localhost:8420/" + activity.action + ".html";
addServicesService.iframe = document.createElement('iframe');
addServicesService.iframe.setAttribute('id', guid());
addServicesService.iframe.src = addServicesService.url;
var services = serviceList.concat(addServicesService);

$("#serviceTabs").tmpl({
'services': services
}).appendTo("#servicebox");
// insert the service iframes now
for (var i = 0; i < services.length; i++) {
var svc = services[i];
svc.iframe.classList.add("serviceFrame");
$('div[id="svc-tab-'+i+'"]').append(svc.iframe);
}
$("#services").tabs();
}

Expand Down
4 changes: 1 addition & 3 deletions addons/jetpack/data/service2.html
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,7 @@
{{/each}}
</ul>
{{each( i, svc ) services}}
<div id="svc-tab-${i}" class="serviceDiv">
<iframe id="svc-frame-${i}" src="${svc.url}" class="serviceFrame" />
</div>
<div id="svc-tab-${i}" class="serviceDiv"></div>
{{/each}}
</div>
</script>
Expand Down
72 changes: 72 additions & 0 deletions addons/jetpack/data/servicesapi.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@

if (!window.navigator.mozApps)
window.navigator.mozApps = {}
if (!window.navigator.mozApps.services)
window.navigator.mozApps.services = {}

// Insert the services api into unsafeWindow
if (!unsafeWindow.navigator.mozApps)
unsafeWindow.navigator.mozApps = window.navigator.mozApps;
if (!unsafeWindow.navigator.mozApps.mediation) 3
unsafeWindow.navigator.mozApps.services = window.navigator.mozApps.services;

var activities = {};
var origin = null;
var callid = 0;

window.navigator.mozApps.services = {
// notify our mediator that we're ready for business.
ready: function() {
self.port.emit("owa.service.ready", origin);
},
// the service is registering a handler. we track it here and then let the mediator know
// we're listing for shit
registerHandler: function(action, message, func) {
var activity = {
origin: origin,
action: action,
message: message
}
activities[action+"/"+message] = {
activity: activity,
message: message,
callback: func
}
self.port.emit("owa.service.register.handler", activity);
},
// the service is making an oauth call, setup a result callback mechanism then make the call.
// the service will already have oauth credentials from an early login process initiated by
// our mediator
oauth: {
call: function(svc, data, callback) {
callid++;
self.port.once("owa.service.oauth.call.result."+callid, function(result) {
callback(result);
});
self.port.emit('owa.service.oauth.call', {
svc: svc,
data: data,
result: "owa.service.oauth.call.result."+callid
});
}
}
}

self.port.on("owa.service.origin", function(frameOrigin) {
origin = frameOrigin;
});

// someone called invokeService, we handle it here
self.port.on("owa.service.invoke", function(args) {
var activity = args.activity;
var credentials = args.credentials;
activity.postResult = function postResult(result) {
self.port.emit(activity.success, result);
}
activity.postException = function postException(exc) {
self.port.emit(activity.error, exc);
}
activities[activity.action+"/"+activity.message].callback(activity, credentials);
});

unsafeWindow.navigator.mozApps.services = window.navigator.mozApps.services;
57 changes: 0 additions & 57 deletions addons/jetpack/lib/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,63 +177,6 @@ openwebapps.prototype = {
}
});

// this one kinda sucks - but it is the only way markh can find to
// pass a content object (eg, the iframe or the frame's content window).
// Attempting to pass it via self.emit() fails...
win.appinjector.register({
apibase: "navigator.mozApps.mediation",
name: "_invokeService",
script: null,
getapi: function(contentWindowRef) {
return function (iframe, activity, message, cb, cberr) {
if (activity.data) {
activity.data = JSON.parse(JSON.stringify(activity.data)); // flatten and reinflate...
}
self._services.invokeService(iframe.wrappedJSObject, activity, message, cb, cberr);
}
}
});

// XXX TEMPORARY HACK to allow our builtin apps to work for the all-hands demo
var {OAuthConsumer} = require("oauthorizer/oauthconsumer");
win.appinjector.register({
apibase: "navigator.mozApps.oauth",
name: "call",
script: null,
getapi: function(contentWindowRef) {
return function(svc, message, callback) {
OAuthConsumer.call(svc, message, function(req) {
//dump("oauth call response "+req.status+" "+req.statusText+" "+req.responseText+"\n");
let response = JSON.parse(req.responseText);
callback(response);
});
}
}
});

// services APIs
win.appinjector.register({
apibase: "navigator.mozApps.services",
name: "ready",
script: null,
getapi: function(contentWindowRef) {
return function(args) {
self._services.initApp(contentWindowRef.wrappedJSObject);
}
}
});

win.appinjector.register({
apibase: "navigator.mozApps.services",
name: "registerHandler",
script: null,
getapi: function(contentWindowRef) {
return function(activity, message, func) {
self._services.registerServiceHandler(contentWindowRef.wrappedJSObject, activity, message, func);
}
}
});

// management APIs:
win.appinjector.register({
apibase: "navigator.mozApps.mgmt",
Expand Down
Loading

0 comments on commit 9fcdc63

Please sign in to comment.