Adding float-no-zero branch hosted build
This commit is contained in:
@@ -0,0 +1,254 @@
|
||||
// Copyright 2007 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Contains the frame element method transport for cross-domain
|
||||
* communication. It exploits the fact that FF lets a page in an
|
||||
* iframe call a method on the iframe-element it is contained in, even if the
|
||||
* containing page is from a different domain.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.net.xpc.FrameElementMethodTransport');
|
||||
|
||||
goog.require('goog.net.xpc');
|
||||
goog.require('goog.net.xpc.CrossPageChannelRole');
|
||||
goog.require('goog.net.xpc.Transport');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Frame-element method transport.
|
||||
*
|
||||
* Firefox allows a document within an iframe to call methods on the
|
||||
* iframe-element added by the containing document.
|
||||
* NOTE(user): Tested in all FF versions starting from 1.0
|
||||
*
|
||||
* @param {goog.net.xpc.CrossPageChannel} channel The channel this transport
|
||||
* belongs to.
|
||||
* @param {goog.dom.DomHelper=} opt_domHelper The dom helper to use for finding
|
||||
* the correct window.
|
||||
* @constructor
|
||||
* @extends {goog.net.xpc.Transport}
|
||||
*/
|
||||
goog.net.xpc.FrameElementMethodTransport = function(channel, opt_domHelper) {
|
||||
goog.base(this, opt_domHelper);
|
||||
|
||||
/**
|
||||
* The channel this transport belongs to.
|
||||
* @type {goog.net.xpc.CrossPageChannel}
|
||||
* @private
|
||||
*/
|
||||
this.channel_ = channel;
|
||||
|
||||
// To transfer messages, this transport basically uses normal function calls,
|
||||
// which are synchronous. To avoid endless recursion, the delivery has to
|
||||
// be artificially made asynchronous.
|
||||
|
||||
/**
|
||||
* Array for queued messages.
|
||||
* @type {Array}
|
||||
* @private
|
||||
*/
|
||||
this.queue_ = [];
|
||||
|
||||
/**
|
||||
* Callback function which wraps deliverQueued_.
|
||||
* @type {Function}
|
||||
* @private
|
||||
*/
|
||||
this.deliverQueuedCb_ = goog.bind(this.deliverQueued_, this);
|
||||
};
|
||||
goog.inherits(goog.net.xpc.FrameElementMethodTransport, goog.net.xpc.Transport);
|
||||
|
||||
|
||||
/**
|
||||
* The transport type.
|
||||
* @type {number}
|
||||
* @protected
|
||||
* @override
|
||||
*/
|
||||
goog.net.xpc.FrameElementMethodTransport.prototype.transportType =
|
||||
goog.net.xpc.TransportTypes.FRAME_ELEMENT_METHOD;
|
||||
|
||||
|
||||
/**
|
||||
* Flag used to enforce asynchronous messaging semantics.
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
goog.net.xpc.FrameElementMethodTransport.prototype.recursive_ = false;
|
||||
|
||||
|
||||
/**
|
||||
* Timer used to enforce asynchronous message delivery.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
goog.net.xpc.FrameElementMethodTransport.prototype.timer_ = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Holds the function to send messages to the peer
|
||||
* (once it becomes available).
|
||||
* @type {Function}
|
||||
* @private
|
||||
*/
|
||||
goog.net.xpc.FrameElementMethodTransport.outgoing_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* Connect this transport.
|
||||
* @override
|
||||
*/
|
||||
goog.net.xpc.FrameElementMethodTransport.prototype.connect = function() {
|
||||
if (this.channel_.getRole() == goog.net.xpc.CrossPageChannelRole.OUTER) {
|
||||
// get shortcut to iframe-element
|
||||
this.iframeElm_ = this.channel_.getIframeElement();
|
||||
|
||||
// add the gateway function to the iframe-element
|
||||
// (to be called by the peer)
|
||||
this.iframeElm_['XPC_toOuter'] = goog.bind(this.incoming_, this);
|
||||
|
||||
// at this point we just have to wait for a notification from the peer...
|
||||
|
||||
} else {
|
||||
this.attemptSetup_();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Only used from within an iframe. Attempts to attach the method
|
||||
* to be used for sending messages by the containing document. Has to
|
||||
* wait until the containing document has finished. Therefore calls
|
||||
* itself in a timeout if not successful.
|
||||
* @private
|
||||
*/
|
||||
goog.net.xpc.FrameElementMethodTransport.prototype.attemptSetup_ = function() {
|
||||
var retry = true;
|
||||
/** @preserveTry */
|
||||
try {
|
||||
if (!this.iframeElm_) {
|
||||
// throws security exception when called too early
|
||||
this.iframeElm_ = this.getWindow().frameElement;
|
||||
}
|
||||
// check if iframe-element and the gateway-function to the
|
||||
// outer-frame are present
|
||||
// TODO(user) Make sure the following code doesn't throw any exceptions
|
||||
if (this.iframeElm_ && this.iframeElm_['XPC_toOuter']) {
|
||||
// get a reference to the gateway function
|
||||
this.outgoing_ = this.iframeElm_['XPC_toOuter'];
|
||||
// attach the gateway function the other document will use
|
||||
this.iframeElm_['XPC_toOuter']['XPC_toInner'] =
|
||||
goog.bind(this.incoming_, this);
|
||||
// stop retrying
|
||||
retry = false;
|
||||
// notify outer frame
|
||||
this.send(goog.net.xpc.TRANSPORT_SERVICE_, goog.net.xpc.SETUP_ACK_);
|
||||
// notify channel that the transport is ready
|
||||
this.channel_.notifyConnected();
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
goog.log.error(goog.net.xpc.logger,
|
||||
'exception caught while attempting setup: ' + e);
|
||||
}
|
||||
// retry necessary?
|
||||
if (retry) {
|
||||
if (!this.attemptSetupCb_) {
|
||||
this.attemptSetupCb_ = goog.bind(this.attemptSetup_, this);
|
||||
}
|
||||
this.getWindow().setTimeout(this.attemptSetupCb_, 100);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handles transport service messages.
|
||||
* @param {string} payload The message content.
|
||||
* @override
|
||||
*/
|
||||
goog.net.xpc.FrameElementMethodTransport.prototype.transportServiceHandler =
|
||||
function(payload) {
|
||||
if (this.channel_.getRole() == goog.net.xpc.CrossPageChannelRole.OUTER &&
|
||||
!this.channel_.isConnected() && payload == goog.net.xpc.SETUP_ACK_) {
|
||||
// get a reference to the gateway function
|
||||
this.outgoing_ = this.iframeElm_['XPC_toOuter']['XPC_toInner'];
|
||||
// notify the channel we're ready
|
||||
this.channel_.notifyConnected();
|
||||
} else {
|
||||
throw Error('Got unexpected transport message.');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Process incoming message.
|
||||
* @param {string} serviceName The name of the service the message is to be
|
||||
* delivered to.
|
||||
* @param {string} payload The message to process.
|
||||
* @private
|
||||
*/
|
||||
goog.net.xpc.FrameElementMethodTransport.prototype.incoming_ =
|
||||
function(serviceName, payload) {
|
||||
if (!this.recursive_ && this.queue_.length == 0) {
|
||||
this.channel_.xpcDeliver(serviceName, payload);
|
||||
}
|
||||
else {
|
||||
this.queue_.push({serviceName: serviceName, payload: payload});
|
||||
if (this.queue_.length == 1) {
|
||||
this.timer_ = this.getWindow().setTimeout(this.deliverQueuedCb_, 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Delivers queued messages.
|
||||
* @private
|
||||
*/
|
||||
goog.net.xpc.FrameElementMethodTransport.prototype.deliverQueued_ =
|
||||
function() {
|
||||
while (this.queue_.length) {
|
||||
var msg = this.queue_.shift();
|
||||
this.channel_.xpcDeliver(msg.serviceName, msg.payload);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Send a message
|
||||
* @param {string} service The name off the service the message is to be
|
||||
* delivered to.
|
||||
* @param {string} payload The message content.
|
||||
* @override
|
||||
*/
|
||||
goog.net.xpc.FrameElementMethodTransport.prototype.send =
|
||||
function(service, payload) {
|
||||
this.recursive_ = true;
|
||||
this.outgoing_(service, payload);
|
||||
this.recursive_ = false;
|
||||
};
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.net.xpc.FrameElementMethodTransport.prototype.disposeInternal =
|
||||
function() {
|
||||
goog.net.xpc.FrameElementMethodTransport.superClass_.disposeInternal.call(
|
||||
this);
|
||||
this.outgoing_ = null;
|
||||
this.iframeElm_ = null;
|
||||
};
|
||||
Reference in New Issue
Block a user