WIN32OLE - 将 Ruby 函数注入 Internet Explorer 的 JavaScript
WIN32OLE - Inject Ruby function into Internet Explorer's JavaScript
在 AHK 中,以下代码可用于将 AHK 函数注入 Internet Explorer 的 JavaScript 引擎:
#Persistent
html =
(
<html>
<head>
<script>
document.setVar = function`(name,val`){
document[name]=val;
}
</script>
</head>
<body>
<h1>Hello!</h1>
</body>
</html>
)
ie := ComObjCreate("InternetExplorer.Application")
ie.navigate("about:blank")
sleep, 2000
msgbox, %html%
ie.document.writeln(html)
ie.visible := true
ie.document.setVar("someFunc",Func("someFunc"))
someFunc(){
msgbox, "hello"
}
注入函数后,JavaScript可以调用document.someFunc()
,从而JavaScript调用AHK函数,最终运行一个消息框。
我想将此代码移植到 Ruby。到目前为止我有这个:
require 'win32ole'
ie = WIN32OLE.new('InternetExplorer.Application')
ie.navigate("about:blank")
sleep(0.1) until !ie.busy
html = <<Heredoc
<html>
<head>
<script>
document.setVar = function(name,val){
document[name]=val;
}
</script>
</head>
<body>
<h1>Hello!</h1>
</body>
</html>
Heredoc
ie.document.writeln(html)
ie.visible = true
既然我们到了这里,我们应该能够注入 Ruby 方法,但是目前我不知道如何实现它。每次我尝试某事时,JavaScript 引擎都会冻结。我尝试过的一些事情:
ie.document.setVar("someFunc",method(:someFunc))
#----------------------------------
ie.document.setVar("someFunc",->{puts "hello"})
#----------------------------------
class someClass
def someFunc
puts "hello"
end
end
ie.document.setVar("someClass",someClass})
#----------------------------------
closure = Class.new(Fiddle::Closure) {
def call
puts "hello world"
end
}.new(Fiddle::TYPE_INT,[])
someFunc = Fiddle::Function.new(closure, [], Fiddle::TYPE_INT)
#Both:
doc.setVar("someFunc",closure)
#and
doc.setVar("someFunc",someFunc)
#----------------------------------
None 以上方法都有效。最后他们都冻结了 JavaScript 引擎...有谁知道我如何将对 Ruby 函数的实际引用传递给 JavaScript?
在互联网上搜索了一个星期后,一无所获,我想 "What if we are naive and pass an object with method_missing
defined?"
30 分钟后,我可以从 JavaScript 呼叫 Ruby。
class MyFunc
# Called when no arguments are passed to JavaScript function
def call
#Execute any ruby code here!!
#You can also return values back to JavaScript!!
return 1
end
# Called when arguments are passed to JavaScript function
def value(*args)
if args.length == 0
# This will be called if the function is called without parenthesis in JS
# e.g. console.log(document.someFunc)
return nil
else
#This is called with the parsed arguments. Note: Functions passed in from JS are of type WIN32OLE. Theoretically this should be callable, but better would be to make a JS function which can call other JS functions
#Execute any ruby code here!!
puts "#{args.inspect}"
#Can also return values here as well
return 1
end
end
end
ie.document.setVar("myFunc",MyFunc.new})
您还可以初始化和访问实例变量:
class MyClass
def initialize
@hello = "world"
end
end
ie.document.setVar("myClass",MyClass.new})
#IN IE: document.myClass["hello"] //=> "world"
注:
有些事情可能会出现严重错误,甚至会导致 ruby 崩溃。一些不起作用的例子:
- 直接评估对象:
document.myObj
。 JavaScript 会将函数解释为 Object ,也许正如人们所期望的那样。
- 获取不存在的值没有任何作用:
document.myObj["hello"]
。
- 设置不存在的值会导致 ruby 崩溃:
document.myObj["hello"]=1
。
有些事情也毫无意义,例如我做了以下循环:
给定一个 class:
class MyClass
def call
puts "Call"
end
def method_missing(m,*args,&block)
puts "#{m}(#{args.inspect})"
end
end
ie.document.setVar("obj",MyClass.new)
和JavaScript:
for(var i=0;i<24;i++){
document.obj[chars[i]]()
}
这将执行以字母字符命名的obj 的每个函数。事实上,它在大多数情况下确实这样做了,但有时却没有。有时它会调用主要的call
方法,而在document.obj.j()
的情况下它什么都不做...
完整日志:
a([])
b([])
c([])
d([])
e([])
f([])
Hello world
h([])
i([])
k([])
Hello world
m([])
n([])
o([])
q([])
s([])
t([])
Hello world
v([])
w([])
x([])
y([])
Hello world
编辑
I've written a GIST 这通常更容易实现。例如。要将 File
对象传递给 IE,您可以执行以下操作:
ie.document.setVar("RubyFile",WIN32OLE::getDispatch(File))
在 AHK 中,以下代码可用于将 AHK 函数注入 Internet Explorer 的 JavaScript 引擎:
#Persistent
html =
(
<html>
<head>
<script>
document.setVar = function`(name,val`){
document[name]=val;
}
</script>
</head>
<body>
<h1>Hello!</h1>
</body>
</html>
)
ie := ComObjCreate("InternetExplorer.Application")
ie.navigate("about:blank")
sleep, 2000
msgbox, %html%
ie.document.writeln(html)
ie.visible := true
ie.document.setVar("someFunc",Func("someFunc"))
someFunc(){
msgbox, "hello"
}
注入函数后,JavaScript可以调用document.someFunc()
,从而JavaScript调用AHK函数,最终运行一个消息框。
我想将此代码移植到 Ruby。到目前为止我有这个:
require 'win32ole'
ie = WIN32OLE.new('InternetExplorer.Application')
ie.navigate("about:blank")
sleep(0.1) until !ie.busy
html = <<Heredoc
<html>
<head>
<script>
document.setVar = function(name,val){
document[name]=val;
}
</script>
</head>
<body>
<h1>Hello!</h1>
</body>
</html>
Heredoc
ie.document.writeln(html)
ie.visible = true
既然我们到了这里,我们应该能够注入 Ruby 方法,但是目前我不知道如何实现它。每次我尝试某事时,JavaScript 引擎都会冻结。我尝试过的一些事情:
ie.document.setVar("someFunc",method(:someFunc))
#----------------------------------
ie.document.setVar("someFunc",->{puts "hello"})
#----------------------------------
class someClass
def someFunc
puts "hello"
end
end
ie.document.setVar("someClass",someClass})
#----------------------------------
closure = Class.new(Fiddle::Closure) {
def call
puts "hello world"
end
}.new(Fiddle::TYPE_INT,[])
someFunc = Fiddle::Function.new(closure, [], Fiddle::TYPE_INT)
#Both:
doc.setVar("someFunc",closure)
#and
doc.setVar("someFunc",someFunc)
#----------------------------------
None 以上方法都有效。最后他们都冻结了 JavaScript 引擎...有谁知道我如何将对 Ruby 函数的实际引用传递给 JavaScript?
在互联网上搜索了一个星期后,一无所获,我想 "What if we are naive and pass an object with method_missing
defined?"
30 分钟后,我可以从 JavaScript 呼叫 Ruby。
class MyFunc
# Called when no arguments are passed to JavaScript function
def call
#Execute any ruby code here!!
#You can also return values back to JavaScript!!
return 1
end
# Called when arguments are passed to JavaScript function
def value(*args)
if args.length == 0
# This will be called if the function is called without parenthesis in JS
# e.g. console.log(document.someFunc)
return nil
else
#This is called with the parsed arguments. Note: Functions passed in from JS are of type WIN32OLE. Theoretically this should be callable, but better would be to make a JS function which can call other JS functions
#Execute any ruby code here!!
puts "#{args.inspect}"
#Can also return values here as well
return 1
end
end
end
ie.document.setVar("myFunc",MyFunc.new})
您还可以初始化和访问实例变量:
class MyClass
def initialize
@hello = "world"
end
end
ie.document.setVar("myClass",MyClass.new})
#IN IE: document.myClass["hello"] //=> "world"
注:
有些事情可能会出现严重错误,甚至会导致 ruby 崩溃。一些不起作用的例子:
- 直接评估对象:
document.myObj
。 JavaScript 会将函数解释为 Object ,也许正如人们所期望的那样。 - 获取不存在的值没有任何作用:
document.myObj["hello"]
。 - 设置不存在的值会导致 ruby 崩溃:
document.myObj["hello"]=1
。
有些事情也毫无意义,例如我做了以下循环:
给定一个 class:
class MyClass
def call
puts "Call"
end
def method_missing(m,*args,&block)
puts "#{m}(#{args.inspect})"
end
end
ie.document.setVar("obj",MyClass.new)
和JavaScript:
for(var i=0;i<24;i++){
document.obj[chars[i]]()
}
这将执行以字母字符命名的obj 的每个函数。事实上,它在大多数情况下确实这样做了,但有时却没有。有时它会调用主要的call
方法,而在document.obj.j()
的情况下它什么都不做...
完整日志:
a([])
b([])
c([])
d([])
e([])
f([])
Hello world
h([])
i([])
k([])
Hello world
m([])
n([])
o([])
q([])
s([])
t([])
Hello world
v([])
w([])
x([])
y([])
Hello world
编辑
I've written a GIST 这通常更容易实现。例如。要将 File
对象传递给 IE,您可以执行以下操作:
ie.document.setVar("RubyFile",WIN32OLE::getDispatch(File))