Mercurial > summit-idp
changeset 17:18d28e6a9887
Added sample client and postMessage-based API.
author | Atul Varma <avarma@mozilla.com> |
---|---|
date | Fri, 25 Jun 2010 11:39:28 -0700 |
parents | 9455ec115a5c |
children | f6db6f8cbf5b |
files | static-files/api.js static-files/example-client.html static-files/index.html static-files/index.js |
diffstat | 4 files changed, 215 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/static-files/api.js Fri Jun 25 11:39:28 2010 -0700 @@ -0,0 +1,146 @@ +( + // Set up the public API for the Summit IDP. + function(window) { + var currId = 0; + + function MessageBroker(handlers, postMessage) { + var awaitingResponses = {}; + + function sendResponse(id, value) { + var responseMsg = { + type: "response", + id: id, + value: value + }; + postMessage(responseMsg); + } + + this.callCmd = function callCmd(cmd, options, cb) { + var msg = { + type: "cmd", + name: cmd, + id: ++currId, + options: options + }; + if (cb) { + awaitingResponses[currId] = cb; + msg.cb = true; + } + postMessage(msg); + }; + + this.onMessage = function onMessage(msg) { + switch (msg.type) { + case "response": + if (msg.id in awaitingResponses) { + var cb = awaitingResponses[msg.id]; + delete awaitingResponses[msg.id]; + cb(msg.value); + } + break; + case "cmd": + var handler = msg.name; + if (handler in handlers) { + var cb = undefined; + if (msg.cb) + cb = function(response) { + sendResponse(msg.id, response); + }; + handlers[handler](msg.options, cb); + } + break; + } + }; + } + + function Server(handlers, isOriginValid) { + var broker = new MessageBroker(handlers, postMessage); + var originBrokers = {}; + var allSources = []; + + function brokerForOrigin(origin, source) { + function postMessage(msg) { + source.postMessage(JSON.stringify(msg), origin); + } + + return new MessageBroker(handlers, postMessage); + } + + function onMessage(event) { + if (!(event.origin in originBrokers)) { + if (isOriginValid && !isOriginValid(event.origin)) + return; + originBrokers[event.origin] = brokerForOrigin(event.origin, + event.source); + allSources.push(event.source); + } + + if (allSources.indexOf(event.source) == -1) + throw new Error("Clients from the same origin are not " + + "currently supported: " + event.origin); + originBrokers[event.origin].onMessage(JSON.parse(event.data)); + } + + window.addEventListener("message", onMessage, false); + } + + function GenericClient(origin, path) { + var broker = new MessageBroker({}, postMessage); + var iframe = window.document.createElement("iframe"); + var otherWindow; + var queuedMessages = []; + + if (!path) + path = "/"; + + iframe.src = origin + path; + + iframe.onload = function() { + otherWindow = iframe.contentWindow; + queuedMessages.forEach(postMessage); + queuedMessages = []; + }; + + iframe.style.display = "none"; + window.document.documentElement.appendChild(iframe); + + function postMessage(msg) { + if (!otherWindow) + queuedMessages.push(msg); + else + otherWindow.postMessage(JSON.stringify(msg), origin); + } + + function onMessage(event) { + if (event.origin == origin) + broker.onMessage(JSON.parse(event.data)); + } + + this.callCmd = broker.callCmd; + + window.addEventListener("message", onMessage, false); + }; + + function Client(origin, path) { + var self = this; + var client = new GenericClient(origin, path); + + function addMethod(name) { + self[name] = function(options, cb) { + if (typeof(options) == "function" && !cb) { + cb = options; + options = null; + } + client.callCmd(name, options, cb); + }; + } + + addMethod("getAllUsers"); + } + + window.Summit = { + Client: Client, + Server: Server + }; + } +)(window);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/static-files/example-client.html Fri Jun 25 11:39:28 2010 -0700 @@ -0,0 +1,37 @@ +<html> +<head> + <title>Example Client</title> + <style> + #error { + background: red; + color: white; + display: none; + } + </style> +</head> +<body> +<p>JSON data for all users should appear below, unless you're not +logged in, in which case you should <a target="_blank" href="/">log +in</a>.</p> +<pre id="users"></pre> +<div id="error"> + Error: <span class="reason"></span> +</div> +<script src="api.js"></script> +<script src="jquery-1.4.2.min.js"></script> +<script> +$(window).ready(function(event) { + var api = new Summit.Client(window.location.protocol + "//" + + window.location.host); + api.getAllUsers(function(response) { + if (response.error) { + $("#error .reason").text(response.error); + $("#error").slideDown(); + } else { + $("#users").text(JSON.stringify(response.users)); + } + }); +}); +</script> +</body> +</html> \ No newline at end of file
--- a/static-files/index.html Thu Jun 24 22:53:16 2010 -0700 +++ b/static-files/index.html Fri Jun 25 11:39:28 2010 -0700 @@ -54,6 +54,7 @@ <div class="button start-over">Log Out</div> </div> <script src="jquery-1.4.2.min.js"></script> +<script src="api.js"></script> <script src="index.js"></script> </body> </html>
--- a/static-files/index.js Thu Jun 24 22:53:16 2010 -0700 +++ b/static-files/index.js Fri Jun 25 11:39:28 2010 -0700 @@ -70,13 +70,6 @@ break; case "logged-in": $(".login-email").text(Config.value.email); - jQuery.getJSON( - "/profile", - {token: Config.value.token}, - function(data, textStatus) { - // TODO: This is only temporary, change it. - console.log(data, textStatus); - }); break; } } @@ -148,3 +141,34 @@ $(window).ready(initUI); } )(window); + +( + // Set up the postMessage API. + function(window) { + var handlers = { + getAllUsers: function(options, cb) { + if (Config.value.state != "logged-in") { + cb({error: "not logged in"}); + return; + } + + jQuery.getJSON( + "/profile", + {token: Config.value.token}, + function(data, textStatus) { + if (textStatus == "success") + cb({users: data}); + else + cb({error: "an error occurred retrieving user data."}); + }); + } + }; + + function isOriginValid(origin) { + // TODO: Finish this. + return true; + } + + var server = new Summit.Server(handlers, isOriginValid); + } +)(window);