Class: Sol::Js

Inherits:
Object
  • Object
show all
Defined in:
lib/jx/js.rb

Overview

Class to communicate with the embedded browser (jxBrowser), by sending javascript messages

Defined Under Namespace

Classes: RBListener

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(browser) ⇒ Js



Parameters:

  • browser (Browser)

    the jxBrowser instance



72
73
74
75
76
77
78
79
# File 'lib/jx/js.rb', line 72

def initialize(browser)

  @browser = browser

  # listen for console events
  @browser.addConsoleListener(RBListener.new)
  
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(symbol, *args, &blk) ⇒ Object





291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
# File 'lib/jx/js.rb', line 291

def method_missing(symbol, *args, &blk)

  # if block is given, then create a javascript function that will call the block
  # passing the args
  args.push(blk2func(blk)) if (blk)
    
  name = symbol.id2name
  name.gsub!(/__/,"$")

  if name =~ /(.*)=$/
    ret = assign_window($1, process_args(args)[0])
  else
    if (((ret = pull(name)).is_a? Sol::JSObject) && ret.function?)
      if (args.size > 0)
        if (args.size == 1 && args[0].nil?)
          ret = ret.send
        else
          ret = ret.send(*args)
        end
      end
    end
  end
  ret
end

Instance Attribute Details

#browserObject (readonly)

function is an instance of a class



64
65
66
# File 'lib/jx/js.rb', line 64

def browser
  @browser
end

#identityObject

Returns the value of attribute identity.



65
66
67
# File 'lib/jx/js.rb', line 65

def identity
  @identity
end

#instanceOfObject

Returns the value of attribute instanceOf.



66
67
68
# File 'lib/jx/js.rb', line 66

def instanceOf
  @instanceOf
end

Instance Method Details

#blk2func(blk) ⇒ Object


TODO: Something is wrong here!!!! Need to set B.block, but if we pass the B.block variable to make_callback, the application crashes.




282
283
284
285
# File 'lib/jx/js.rb', line 282

def blk2func(blk)
  B.block = Callback.build(blk)
  B.rr.make_callback(nil)
end

#documentObject



Returns:

  • the browser ‘document’ object



101
102
103
# File 'lib/jx/js.rb', line 101

def document
  @browser.executeJavaScriptAndReturnValue("document")
end

#dup(data) ⇒ Object


Duplicates the given Ruby data into a javascript object in the Browser


Parameters:

  • name (Symbol, String)

    the name of the javascript variable into which to dup

  • data (Object)

    a Ruby object



261
262
263
# File 'lib/jx/js.rb', line 261

def dup(data)
  push(JSONString.new(data.to_json))
end

#eval(scrpt) ⇒ JSObject || RBObject


Evaluates the javascript script synchronously and then proxies the result in a Ruby JSObject or RBObject


Parameters:

  • scrpt (String)

    a javascript script to be executed synchronously

Returns:



210
211
212
# File 'lib/jx/js.rb', line 210

def eval(scrpt)
  proxy(@browser.executeJavaScriptAndReturnValue(scrpt))
end

#eval_obj(jsobject, prop) ⇒ Object





230
231
232
233
234
235
# File 'lib/jx/js.rb', line 230

def eval_obj(jsobject, prop)
  B.obj = push(jsobject)
  jeval(<<-EOT)
     obj.#{prop}
  EOT
end

#function(definition) ⇒ JSFunction


Creates a new function in javascript and returns it as a jsfunction given, then a temporary name is used just to be able to create the function.


Parameters:

  • symbol (Symbol)

    the name of the function in javascript namespace. If not

Returns:



272
273
274
275
# File 'lib/jx/js.rb', line 272

def function(definition)
  eval("var __tmpvar__ = function #{definition}")
  eval("__tmpvar__")
end

#instanceof(object, type) ⇒ Object


Applies javascript method ‘instanceOf’ defined in ruby_rich.rb to the given object and type. ‘instanceOf’ is a JSFunction.


Parameters:

  • object (JSObject)
  • type (String)

    the type to check



128
129
130
# File 'lib/jx/js.rb', line 128

def instanceof(object, type)
  @instanceOf[object, type]
end

#invoke(scope, function, *args) ⇒ Object


Invokes the function form result of the function invokation TODO: needs implementation/tests to call functions in the scope of a given object. method_missing in jsobject does create fix the scope, but needs to check if this also needs to be done in this (invoke) method.


Parameters:

  • scope (Java::JSObject)

    the object that holds the function, i.e., it´s scope

  • function (java JSFunction)

    the function to be invoked, already in its java

  • *args (Args)

    a list of java arguments to pass to the function



250
251
252
253
# File 'lib/jx/js.rb', line 250

def invoke(scope, function, *args)
  args = nil if (args.size == 1 && args[0].nil?)
  proxy(function.invoke(scope, *(args)))
end

#jeval(scrpt) ⇒ java.JSObject


Evaluates the javascript script synchronously, but does not pack in JSObject. This method should not be normally called by normal users. This should be used only in some special cases, usually developers of this application.


Parameters:

  • scrpt (String)

    a javascript script to be executed synchronously

Returns:



222
223
224
# File 'lib/jx/js.rb', line 222

def jeval(scrpt)
  @browser.executeJavaScriptAndReturnValue(scrpt)
end

#jscontextObject



Returns:

  • the browser JSContext



109
110
111
# File 'lib/jx/js.rb', line 109

def jscontext
  @browser.getJSContext()
end

#load(filename) ⇒ Object


Loads a javascript file relative to the callers directory




394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
# File 'lib/jx/js.rb', line 394

