123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410 |
- goog.provide('goog.net.xpc.IframeRelayTransport');
- goog.require('goog.dom');
- goog.require('goog.dom.TagName');
- goog.require('goog.dom.safe');
- goog.require('goog.events');
- goog.require('goog.html.SafeHtml');
- goog.require('goog.log');
- goog.require('goog.log.Level');
- goog.require('goog.net.xpc');
- goog.require('goog.net.xpc.CfgFields');
- goog.require('goog.net.xpc.Transport');
- goog.require('goog.net.xpc.TransportTypes');
- goog.require('goog.string');
- goog.require('goog.string.Const');
- goog.require('goog.userAgent');
- goog.net.xpc.IframeRelayTransport = function(channel, opt_domHelper) {
- goog.net.xpc.IframeRelayTransport.base(this, 'constructor', opt_domHelper);
-
- this.channel_ = channel;
-
- this.peerRelayUri_ =
- this.channel_.getConfig()[goog.net.xpc.CfgFields.PEER_RELAY_URI];
-
- this.peerIframeId_ =
- this.channel_.getConfig()[goog.net.xpc.CfgFields.IFRAME_ID];
- if (goog.userAgent.WEBKIT) {
- goog.net.xpc.IframeRelayTransport.startCleanupTimer_();
- }
- };
- goog.inherits(goog.net.xpc.IframeRelayTransport, goog.net.xpc.Transport);
- if (goog.userAgent.WEBKIT) {
-
- goog.net.xpc.IframeRelayTransport.iframeRefs_ = [];
-
- goog.net.xpc.IframeRelayTransport.CLEANUP_INTERVAL_ = 1000;
-
- goog.net.xpc.IframeRelayTransport.IFRAME_MAX_AGE_ = 3000;
-
- goog.net.xpc.IframeRelayTransport.cleanupTimer_ = 0;
-
- goog.net.xpc.IframeRelayTransport.startCleanupTimer_ = function() {
- if (!goog.net.xpc.IframeRelayTransport.cleanupTimer_) {
- goog.net.xpc.IframeRelayTransport.cleanupTimer_ =
- window.setTimeout(function() {
- goog.net.xpc.IframeRelayTransport.cleanup_();
- }, goog.net.xpc.IframeRelayTransport.CLEANUP_INTERVAL_);
- }
- };
-
- goog.net.xpc.IframeRelayTransport.cleanup_ = function(opt_maxAge) {
- var now = goog.now();
- var maxAge =
- opt_maxAge || goog.net.xpc.IframeRelayTransport.IFRAME_MAX_AGE_;
- while (goog.net.xpc.IframeRelayTransport.iframeRefs_.length &&
- now - goog.net.xpc.IframeRelayTransport.iframeRefs_[0].timestamp >=
- maxAge) {
- var ifr =
- goog.net.xpc.IframeRelayTransport.iframeRefs_.shift().iframeElement;
- goog.dom.removeNode(ifr);
- goog.log.log(
- goog.net.xpc.logger, goog.log.Level.FINEST, 'iframe removed');
- }
- goog.net.xpc.IframeRelayTransport.cleanupTimer_ = window.setTimeout(
- goog.net.xpc.IframeRelayTransport.cleanupCb_,
- goog.net.xpc.IframeRelayTransport.CLEANUP_INTERVAL_);
- };
-
- goog.net.xpc.IframeRelayTransport.cleanupCb_ = function() {
- goog.net.xpc.IframeRelayTransport.cleanup_();
- };
- }
- goog.net.xpc.IframeRelayTransport.IE_PAYLOAD_MAX_SIZE_ = 1800;
- goog.net.xpc.IframeRelayTransport.FragmentInfo;
- goog.net.xpc.IframeRelayTransport.fragmentMap_ = {};
- goog.net.xpc.IframeRelayTransport.prototype.transportType =
- goog.net.xpc.TransportTypes.IFRAME_RELAY;
- goog.net.xpc.IframeRelayTransport.prototype.connect = function() {
- if (!this.getWindow()['xpcRelay']) {
- this.getWindow()['xpcRelay'] =
- goog.net.xpc.IframeRelayTransport.receiveMessage_;
- }
- this.send(goog.net.xpc.TRANSPORT_SERVICE_, goog.net.xpc.SETUP);
- };
- goog.net.xpc.IframeRelayTransport.receiveMessage_ = function(
- channelName, frame) {
- var pos = frame.indexOf(':');
- var header = frame.substr(0, pos);
- var payload = frame.substr(pos + 1);
- if (!goog.userAgent.IE || (pos = header.indexOf('|')) == -1) {
-
- var service = header;
- } else {
-
-
- var service = header.substr(0, pos);
- var fragmentIdStr = header.substr(pos + 1);
-
-
-
- pos = fragmentIdStr.indexOf('+');
- var messageIdStr = fragmentIdStr.substr(0, pos);
- var fragmentNum = parseInt(fragmentIdStr.substr(pos + 1), 10);
- var fragmentInfo =
- goog.net.xpc.IframeRelayTransport.fragmentMap_[messageIdStr];
- if (!fragmentInfo) {
- fragmentInfo =
- goog.net.xpc.IframeRelayTransport.fragmentMap_[messageIdStr] =
- {fragments: [], received: 0, expected: 0};
- }
- if (goog.string.contains(fragmentIdStr, '++')) {
- fragmentInfo.expected = fragmentNum + 1;
- }
- fragmentInfo.fragments[fragmentNum] = payload;
- fragmentInfo.received++;
- if (fragmentInfo.received != fragmentInfo.expected) {
- return;
- }
-
-
- payload = fragmentInfo.fragments.join('');
- delete goog.net.xpc.IframeRelayTransport.fragmentMap_[messageIdStr];
- }
- goog.net.xpc.channels[channelName].xpcDeliver(
- service, decodeURIComponent(payload));
- };
- goog.net.xpc.IframeRelayTransport.prototype.transportServiceHandler = function(
- payload) {
- if (payload == goog.net.xpc.SETUP) {
-
-
- this.send(goog.net.xpc.TRANSPORT_SERVICE_, goog.net.xpc.SETUP_ACK_);
- this.channel_.notifyConnected();
- } else if (payload == goog.net.xpc.SETUP_ACK_) {
- this.channel_.notifyConnected();
- }
- };
- goog.net.xpc.IframeRelayTransport.prototype.send = function(service, payload) {
-
-
-
- var encodedPayload = encodeURIComponent(payload);
- var encodedLen = encodedPayload.length;
- var maxSize = goog.net.xpc.IframeRelayTransport.IE_PAYLOAD_MAX_SIZE_;
- if (goog.userAgent.IE && encodedLen > maxSize) {
-
-
- var messageIdStr = goog.string.getRandomString();
- for (var startIndex = 0, fragmentNum = 0; startIndex < encodedLen;
- fragmentNum++) {
- var payloadFragment = encodedPayload.substr(startIndex, maxSize);
- startIndex += maxSize;
- var fragmentIdStr =
- messageIdStr + (startIndex >= encodedLen ? '++' : '+') + fragmentNum;
- this.send_(service, payloadFragment, fragmentIdStr);
- }
- } else {
- this.send_(service, encodedPayload);
- }
- };
- goog.net.xpc.IframeRelayTransport.prototype.send_ = function(
- service, encodedPayload, opt_fragmentIdStr) {
-
-
- if (goog.userAgent.IE) {
- var div =
- this.getWindow().document.createElement(String(goog.dom.TagName.DIV));
-
-
- goog.dom.safe.setInnerHtml(
- div, goog.html.SafeHtml.createIframe(null, null, {
- 'onload': goog.string.Const.from('this.xpcOnload()'),
- 'sandbox': null
- }));
- var ifr = div.childNodes[0];
- div = null;
- ifr['xpcOnload'] = goog.net.xpc.IframeRelayTransport.iframeLoadHandler_;
- } else {
- var ifr = this.getWindow().document.createElement(
- String(goog.dom.TagName.IFRAME));
- if (goog.userAgent.WEBKIT) {
-
-
- goog.net.xpc.IframeRelayTransport.iframeRefs_.push(
- {timestamp: goog.now(), iframeElement: ifr});
- } else {
- goog.events.listen(
- ifr, 'load', goog.net.xpc.IframeRelayTransport.iframeLoadHandler_);
- }
- }
- var style = ifr.style;
- style.visibility = 'hidden';
- style.width = ifr.style.height = '0px';
- style.position = 'absolute';
- var url = this.peerRelayUri_;
- url += '#' + this.channel_.name;
- if (this.peerIframeId_) {
- url += ',' + this.peerIframeId_;
- }
- url += '|' + service;
- if (opt_fragmentIdStr) {
- url += '|' + opt_fragmentIdStr;
- }
- url += ':' + encodedPayload;
- ifr.src = url;
- this.getWindow().document.body.appendChild(ifr);
- goog.log.log(goog.net.xpc.logger, goog.log.Level.FINEST, 'msg sent: ' + url);
- };
- goog.net.xpc.IframeRelayTransport.iframeLoadHandler_ = function() {
- goog.log.log(goog.net.xpc.logger, goog.log.Level.FINEST, 'iframe-load');
- goog.dom.removeNode(this);
- this.xpcOnload = null;
- };
- goog.net.xpc.IframeRelayTransport.prototype.disposeInternal = function() {
- goog.net.xpc.IframeRelayTransport.base(this, 'disposeInternal');
- if (goog.userAgent.WEBKIT) {
- goog.net.xpc.IframeRelayTransport.cleanup_(0);
- }
- };
|