Target.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /**
  2. * Copyright 2019 Google Inc. All rights reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. const {Events} = require('./Events');
  17. const {Page} = require('./Page');
  18. const {Worker} = require('./Worker');
  19. class Target {
  20. /**
  21. * @param {!Protocol.Target.TargetInfo} targetInfo
  22. * @param {!Puppeteer.BrowserContext} browserContext
  23. * @param {!function():!Promise<!Puppeteer.CDPSession>} sessionFactory
  24. * @param {boolean} ignoreHTTPSErrors
  25. * @param {?Puppeteer.Viewport} defaultViewport
  26. * @param {!Puppeteer.TaskQueue} screenshotTaskQueue
  27. */
  28. constructor(targetInfo, browserContext, sessionFactory, ignoreHTTPSErrors, defaultViewport, screenshotTaskQueue) {
  29. this._targetInfo = targetInfo;
  30. this._browserContext = browserContext;
  31. this._targetId = targetInfo.targetId;
  32. this._sessionFactory = sessionFactory;
  33. this._ignoreHTTPSErrors = ignoreHTTPSErrors;
  34. this._defaultViewport = defaultViewport;
  35. this._screenshotTaskQueue = screenshotTaskQueue;
  36. /** @type {?Promise<!Puppeteer.Page>} */
  37. this._pagePromise = null;
  38. /** @type {?Promise<!Worker>} */
  39. this._workerPromise = null;
  40. this._initializedPromise = new Promise(fulfill => this._initializedCallback = fulfill).then(async success => {
  41. if (!success)
  42. return false;
  43. const opener = this.opener();
  44. if (!opener || !opener._pagePromise || this.type() !== 'page')
  45. return true;
  46. const openerPage = await opener._pagePromise;
  47. if (!openerPage.listenerCount(Events.Page.Popup))
  48. return true;
  49. const popupPage = await this.page();
  50. openerPage.emit(Events.Page.Popup, popupPage);
  51. return true;
  52. });
  53. this._isClosedPromise = new Promise(fulfill => this._closedCallback = fulfill);
  54. this._isInitialized = this._targetInfo.type !== 'page' || this._targetInfo.url !== '';
  55. if (this._isInitialized)
  56. this._initializedCallback(true);
  57. }
  58. /**
  59. * @return {!Promise<!Puppeteer.CDPSession>}
  60. */
  61. createCDPSession() {
  62. return this._sessionFactory();
  63. }
  64. /**
  65. * @return {!Promise<?Page>}
  66. */
  67. async page() {
  68. if ((this._targetInfo.type === 'page' || this._targetInfo.type === 'background_page') && !this._pagePromise) {
  69. this._pagePromise = this._sessionFactory()
  70. .then(client => Page.create(client, this, this._ignoreHTTPSErrors, this._defaultViewport, this._screenshotTaskQueue));
  71. }
  72. return this._pagePromise;
  73. }
  74. /**
  75. * @return {!Promise<?Worker>}
  76. */
  77. async worker() {
  78. if (this._targetInfo.type !== 'service_worker' && this._targetInfo.type !== 'shared_worker')
  79. return null;
  80. if (!this._workerPromise) {
  81. // TODO(einbinder): Make workers send their console logs.
  82. this._workerPromise = this._sessionFactory()
  83. .then(client => new Worker(client, this._targetInfo.url, () => {} /* consoleAPICalled */, () => {} /* exceptionThrown */));
  84. }
  85. return this._workerPromise;
  86. }
  87. /**
  88. * @return {string}
  89. */
  90. url() {
  91. return this._targetInfo.url;
  92. }
  93. /**
  94. * @return {"page"|"background_page"|"service_worker"|"shared_worker"|"other"|"browser"}
  95. */
  96. type() {
  97. const type = this._targetInfo.type;
  98. if (type === 'page' || type === 'background_page' || type === 'service_worker' || type === 'shared_worker' || type === 'browser')
  99. return type;
  100. return 'other';
  101. }
  102. /**
  103. * @return {!Puppeteer.Browser}
  104. */
  105. browser() {
  106. return this._browserContext.browser();
  107. }
  108. /**
  109. * @return {!Puppeteer.BrowserContext}
  110. */
  111. browserContext() {
  112. return this._browserContext;
  113. }
  114. /**
  115. * @return {?Puppeteer.Target}
  116. */
  117. opener() {
  118. const { openerId } = this._targetInfo;
  119. if (!openerId)
  120. return null;
  121. return this.browser()._targets.get(openerId);
  122. }
  123. /**
  124. * @param {!Protocol.Target.TargetInfo} targetInfo
  125. */
  126. _targetInfoChanged(targetInfo) {
  127. this._targetInfo = targetInfo;
  128. if (!this._isInitialized && (this._targetInfo.type !== 'page' || this._targetInfo.url !== '')) {
  129. this._isInitialized = true;
  130. this._initializedCallback(true);
  131. return;
  132. }
  133. }
  134. }
  135. module.exports = {Target};