Class: Puppeteer::JSHandle

Inherits:
Object
  • Object
show all
Includes:
IfPresent
Defined in:
lib/puppeteer/js_handle.rb

Direct Known Subclasses

ElementHandle

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from IfPresent

#if_present

Constructor Details

#initialize(context:, client:, remote_object:) ⇒ JSHandle

Returns a new instance of JSHandle.

Parameters:



31
32
33
34
35
36
37
# File 'lib/puppeteer/js_handle.rb', line 31

def initialize(context:, client:, remote_object:)
  @context = context
  @client = client
  @remote_object = remote_object
  @disposed = false
  @moved = false
end

Instance Attribute Details

#contextObject (readonly)

Returns the value of attribute context.



39
40
41
# File 'lib/puppeteer/js_handle.rb', line 39

def context
  @context
end

#remote_objectObject (readonly)

Returns the value of attribute remote_object.



39
40
41
# File 'lib/puppeteer/js_handle.rb', line 39

def remote_object
  @remote_object
end

Class Method Details

.create(context:, remote_object:) ⇒ Object

Parameters:



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/puppeteer/js_handle.rb', line 11

def self.create(context:, remote_object:)
  if remote_object.sub_type == 'node' && context.world
    Puppeteer::ElementHandle.new(
      context: context,
      client: context.client,
      remote_object: remote_object,
      frame: context.world.frame,
    )
  else
    Puppeteer::JSHandle.new(
      context: context,
      client: context.client,
      remote_object: remote_object,
    )
  end
end

Instance Method Details

#[](name) ⇒ Puppeteer::JSHandle

Parameters:

  • name (String)

Returns:



91
92
93
# File 'lib/puppeteer/js_handle.rb', line 91

def [](name)
  property(name)
end

#as_elementObject



153
154
155
# File 'lib/puppeteer/js_handle.rb', line 153

def as_element
  nil
end

#disposeObject



157
158
159
160
161
162
# File 'lib/puppeteer/js_handle.rb', line 157

def dispose
  return if @disposed

  @disposed = true
  @remote_object.release(@client)
end

#dispose_symbolObject



169
170
171
172
173
174
175
176
# File 'lib/puppeteer/js_handle.rb', line 169

def dispose_symbol
  if @moved
    @moved = false
    return
  end

  dispose
end

#disposed?Boolean

Returns:

  • (Boolean)


164
165
166
# File 'lib/puppeteer/js_handle.rb', line 164

def disposed?
  @disposed
end

#evaluate(page_function, *args) ⇒ Object

Parameters:

  • page_function (String)

Returns:

  • (Object)


56
57
58
# File 'lib/puppeteer/js_handle.rb', line 56

def evaluate(page_function, *args)
  execution_context.evaluate(page_function, self, *args)
end

#evaluate_handle(page_function, *args) ⇒ Puppeteer::JSHandle

Parameters:

  • page_function (String)
  • args (Array<*>)

Returns:



65
66
67
# File 'lib/puppeteer/js_handle.rb', line 65

def evaluate_handle(page_function, *args)
  execution_context.evaluate_handle(page_function, self, *args)
end

#execution_contextPuppeteer::ExecutionContext



50
51
52
# File 'lib/puppeteer/js_handle.rb', line 50

def execution_context
  @context
end

#inspectObject



41
42
43
44
45
46
47
# File 'lib/puppeteer/js_handle.rb', line 41

def inspect
  values = %i[context remote_object disposed].map do |sym|
    value = instance_variable_get(:"@#{sym}")
    "@#{sym}=#{value}"
  end
  "#<Puppeteer::JSHandle #{values.join(' ')}>"
end

#json_valueObject



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/puppeteer/js_handle.rb', line 108

def json_value
  # Node.js Puppeteer:
  #   if (!this.#remoteObject.objectId) {
  #     return valueFromRemoteObject(this.#remoteObject);
  #   }
  #   const value = await this.evaluate(object => object);
  #   if (value === undefined) {
  #     throw new Error('Could not serialize referenced object');
  #   }
  #   return value;
  if !@remote_object.object_id?
    return @remote_object.value
  end

  if @remote_object.sub_type == 'date'
    iso_value = evaluate('(object) => object.toISOString()')
    return Time.iso8601(iso_value) if iso_value
  end

  begin
    result = @client.send_message('Runtime.callFunctionOn',
      functionDeclaration: 'function() { return this; }',
      objectId: @remote_object.object_id_value,
      returnByValue: true,
      awaitPromise: true,
      userGesture: true,
    )
  rescue Puppeteer::Connection::ProtocolError => err
    if err.message.include?('Object reference chain is too long') ||
      err.message.include?("Object couldn't be returned by value")
      return nil
    end
    raise
  end
  if result['exceptionDetails']
    raise Puppeteer::ExecutionContext::EvaluationError.new("Evaluation failed: #{result['exceptionDetails']}")
  end

  remote_object = Puppeteer::RemoteObject.new(result['result'])
  if remote_object.type == 'undefined'
    raise Puppeteer::Error.new('Could not serialize referenced object')
  end
  remote_object.value
end

#moveObject



181
182
183
184
# File 'lib/puppeteer/js_handle.rb', line 181

def move
  @moved = true
  self
end

#propertiesHash<String, JSHandle>

getProperties in JavaScript.

Returns:



97
98
99
100
101
102
103
104
105
106
# File 'lib/puppeteer/js_handle.rb', line 97

def properties
  response = @remote_object.properties(@client)
  response['result'].each_with_object({}) do |prop, h|
    next unless prop['enumerable'] && prop['value']
    h[prop['name']] = Puppeteer::JSHandle.create(
      context: @context,
      remote_object: Puppeteer::RemoteObject.new(prop['value']),
    )
  end
end

#property(name) ⇒ Puppeteer::JSHandle

getProperty(propertyName) in JavaScript

Parameters:

  • name (String)

Returns:



74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/puppeteer/js_handle.rb', line 74

def property(name)
  js = <<~JAVASCRIPT
  (object, propertyName) => {
    const result = {__proto__: null};
    result[propertyName] = object[propertyName];
    return result;
  }
  JAVASCRIPT
  object_handle = evaluate_handle(js, name)
  properties = object_handle.properties
  result = properties[name]
  object_handle.dispose
  result
end

#to_sObject



186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/puppeteer/js_handle.rb', line 186

def to_s
  # original logic was:
  #   if (this._remoteObject.objectId) {
  #     const type =  this._remoteObject.subtype || this._remoteObject.type;
  #     return 'JSHandle@' + type;
  #   }
  #   return 'JSHandle:' + helper.valueFromRemoteObject(this._remoteObject);
  #
  # However it would be better that RemoteObject is responsible for
  # the logic `if (this._remoteObject.objectId) { ... }`.
  if_present(@remote_object.type_str) { |type_str| "JSHandle@#{type_str}" } || "JSHandle:#{stringify_remote_value}"
end