Commit 494885e1 authored by thakis@chromium.org's avatar thakis@chromium.org

Revert 162353 (ShimSrcAttribute in browser_tests on linux asan)

- Browser Plugin: Add HTML5-like postMessage support

This is an implementation of HTML5-like postMessage support for the browser plugin.

It works as follows:

In BrowserPluginEmbedder:NavigateGuest, the browser process creates two swapped out RenderView: A swapped out RenderView for the guest in the embedder render process and a swapped out RenderView for the embedder in the guest render process.

The guest RenderView in the embedder process can be accessed via browserPlugin.contentWindow or through the MessageEvent object received from the guest, event.source.

The embedder RenderView in the guest process can be accessed through the MessageEvent object on message events, event.source.

BrowserPluginEmbedderHelper, and BrowserPluginGuestHelper intercept ViewHostMsg_RouteMessageEvent messages from the swapped out RenderViews and route them appropriately.

Note: BrowserPluginBindings now registers add/removeCustomEventListener instead of add/removeEventListener so that the default WebKit implementations are not shadowed by the custom implementations to allow for WebKit MessageEvents to be registered.
BUG=141238

Review URL: https://chromiumcodereview.appspot.com/10829225

TBR=fsamuel@chromium.org

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@162442 0039d316-1c4b-4281-b951-d872f2087c98
parent b5f4c43d
...@@ -109,14 +109,6 @@ void BrowserPluginEmbedder::CreateGuest(RenderViewHost* render_view_host, ...@@ -109,14 +109,6 @@ void BrowserPluginEmbedder::CreateGuest(RenderViewHost* render_view_host,
guest_renderer_prefs->throttle_input_events = false; guest_renderer_prefs->throttle_input_events = false;
AddGuest(instance_id, guest_web_contents); AddGuest(instance_id, guest_web_contents);
guest_web_contents->SetDelegate(guest); guest_web_contents->SetDelegate(guest);
// Create a swapped out RenderView for the guest in the embedder render
// process, so that the embedder can access the guest's window object.
int guest_routing_id =
static_cast<WebContentsImpl*>(guest->GetWebContents())->
CreateSwappedOutRenderView(web_contents()->GetSiteInstance());
render_view_host->Send(new BrowserPluginMsg_GuestContentWindowReady(
instance_id, guest_routing_id));
} }
void BrowserPluginEmbedder::NavigateGuest( void BrowserPluginEmbedder::NavigateGuest(
...@@ -139,7 +131,7 @@ void BrowserPluginEmbedder::NavigateGuest( ...@@ -139,7 +131,7 @@ void BrowserPluginEmbedder::NavigateGuest(
// TODO(creis): Check the validity of the URL: http://crbug.com/139397. // TODO(creis): Check the validity of the URL: http://crbug.com/139397.
guest_web_contents->GetController().LoadURL(url, guest_web_contents->GetController().LoadURL(url,
Referrer(), Referrer(),
PAGE_TRANSITION_AUTO_TOPLEVEL, PAGE_TRANSITION_AUTO_SUBFRAME,
std::string()); std::string());
} }
...@@ -251,6 +243,7 @@ void BrowserPluginEmbedder::DestroyGuestByInstanceID(int instance_id) { ...@@ -251,6 +243,7 @@ void BrowserPluginEmbedder::DestroyGuestByInstanceID(int instance_id) {
void BrowserPluginEmbedder::RenderViewDeleted( void BrowserPluginEmbedder::RenderViewDeleted(
RenderViewHost* render_view_host) { RenderViewHost* render_view_host) {
DestroyGuests();
} }
void BrowserPluginEmbedder::RenderViewGone(base::TerminationStatus status) { void BrowserPluginEmbedder::RenderViewGone(base::TerminationStatus status) {
......
...@@ -833,93 +833,4 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, AcceptDragEvents) { ...@@ -833,93 +833,4 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, AcceptDragEvents) {
EXPECT_EQ(expected_title, actual_title); EXPECT_EQ(expected_title, actual_title);
} }
// This test verifies that round trip postMessage works as expected.
// 1. The embedder posts a message 'testing123' to the guest.
// 2. The guest receives and replies to the message using the event object's
// source object: event.source.postMessage('foobar', '*')
// 3. The embedder receives the message and uses the event's source
// object to do one final reply: 'stop'
// 4. The guest receives the final 'stop' message.
// 5. The guest acks the 'stop' message with a 'stop_ack' message.
// 6. The embedder changes its title to 'main guest' when it sees the 'stop_ack'
// message.
IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, PostMessage) {
const char* kTesting = "testing123";
const char* kEmbedderURL = "files/browser_plugin_embedder.html";
const char* kGuestURL = "files/browser_plugin_post_message_guest.html";
StartBrowserPluginTest(kEmbedderURL, kGuestURL, false, "");
RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
test_embedder()->web_contents()->GetRenderViewHost());
{
const string16 expected_title = ASCIIToUTF16("main guest");
content::TitleWatcher title_watcher(test_embedder()->web_contents(),
expected_title);
// By the time we get here 'contentWindow' should be ready because the
// guest has begun sending pixels to the embedder. This happens after
// the browser process sends the guest_routing_id to the embedder via
// BrowserPluginMsg_GuestContentWindowReady and after the browser process
// issues a ViewMsg_New to create the swapped out guest in the embedder's
// render process.
ExecuteSyncJSFunction(rvh,
ASCIIToUTF16(StringPrintf("PostMessage('%s, false');", kTesting)));
// The title will be updated to "main guest" at the last stage of the
// process described above.
string16 actual_title = title_watcher.WaitAndGetTitle();
EXPECT_EQ(expected_title, actual_title);
}
}
// This is the same as BrowserPluginHostTest.PostMessage but also
// posts a message to an iframe.
// TODO(fsamuel): This test should replace the previous test once postMessage
// iframe targeting is fixed (see http://crbug.com/153701).
IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, DISABLED_PostMessageToIFrame) {
const char* kTesting = "testing123";
const char* kEmbedderURL = "files/browser_plugin_embedder.html";
const char* kGuestURL = "files/browser_plugin_post_message_guest.html";
StartBrowserPluginTest(kEmbedderURL, kGuestURL, false, "");
RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
test_embedder()->web_contents()->GetRenderViewHost());
{
const string16 expected_title = ASCIIToUTF16("main guest");
content::TitleWatcher title_watcher(test_embedder()->web_contents(),
expected_title);
ExecuteSyncJSFunction(rvh,
ASCIIToUTF16(StringPrintf("PostMessage('%s, false');", kTesting)));
// The title will be updated to "main guest" at the last stage of the
// process described above.
string16 actual_title = title_watcher.WaitAndGetTitle();
EXPECT_EQ(expected_title, actual_title);
}
{
content::TitleWatcher ready_watcher(test_embedder()->web_contents(),
ASCIIToUTF16("ready"));
RenderViewHostImpl* guest_rvh = static_cast<RenderViewHostImpl*>(
test_guest()->web_contents()->GetRenderViewHost());
GURL test_url = test_server()->GetURL(
"files/browser_plugin_post_message_guest.html");
ExecuteSyncJSFunction(guest_rvh,
ASCIIToUTF16(StringPrintf("CreateChildFrame('%s');",
test_url.spec().c_str())));
string16 actual_title = ready_watcher.WaitAndGetTitle();
EXPECT_EQ(ASCIIToUTF16("ready"), actual_title);
content::TitleWatcher iframe_watcher(test_embedder()->web_contents(),
ASCIIToUTF16("iframe"));
ExecuteSyncJSFunction(rvh,
ASCIIToUTF16(StringPrintf("PostMessage('%s', true);", kTesting)));
// The title will be updated to "iframe" at the last stage of the
// process described above.
actual_title = iframe_watcher.WaitAndGetTitle();
EXPECT_EQ(ASCIIToUTF16("iframe"), actual_title);
}
}
} // namespace content } // namespace content
...@@ -3005,14 +3005,8 @@ void WebContentsImpl::RouteMessageEvent( ...@@ -3005,14 +3005,8 @@ void WebContentsImpl::RouteMessageEvent(
RenderViewHost* rvh, RenderViewHost* rvh,
const ViewMsg_PostMessage_Params& params) { const ViewMsg_PostMessage_Params& params) {
// Only deliver the message to the active RenderViewHost if the request // Only deliver the message to the active RenderViewHost if the request
// came from a RenderViewHost in the same BrowsingInstance or if this // came from a RenderViewHost in the same BrowsingInstance.
// WebContents is dedicated to a browser plugin guest. if (!rvh->GetSiteInstance()->IsRelatedSiteInstance(GetSiteInstance()))
// Note: This check means that an embedder could theoretically receive a
// postMessage from anyone (not just its own guests). However, this is
// probably not a risk for apps since other pages won't have references
// to App windows.
if (!rvh->GetSiteInstance()->IsRelatedSiteInstance(GetSiteInstance()) &&
!GetBrowserPluginGuest() && !GetBrowserPluginEmbedder())
return; return;
ViewMsg_PostMessage_Params new_params(params); ViewMsg_PostMessage_Params new_params(params);
...@@ -3037,16 +3031,8 @@ void WebContentsImpl::RouteMessageEvent( ...@@ -3037,16 +3031,8 @@ void WebContentsImpl::RouteMessageEvent(
} }
if (source_contents) { if (source_contents) {
if (GetBrowserPluginGuest()) { new_params.source_routing_id =
// We create a swapped out RenderView for the embedder in the guest's source_contents->CreateOpenerRenderViews(GetSiteInstance());
// render process but we intentionally do not expose the embedder's
// opener chain to it.
new_params.source_routing_id =
source_contents->CreateSwappedOutRenderView(GetSiteInstance());
} else {
new_params.source_routing_id =
source_contents->CreateOpenerRenderViews(GetSiteInstance());
}
} else { } else {
// We couldn't find it, so don't pass a source frame. // We couldn't find it, so don't pass a source frame.
new_params.source_routing_id = MSG_ROUTING_NONE; new_params.source_routing_id = MSG_ROUTING_NONE;
...@@ -3149,11 +3135,6 @@ WebPreferences WebContentsImpl::GetWebkitPrefs() { ...@@ -3149,11 +3135,6 @@ WebPreferences WebContentsImpl::GetWebkitPrefs() {
return GetWebkitPrefs(GetRenderViewHost(), url); return GetWebkitPrefs(GetRenderViewHost(), url);
} }
int WebContentsImpl::CreateSwappedOutRenderView(
content::SiteInstance* instance) {
return render_manager_.CreateRenderView(instance, MSG_ROUTING_NONE, true);
}
void WebContentsImpl::OnUserGesture() { void WebContentsImpl::OnUserGesture() {
// Notify observers. // Notify observers.
FOR_EACH_OBSERVER(WebContentsObserver, observers_, DidGetUserGesture()); FOR_EACH_OBSERVER(WebContentsObserver, observers_, DidGetUserGesture());
......
...@@ -103,12 +103,6 @@ class CONTENT_EXPORT WebContentsImpl ...@@ -103,12 +103,6 @@ class CONTENT_EXPORT WebContentsImpl
static webkit_glue::WebPreferences GetWebkitPrefs( static webkit_glue::WebPreferences GetWebkitPrefs(
content::RenderViewHost* rvh, const GURL& url); content::RenderViewHost* rvh, const GURL& url);
// Creates a swapped out RenderView. This is used by the browser plugin to
// create a swapped out RenderView in the embedder render process for the
// guest, to expose the guest's window object to the embedder.
// This returns the routing ID of the newly created swapped out RenderView.
int CreateSwappedOutRenderView(content::SiteInstance* instance);
// Complex initialization here. Specifically needed to avoid having // Complex initialization here. Specifically needed to avoid having
// members call back into our virtual functions in the constructor. // members call back into our virtual functions in the constructor.
virtual void Init(content::BrowserContext* browser_context, virtual void Init(content::BrowserContext* browser_context,
......
...@@ -149,12 +149,6 @@ IPC_SYNC_MESSAGE_ROUTED2_0(BrowserPluginHostMsg_ResizeGuest, ...@@ -149,12 +149,6 @@ IPC_SYNC_MESSAGE_ROUTED2_0(BrowserPluginHostMsg_ResizeGuest,
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// These messages are from the browser process to the embedder. // These messages are from the browser process to the embedder.
// Once the swapped out guest RenderView has been created in the embedder render
// process, the browser process informs the embedder of its routing ID.
IPC_MESSAGE_CONTROL2(BrowserPluginMsg_GuestContentWindowReady,
int /* instance_id */,
int /* source_routing_id */)
// When the guest begins to load a page, the browser process informs the // When the guest begins to load a page, the browser process informs the
// embedder through the BrowserPluginMsg_LoadStart message. // embedder through the BrowserPluginMsg_LoadStart message.
IPC_MESSAGE_CONTROL3(BrowserPluginMsg_LoadStart, IPC_MESSAGE_CONTROL3(BrowserPluginMsg_LoadStart,
......
...@@ -72,7 +72,6 @@ BrowserPlugin::BrowserPlugin( ...@@ -72,7 +72,6 @@ BrowserPlugin::BrowserPlugin(
navigate_src_sent_(false), navigate_src_sent_(false),
process_id_(-1), process_id_(-1),
persist_storage_(false), persist_storage_(false),
content_window_routing_id_(MSG_ROUTING_NONE),
visible_(true), visible_(true),
current_nav_entry_index_(0), current_nav_entry_index_(0),
nav_entry_count_(0) { nav_entry_count_(0) {
...@@ -135,17 +134,6 @@ void BrowserPlugin::SetSrcAttribute(const std::string& src) { ...@@ -135,17 +134,6 @@ void BrowserPlugin::SetSrcAttribute(const std::string& src) {
src_ = src; src_ = src;
} }
NPObject* BrowserPlugin::GetContentWindow() const {
if (content_window_routing_id_ == MSG_ROUTING_NONE)
return NULL;
RenderViewImpl* guest_render_view = static_cast<RenderViewImpl*>(
ChildThread::current()->ResolveRoute(content_window_routing_id_));
if (!guest_render_view)
return NULL;
WebKit::WebFrame* guest_frame = guest_render_view->GetWebView()->mainFrame();
return guest_frame->windowObject();
}
std::string BrowserPlugin::GetPartitionAttribute() const { std::string BrowserPlugin::GetPartitionAttribute() const {
std::string value; std::string value;
if (persist_storage_) if (persist_storage_)
...@@ -498,11 +486,6 @@ void BrowserPlugin::AdvanceFocus(bool reverse) { ...@@ -498,11 +486,6 @@ void BrowserPlugin::AdvanceFocus(bool reverse) {
render_view_->GetWebView()->advanceFocus(reverse); render_view_->GetWebView()->advanceFocus(reverse);
} }
void BrowserPlugin::GuestContentWindowReady(int content_window_routing_id) {
DCHECK(content_window_routing_id != MSG_ROUTING_NONE);
content_window_routing_id_ = content_window_routing_id;
}
void BrowserPlugin::SetAcceptTouchEvents(bool accept) { void BrowserPlugin::SetAcceptTouchEvents(bool accept) {
if (container()) if (container())
container()->setIsAcceptingTouchEvents(accept); container()->setIsAcceptingTouchEvents(accept);
......
...@@ -38,8 +38,6 @@ class CONTENT_EXPORT BrowserPlugin : ...@@ -38,8 +38,6 @@ class CONTENT_EXPORT BrowserPlugin :
// Set the src attribute value of the BrowserPlugin instance and reset // Set the src attribute value of the BrowserPlugin instance and reset
// the guest_crashed_ flag. // the guest_crashed_ flag.
void SetSrcAttribute(const std::string& src); void SetSrcAttribute(const std::string& src);
// Get the guest's DOMWindow proxy.
NPObject* GetContentWindow() const;
// Returns Chrome's process ID for the current guest. // Returns Chrome's process ID for the current guest.
int process_id() const { return process_id_; } int process_id() const { return process_id_; }
// The partition identifier string is stored as UTF-8. // The partition identifier string is stored as UTF-8.
...@@ -74,10 +72,6 @@ class CONTENT_EXPORT BrowserPlugin : ...@@ -74,10 +72,6 @@ class CONTENT_EXPORT BrowserPlugin :
// element. // element.
void AdvanceFocus(bool reverse); void AdvanceFocus(bool reverse);
// Inform the BrowserPlugin that the guest's contentWindow is ready,
// and provide it with a routing ID to grab it.
void GuestContentWindowReady(int content_window_routing_id);
// Informs the BrowserPlugin that the guest has started/stopped accepting // Informs the BrowserPlugin that the guest has started/stopped accepting
// touch events. // touch events.
void SetAcceptTouchEvents(bool accept); void SetAcceptTouchEvents(bool accept);
...@@ -208,7 +202,6 @@ class CONTENT_EXPORT BrowserPlugin : ...@@ -208,7 +202,6 @@ class CONTENT_EXPORT BrowserPlugin :
int process_id_; int process_id_;
std::string storage_partition_id_; std::string storage_partition_id_;
bool persist_storage_; bool persist_storage_;
int content_window_routing_id_;
// Tracks the visibility of the browser plugin regardless of the whole // Tracks the visibility of the browser plugin regardless of the whole
// embedder RenderView's visibility. // embedder RenderView's visibility.
bool visible_; bool visible_;
......
...@@ -41,7 +41,6 @@ const char kAddEventListener[] = "addEventListener"; ...@@ -41,7 +41,6 @@ const char kAddEventListener[] = "addEventListener";
const char kBackMethod[] = "back"; const char kBackMethod[] = "back";
const char kCanGoBack[] = "canGoBack"; const char kCanGoBack[] = "canGoBack";
const char kCanGoForward[] = "canGoForward"; const char kCanGoForward[] = "canGoForward";
const char kContentWindow[] = "contentWindow";
const char kForwardMethod[] = "forward"; const char kForwardMethod[] = "forward";
const char kGetProcessId[] = "getProcessId"; const char kGetProcessId[] = "getProcessId";
const char kGoMethod[] = "go"; const char kGoMethod[] = "go";
...@@ -57,10 +56,6 @@ BrowserPluginBindings* GetBindings(NPObject* object) { ...@@ -57,10 +56,6 @@ BrowserPluginBindings* GetBindings(NPObject* object) {
message_channel; message_channel;
} }
bool IdentifierIsContentWindow(NPIdentifier identifier) {
return WebBindings::getStringIdentifier(kContentWindow) == identifier;
}
bool IdentifierIsPartitionAttribute(NPIdentifier identifier) { bool IdentifierIsPartitionAttribute(NPIdentifier identifier) {
return WebBindings::getStringIdentifier(kPartitionAttribute) == identifier; return WebBindings::getStringIdentifier(kPartitionAttribute) == identifier;
} }
...@@ -146,7 +141,6 @@ bool BrowserPluginBindingsInvokeDefault(NPObject* np_obj, ...@@ -146,7 +141,6 @@ bool BrowserPluginBindingsInvokeDefault(NPObject* np_obj,
bool BrowserPluginBindingsHasProperty(NPObject* np_obj, NPIdentifier name) { bool BrowserPluginBindingsHasProperty(NPObject* np_obj, NPIdentifier name) {
return IdentifierIsSrcAttribute(name) || return IdentifierIsSrcAttribute(name) ||
IdentifierIsContentWindow(name) ||
IdentifierIsPartitionAttribute(name); IdentifierIsPartitionAttribute(name);
} }
...@@ -169,15 +163,6 @@ bool BrowserPluginBindingsGetProperty(NPObject* np_obj, NPIdentifier name, ...@@ -169,15 +163,6 @@ bool BrowserPluginBindingsGetProperty(NPObject* np_obj, NPIdentifier name,
return StringToNPVariant(src, result); return StringToNPVariant(src, result);
} }
if (IdentifierIsContentWindow(name)) {
NPObject* obj = bindings->instance()->GetContentWindow();
if (obj) {
result->type = NPVariantType_Object;
result->value.objectValue = WebBindings::retainObject(obj);
}
return true;
}
if (IdentifierIsPartitionAttribute(name)) { if (IdentifierIsPartitionAttribute(name)) {
std::string partition_id = bindings->instance()->GetPartitionAttribute(); std::string partition_id = bindings->instance()->GetPartitionAttribute();
return StringToNPVariant(partition_id, result); return StringToNPVariant(partition_id, result);
......
...@@ -39,8 +39,6 @@ bool BrowserPluginManagerImpl::OnControlMessageReceived( ...@@ -39,8 +39,6 @@ bool BrowserPluginManagerImpl::OnControlMessageReceived(
IPC_MESSAGE_HANDLER(BrowserPluginMsg_GuestCrashed, OnGuestCrashed) IPC_MESSAGE_HANDLER(BrowserPluginMsg_GuestCrashed, OnGuestCrashed)
IPC_MESSAGE_HANDLER(BrowserPluginMsg_DidNavigate, OnDidNavigate) IPC_MESSAGE_HANDLER(BrowserPluginMsg_DidNavigate, OnDidNavigate)
IPC_MESSAGE_HANDLER(BrowserPluginMsg_AdvanceFocus, OnAdvanceFocus) IPC_MESSAGE_HANDLER(BrowserPluginMsg_AdvanceFocus, OnAdvanceFocus)
IPC_MESSAGE_HANDLER(BrowserPluginMsg_GuestContentWindowReady,
OnGuestContentWindowReady)
IPC_MESSAGE_HANDLER(BrowserPluginMsg_ShouldAcceptTouchEvents, IPC_MESSAGE_HANDLER(BrowserPluginMsg_ShouldAcceptTouchEvents,
OnShouldAcceptTouchEvents) OnShouldAcceptTouchEvents)
IPC_MESSAGE_HANDLER(BrowserPluginMsg_LoadStart, OnLoadStart) IPC_MESSAGE_HANDLER(BrowserPluginMsg_LoadStart, OnLoadStart)
...@@ -80,13 +78,6 @@ void BrowserPluginManagerImpl::OnAdvanceFocus(int instance_id, bool reverse) { ...@@ -80,13 +78,6 @@ void BrowserPluginManagerImpl::OnAdvanceFocus(int instance_id, bool reverse) {
plugin->AdvanceFocus(reverse); plugin->AdvanceFocus(reverse);
} }
void BrowserPluginManagerImpl::OnGuestContentWindowReady(int instance_id,
int guest_routing_id) {
BrowserPlugin* plugin = GetBrowserPlugin(instance_id);
if (plugin)
plugin->GuestContentWindowReady(guest_routing_id);
}
void BrowserPluginManagerImpl::OnShouldAcceptTouchEvents(int instance_id, void BrowserPluginManagerImpl::OnShouldAcceptTouchEvents(int instance_id,
bool accept) { bool accept) {
BrowserPlugin* plugin = GetBrowserPlugin(instance_id); BrowserPlugin* plugin = GetBrowserPlugin(instance_id);
......
...@@ -37,7 +37,6 @@ class BrowserPluginManagerImpl : public BrowserPluginManager { ...@@ -37,7 +37,6 @@ class BrowserPluginManagerImpl : public BrowserPluginManager {
void OnDidNavigate(int instance_id, void OnDidNavigate(int instance_id,
const BrowserPluginMsg_DidNavigate_Params& params); const BrowserPluginMsg_DidNavigate_Params& params);
void OnAdvanceFocus(int instance_id, bool reverse); void OnAdvanceFocus(int instance_id, bool reverse);
void OnGuestContentWindowReady(int instance_id, int guest_routing_id);
void OnShouldAcceptTouchEvents(int instance_id, bool accept); void OnShouldAcceptTouchEvents(int instance_id, bool accept);
void OnLoadStart(int instance_id, void OnLoadStart(int instance_id,
const GURL& url, const GURL& url,
......
...@@ -23,16 +23,6 @@ function SetSize(w, h) { ...@@ -23,16 +23,6 @@ function SetSize(w, h) {
plugin.width = w; plugin.width = w;
plugin.height = h; plugin.height = h;
} }
function PostMessage(data, shouldTargetIframe) {
plugin = document.getElementById('plugin');
// TODO(fsamuel): contentWindow can be accessed directly once
// http://wkbug.com/85679 lands.
if (shouldTargetIframe) {
plugin.contentWindow.frames[0].postMessage('testing123', '*');
} else {
plugin.contentWindow.frames.postMessage('testing123', '*');
}
}
function Back() { function Back() {
var plugin = document.getElementById('plugin'); var plugin = document.getElementById('plugin');
plugin.back(); plugin.back();
...@@ -65,28 +55,10 @@ document.title = 'embedder'; ...@@ -65,28 +55,10 @@ document.title = 'embedder';
width="640" width="640"
height="480" height="480"
border="0px"></object> border="0px"></object>
<script type="text/javascript">
var msg; <script>
function receiveMessage(event) {
msg = event.data;
if (msg == 'ready') {
document.title = 'ready';
return;
}
if (msg.indexOf('stop_ack') == -1) {
event.source.postMessage('stop', '*');
} else {
var name = msg.replace("stop_ack", "").trim();
if (name !== '') {
window.document.title = name;
} else {
window.document.title = 'main guest';
}
}
}
var plugin = document.getElementById('plugin'); var plugin = document.getElementById('plugin');
plugin.addEventListener('loadStart', loadStart); plugin.addEventListener('loadStart', loadStart);
plugin.addEventListener('loadAbort', loadAbort); plugin.addEventListener('loadAbort', loadAbort);
plugin.addEventListener('loadRedirect', loadRedirect); plugin.addEventListener('loadRedirect', loadRedirect);
window.addEventListener('message', receiveMessage, false);
</script> </script>
<script>
var embedder;
function receiveMessage(event) {
embedder = event.source;
if (event.data !== 'stop') {
event.source.postMessage('foobar', '*');
} else {
if (event.data !== '') {
event.source.postMessage('stop_ack ' + window.name, '*');
}
}
}
window.addEventListener('message', receiveMessage, false);
function CreateChildFrame(src) {
var ifrm = document.createElement("IFRAME");
ifrm.style.width = "640px";
ifrm.style.height = "480px";
ifrm.src = src;
ifrm.name = 'iframe';
document.body.appendChild(ifrm);
embedder.postMessage('ready', '*');
}
</script>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment