diff --git a/lib/puppeteer/browser.rb b/lib/puppeteer/browser.rb index beede78..3596a59 100644 --- a/lib/puppeteer/browser.rb +++ b/lib/puppeteer/browser.rb @@ -13,7 +13,14 @@ class Puppeteer::Browser # @param {?Puppeteer.Viewport} defaultViewport # @param process [Puppeteer::BrowserRunner::BrowserProcess|NilClass] # @param {function()=} closeCallback - def self.create(connection:, context_ids:, ignore_https_errors:, default_viewport:, process:, close_callback:) + def self.create(connection:, + context_ids:, + ignore_https_errors:, + default_viewport:, + process:, + close_callback:, + target_filter_callback:, + is_page_target_callback:) browser = Puppeteer::Browser.new( connection: connection, context_ids: context_ids, @@ -21,6 +28,8 @@ def self.create(connection:, context_ids:, ignore_https_errors:, default_viewpor default_viewport: default_viewport, process: process, close_callback: close_callback, + target_filter_callback: target_filter_callback, + is_page_target_callback: is_page_target_callback, ) connection.send_message('Target.setDiscoverTargets', discover: true) browser @@ -32,12 +41,21 @@ def self.create(connection:, context_ids:, ignore_https_errors:, default_viewpor # @param {?Puppeteer.Viewport} defaultViewport # @param {?Puppeteer.ChildProcess} process # @param {(function():Promise)=} closeCallback - def initialize(connection:, context_ids:, ignore_https_errors:, default_viewport:, process:, close_callback:) + def initialize(connection:, + context_ids:, + ignore_https_errors:, + default_viewport:, + process:, + close_callback:, + target_filter_callback:, + is_page_target_callback:) @ignore_https_errors = ignore_https_errors @default_viewport = default_viewport @process = process @connection = connection @close_callback = close_callback + @target_filter_callback = target_filter_callback || method(:default_target_filter_callback) + @is_page_target_callback = is_page_target_callback || method(:default_is_page_target_callback) @default_context = Puppeteer::BrowserContext.new(@connection, self, nil) @contexts = {} @@ -54,6 +72,14 @@ def initialize(connection:, context_ids:, ignore_https_errors:, default_viewport @connection.on_event('Target.targetInfoChanged', &method(:handle_target_info_changed)) end + private def default_target_filter_callback(target_info) + true + end + + private def default_is_page_target_callback(target_info) + ['page', 'background_page', 'webview'].include?(target_info.type) + end + # @param event_name [Symbol] either of :disconnected, :targetcreated, :targetchanged, :targetdestroyed def on(event_name, &block) unless BrowserEmittedEvents.values.include?(event_name.to_s) @@ -119,12 +145,16 @@ def handle_target_created(event) if @targets[target_info.target_id] raise TargetAlreadyExistError.new end + + return unless @target_filter_callback.call(target_info) + target = Puppeteer::Target.new( target_info: target_info, browser_context: context, session_factory: -> { @connection.create_session(target_info) }, ignore_https_errors: @ignore_https_errors, default_viewport: @default_viewport, + is_page_target_callback: @is_page_target_callback, ) @targets[target_info.target_id] = target if_present(@wait_for_creating_targets.delete(target_info.target_id)) do |promise| diff --git a/lib/puppeteer/launcher/browser_options.rb b/lib/puppeteer/launcher/browser_options.rb index 184e3b3..141b621 100644 --- a/lib/puppeteer/launcher/browser_options.rb +++ b/lib/puppeteer/launcher/browser_options.rb @@ -31,9 +31,20 @@ def initialize(options) # `default_viewport: nil` must be respected here. @default_viewport = options.key?(:default_viewport) ? options[:default_viewport] : Puppeteer::Viewport.new(width: 800, height: 600) @slow_mo = options[:slow_mo] || 0 + + # only for Puppeteer.connect + @target_filter = options[:target_filter] + if @target_filter && !@target_filter.respond_to?(:call) + raise ArgumentError.new('target_filter must be a Proc (target_info => true/false)') + end + + @is_page_target = options[:is_page_target] + if @is_page_target && !@is_page_target.respond_to?(:call) + raise ArgumentError.new('is_page_target must be a Proc (target_info => true/false)') + end end - attr_reader :default_viewport, :slow_mo + attr_reader :default_viewport, :slow_mo, :target_filter, :is_page_target def ignore_https_errors? @ignore_https_errors diff --git a/lib/puppeteer/launcher/chrome.rb b/lib/puppeteer/launcher/chrome.rb index aab5075..2e79856 100644 --- a/lib/puppeteer/launcher/chrome.rb +++ b/lib/puppeteer/launcher/chrome.rb @@ -87,6 +87,8 @@ def launch(options = {}) default_viewport: @browser_options.default_viewport, process: runner.proc, close_callback: -> { runner.close }, + target_filter_callback: nil, + is_page_target_callback: nil, ) rescue runner.kill @@ -205,6 +207,8 @@ def connect(options = {}) default_viewport: @browser_options.default_viewport, process: nil, close_callback: -> { connection.send_message('Browser.close') }, + target_filter_callback: @browser_options.target_filter, + is_page_target_callback: @browser_options.is_page_target, ) end diff --git a/lib/puppeteer/launcher/firefox.rb b/lib/puppeteer/launcher/firefox.rb index 8255705..8529f1c 100644 --- a/lib/puppeteer/launcher/firefox.rb +++ b/lib/puppeteer/launcher/firefox.rb @@ -85,6 +85,8 @@ def launch(options = {}) default_viewport: @browser_options.default_viewport, process: runner.proc, close_callback: -> { runner.close }, + target_filter_callback: nil, + is_page_target_callback: nil, ) rescue runner.kill @@ -132,6 +134,8 @@ def connect(options = {}) default_viewport: @browser_options.default_viewport, process: nil, close_callback: -> { connection.send_message('Browser.close') }, + target_filter_callback: nil, + is_page_target_callback: nil, ) end diff --git a/lib/puppeteer/target.rb b/lib/puppeteer/target.rb index 15919dd..898de79 100644 --- a/lib/puppeteer/target.rb +++ b/lib/puppeteer/target.rb @@ -18,14 +18,19 @@ def initialize(options) # @param {!function():!Promise} sessionFactory # @param {boolean} ignoreHTTPSErrors # @param {?Puppeteer.Viewport} defaultViewport - def initialize(target_info:, browser_context:, session_factory:, ignore_https_errors:, default_viewport:) + def initialize(target_info:, + browser_context:, + session_factory:, + ignore_https_errors:, + default_viewport:, + is_page_target_callback:) @target_info = target_info @browser_context = browser_context @target_id = target_info.target_id @session_factory = session_factory @ignore_https_errors = ignore_https_errors @default_viewport = default_viewport - + @is_page_target_callback = is_page_target_callback # /** @type {?Promise} */ # this._pagePromise = null; @@ -37,7 +42,7 @@ def initialize(target_info:, browser_context:, session_factory:, ignore_https_er end @is_closed_promise = resolvable_future - @is_initialized = @target_info.type != 'page' || !@target_info.url.empty? + @is_initialized = !@is_page_target_callback.call(@target_info) || !@target_info.url.empty? if @is_initialized @initialize_callback_promise.fulfill(true) @@ -83,7 +88,7 @@ def create_cdp_session end def page - if ['page', 'background_page', 'webview'].include?(@target_info.type) && @page.nil? + if @is_page_target_callback.call(@target_info) && @page.nil? client = @session_factory.call @page = Puppeteer::Page.create(client, self, @ignore_https_errors, @default_viewport) end @@ -145,7 +150,7 @@ def opener def handle_target_info_changed(target_info) @target_info = target_info - if !@is_initialized && (@target_info.type != 'page' || !@target_info.url.empty?) + if !@is_initialized && (!@is_page_target_callback.call(@target_info) || !@target_info.url.empty?) @is_initialized = true @initialize_callback_promise.fulfill(true) end