diff --git a/examples/oopif.js b/examples/oopif.js new file mode 100644 index 0000000000000..52e2047b31d37 --- /dev/null +++ b/examples/oopif.js @@ -0,0 +1,47 @@ +/** + * Copyright 2020 Google Inc. 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. + */ + +'use strict'; + +const puppeteer = require('puppeteer'); + +async function attachFrame(frameId, url) { + const frame = document.createElement('iframe'); + frame.src = url; + frame.id = frameId; + document.body.appendChild(frame); + await new Promise((x) => (frame.onload = x)); + return frame; +} + +(async () => { + // Launch browser in non-headless mode. + const browser = await puppeteer.launch({ headless: false }); + const page = await browser.newPage(); + + // Load a page from one origin: + await page.goto('http://example.org/'); + + // Inject iframe with the another origin. + await page.evaluateHandle(attachFrame, 'frame1', 'https://example.com/'); + + // At this point there should be a message in the output: + // puppeteer:frame The frame '...' moved to another session. Out-of-proccess + // iframes (OOPIF) are not supported by Puppeteer yet. + // https://github.com/puppeteer/puppeteer/issues/2548 + + await browser.close(); +})(); diff --git a/src/common/FrameManager.ts b/src/common/FrameManager.ts index 5507d9e5c7896..6d35dd6dc1ec6 100644 --- a/src/common/FrameManager.ts +++ b/src/common/FrameManager.ts @@ -14,6 +14,8 @@ * limitations under the License. */ +import { debug } from '../common/Debug.js'; + import { EventEmitter } from './EventEmitter.js'; import { assert } from './assert.js'; import { helper, debugError } from './helper.js'; @@ -111,6 +113,9 @@ export class FrameManager extends EventEmitter { this._client.on('Page.lifecycleEvent', (event) => this._onLifecycleEvent(event) ); + this._client.on('Target.attachedToTarget', async (event) => + this._onFrameMoved(event) + ); } async initialize(): Promise { @@ -213,6 +218,20 @@ export class FrameManager extends EventEmitter { return watcher.navigationResponse(); } + private async _onFrameMoved(event: Protocol.Target.AttachedToTargetEvent) { + if (event.targetInfo.type !== 'iframe') { + return; + } + + // TODO(sadym): Remove debug message once proper OOPIF support is + // implemented: https://github.com/puppeteer/puppeteer/issues/2548 + debug('puppeteer:frame')( + `The frame '${event.targetInfo.targetId}' moved to another session. ` + + `Out-of-process iframes (OOPIF) are not supported by Puppeteer yet. ` + + `https://github.com/puppeteer/puppeteer/issues/2548` + ); + } + _onLifecycleEvent(event: Protocol.Page.LifecycleEventEvent): void { const frame = this._frames.get(event.frameId); if (!frame) return;