86846dd68701c597801a0cbfe8a60be85cd1662e
[platform/framework/web/crosswalk.git] / src / third_party / libjingle / source / talk / examples / ios / AppRTCDemo / ios_channel.html
1 <html>
2   <head>
3     <script src="http://apprtc.appspot.com/_ah/channel/jsapi"></script>
4   </head>
5   <!--
6   Helper HTML that redirects Google AppEngine's Channel API to Objective C.
7   This is done by hosting this page in an iOS application.  The hosting
8   class creates a UIWebView control and implements the UIWebViewDelegate
9   protocol.  Then when there is a channel message it is queued in JS,
10   and an IFRAME is added to the DOM, triggering a navigation event
11   |shouldStartLoadWithRequest| in Objective C which can then fetch the
12   message using |popQueuedMessage|.  This queuing is necessary to avoid URL
13   length limits in UIWebView (which are undocumented).
14   -->
15   <body onbeforeunload="closeSocket()" onload="openSocket()">
16     <script type="text/javascript">
17       // QueryString is copy/pasta from
18       // chromium's chrome/test/data/media/html/utils.js.
19       var QueryString = function () {
20         // Allows access to query parameters on the URL; e.g., given a URL like:
21         //    http://<url>/my.html?test=123&bob=123
22         // parameters can now be accessed via QueryString.test or
23         // QueryString.bob.
24         var params = {};
25
26         // RegEx to split out values by &.
27         var r = /([^&=]+)=?([^&]*)/g;
28
29         // Lambda function for decoding extracted match values. Replaces '+'
30         // with space so decodeURIComponent functions properly.
31         function d(s) { return decodeURIComponent(s.replace(/\+/g, ' ')); }
32
33         var match;
34         while (match = r.exec(window.location.search.substring(1)))
35           params[d(match[1])] = d(match[2]);
36
37         return params;
38       } ();
39
40       var channel = null;
41       var socket = null;
42       // In-order queue of messages to be delivered to ObjectiveC.
43       // Each is a JSON.stringify()'d dictionary containing a 'type'
44       // field and optionally a 'payload'.
45       var messageQueue = [];
46
47       function openSocket() {
48         if (!QueryString.token || !QueryString.token.match(/^[A-z0-9_-]+$/)) {
49           // Send error back to ObjC.  This will assert in GAEChannelClient.m.
50           sendMessageToObjC("JSError:Missing/malformed token parameter " +
51                             QueryString.token);
52           throw "Missing/malformed token parameter: " + QueryString.token;
53         }
54         channel = new goog.appengine.Channel(QueryString.token);
55         socket = channel.open({
56           'onopen': function() {
57             sendMessageToObjC("onopen");
58           },
59           'onmessage': function(msg) {
60             sendMessageToObjC("onmessage", msg);
61           },
62           'onclose': function() {
63             sendMessageToObjC("onclose");
64           },
65           'onerror': function(err) {
66             sendMessageToObjC("onerror", err);
67           }
68         });
69       }
70
71       function closeSocket() {
72         socket.close();
73       }
74
75       // Add an IFRAME to the DOM to trigger a navigation event.  Then remove
76       // it as it is no longer needed.  Only one event is generated.
77       function sendMessageToObjC(type, payload) {
78         messageQueue.push(JSON.stringify({'type': type, 'payload': payload}));
79         var iframe = document.createElement("IFRAME");
80         iframe.setAttribute("src", "js-frame:");
81         // For some reason we need to set a non-empty size for the iOS6
82         // simulator...
83         iframe.setAttribute("height", "1px");
84         iframe.setAttribute("width", "1px");
85         document.documentElement.appendChild(iframe);
86         iframe.parentNode.removeChild(iframe);
87       }
88
89       function popQueuedMessage() {
90         return messageQueue.shift();
91       }
92     </script>
93   </body>
94 </html>