blob: c9fa557b480914bd7d4359fa1c01654e82043738 [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Scripts for the message handler.
goog.provide('__crWeb.message');
goog.require('__crWeb.common');
goog.require('__crWeb.messageDynamic');
/**
* Namespace for this module.
*/
__gCrWeb.message = {};
/* Beginning of anonymous object. */
(function() {
/**
* Object to manage queue of messages waiting to be sent to the main
* application for immediate processing.
* @type {Object}
* @private
*/
var immediateMessageQueue_ = {
scheme: 'crwebinvokeimmediate',
reset: function() {
immediateMessageQueue_.queue = [];
// Since the array will be JSON serialized, protect against non-standard
// custom versions of Array.prototype.toJSON.
immediateMessageQueue_.queue.toJSON = null;
}
};
immediateMessageQueue_.reset();
/**
* Object to manage queue of messages waiting to be sent to the main
* application for asynchronous processing.
* @type {Object}
* @private
*/
var messageQueue_ = {
scheme: 'crwebinvoke',
reset: function() {
messageQueue_.queue = [];
// Since the array will be JSON serialized, protect against non-standard
// custom versions of Array.prototype.toJSON.
messageQueue_.queue.toJSON = null
}
};
messageQueue_.reset();
/**
* Invokes a command immediately on the Objective-C side.
* An immediate command is a special class of command that must be handled at
* the earliest opportunity. See the notes in CRWWebController for
* restrictions and precautions.
* @param {Object} command The command in a JavaScript object.
* @private
*/
__gCrWeb.message.invokeOnHostImmediate = function(command) {
// If there is no document or body, the command will be silently dropped.
if (!document || !document.body)
return;
immediateMessageQueue_.queue.push(command);
sendQueue_(immediateMessageQueue_);
};
/**
* Invokes a command on the Objective-C side.
* @param {Object} command The command in a JavaScript object.
* @private
*/
__gCrWeb.message.invokeOnHost = function(command) {
// Avoid infinite loops in sites that send messages as a side effect
// of URL verification (e.g., due to logging in an XHR override).
if (window.__gCrWeb_Verifying) {
return;
}
messageQueue_.queue.push(command);
sendQueue_(messageQueue_);
};
/**
* Returns the message queue as a string.
* @return {string} The current message queue as a JSON string.
*/
__gCrWeb.message.getMessageQueue = function() {
var messageQueueString = __gCrWeb.common.JSONStringify(messageQueue_.queue);
messageQueue_.reset()
return messageQueueString;
};
/**
* Sends both queues if they contain messages.
*/
__gCrWeb.message.invokeQueues = function() {
if (immediateMessageQueue_.queue.length > 0)
sendQueue_(immediateMessageQueue_);
if (messageQueue_.queue.length > 0)
sendQueue_(messageQueue_);
};
function sendQueue_(queueObject) {
// Do nothing if windowId has not been set.
if (!__gCrWeb.windowIdObject || typeof __gCrWeb.windowId != 'string') {
return;
}
// Some pages/plugins implement Object.prototype.toJSON, which can result
// in serializing messageQueue_ to an invalid format.
var originalObjectToJSON = Object.prototype.toJSON;
if (originalObjectToJSON)
delete Object.prototype.toJSON;
__gCrWeb.message_dynamic.sendQueue(queueObject);
if (originalObjectToJSON) {
// Restore Object.prototype.toJSON to prevent from breaking any
// functionality on the page that depends on its custom implementation.
Object.prototype.toJSON = originalObjectToJSON;
}
};
}());