def load(filename)

  file = caller.first.split(/:\d/,2).first
  dir = File.dirname(File.expand_path(file))
  
  scrpt = "" 
  begin
    file = File.new("#{dir}/#{filename}", "r") 
    while (line = file.gets)
      scrpt << line
    end
    file.close
  rescue => err
    puts "Exception: #{err}"
    err
  end

  @browser.executeJavaScriptAndReturnValue(scrpt)
  
end

#pack(obj) ⇒ java.JSObject


Pack a ruby object for use inside a javascript script. A packed ruby object is identical to a proxy object exect by the return value that is a java.JSValue and not a Sol::xxx object.


Parameters:

  • obj (Object)

    The ruby object to be packed

Returns:

  • (java.JSObject)

    A java.JSObject that that implements the ‘run’ interface



186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
# File 'lib/jx/js.rb', line 186

def pack(obj)

  case obj
  when TrueClass, FalseClass, Numeric, String, NilClass,
       Java::ComTeamdevJxbrowserChromium::JSValue
    obj
  when Proc
    blk2func(obj).jsvalue
  when Object
    B.obj = Callback.build(obj)
    jeval("new RubyProxy(obj)")
  else
    raise "No method to pack the given object: #{obj}"
  end
  
end

Calls Chrome printing popup interface




117
118
119
# File 'lib/jx/js.rb', line 117

def print_page
  @browser.print
end

#process_args(args) ⇒ Object


Converts Ruby arguments into a javascript objects to run in a javascript script. A Sol::JSObject and Sol::RBObject are similar in that they pack a ‘native’ object (either java.JSObject or ruby Object). These objects show up in a ruby script and when injected in javascript their jsvalue is made available. An IRBObject (Internal Ruby Object) appears when a Ruby Callback is executed and exists for the case that this object transitions between javascript and ends up in a Ruby script. arguments TODO: Can an IRBObject end up in a javascript script? If so, will it work fine? TODO: Make tests that allow Proc/block to be injected into javascript


Parameters:

  • args (Array)

    Ruby array with ruby arguments



331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
# File 'lib/jx/js.rb', line 331

def process_args(args)

  args.map do |arg|
    case arg
    when Sol::IRBObject # Sol::Callback
      arg
    when Sol::JSObject, Sol::RBObject
      arg.jsvalue
    when Hash, Array
      pack(arg)
    when Symbol
      raise "Ruby Symbols are not supported in jxBrowser.  Converting ':#{arg}' not supported."
    when Proc
      p "i´m a proc... not implemented yet"
      arg
    else
      arg
    end
  end
  
end

#process_args2(args) ⇒ Object


Converts Ruby arguments into a javascript objects to run in a javascript script. A Sol::JSObject and Sol::RBObject are similar in that they pack a ‘native’ object (either java.JSObject or ruby Object). These objects show up in a ruby script and when injected in javascript their jsvalue is made available. An IRBObject (Internal Ruby Object) appears when a Ruby Callback is executed and exists for the case that this object transitions between javascript and ends up in a Ruby script. arguments TODO: Can an IRBObject end up in a javascript script? If so, will it work fine? TODO: Make tests that allow Proc/block to be injected into javascript


Parameters:

  • args (Array)

    Ruby array with ruby arguments



368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
# File 'lib/jx/js.rb', line 368

def process_args2(args)

  args.map do |arg|
    case arg
    when Sol::IRBObject
      arg.to_java
    when Sol::JSObject, Sol::RBObject
      arg.jsvalue.to_java
    when Hash, Array
      pack(arg).to_java
    when Symbol
      raise "Ruby Symbols are not supported in jxBrowser.  Converting ':#{arg}' not supported."
    when Proc
      p "i´m a proc... not implemented yet"
      arg.to_java
    else
      arg.to_java
    end
  end
  
end

#proxy(obj) ⇒ JSObject || RBObject


Proxies a ruby object into a javascript object. The javascript object captures all method calls and forwads them to a packed ruby object, by calling method ‘run’ on this packed object


Parameters:

  • obj (Object)

    The ruby object to be proxied

Returns:



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/jx/js.rb', line 158

def proxy(obj)

  case obj
  when TrueClass, FalseClass, Numeric, String, NilClass
    obj
  when Java::ComTeamdevJxbrowserChromium::JSValue
    JSObject.build(obj)
  when Proc
    # TODO: Needs to test Proc proxying.  I don´t think the code ever gets here
    blk2func(obj)
  when Object
    # B.obj = Callback.new(obj)
    B.obj = Callback.build(obj)
    RBObject.new(jeval("new RubyProxy(obj)"), obj, true)
  else
    raise "No method to proxy the given object: #{obj}"
  end
  
end

#pull(name) ⇒ Object


return [JSObject || primitive] the given property from the ‘window’ scope




146
147
148
# File 'lib/jx/js.rb', line 146

def pull(name)
  eval("#{name};")
end

#push(value) ⇒ JSObject || primitive


Applies the javascript ‘identity’ function to the given value. be proxied


Returns:

  • (JSObject || primitive)

    a proxy object or a primitive that does not need to



138
139
140
# File 'lib/jx/js.rb', line 138

def push(value)
  @identity[value]
end

#style_sheetsObject


Returns a list of StyleSheet’s




419
420
421
422
423
424
# File 'lib/jx/js.rb', line 419

def style_sheets
  eval(<<-EOT)
    var __style_sheets__ = document.styleSheets;
  EOT
  CSSStyleSheets.new
end

#typeof(object) ⇒ Object





85
86
87
# File 'lib/jx/js.rb', line 85

def typeof(object)
  object.typeof
end

#windowObject



Returns:

  • the browser ‘window’ object



93
94
95
# File 'lib/jx/js.rb', line 93

def window
  @browser.executeJavaScriptAndReturnValue("window")
end