[MacRuby] #594: Not all methods visible to objective-c calls
#594: Not all methods visible to objective-c calls ------------------------------+--------------------------------------------- Reporter: michael@… | Owner: lsansonetti@… Type: defect | Status: new Priority: blocker | Milestone: Component: MacRuby | Keywords: ------------------------------+--------------------------------------------- The following code is taken from http://code.reflectivepixel.com/post/103638573/require-hotcocoa-framework- webkit-class and is just a short example of showing the problem: {{{ require 'hotcocoa' framework 'webkit' class Application include HotCocoa FULL={:expand => [:width,:height]} BASE=<<-END <html><head><style type="text/css"> * { font-family: Monaco; } </style><script type="text/javascript"> function say(arg) { window.TheBridge.click(arg);} </script> </head><body><h3>Ruby JavaScript Bridge</h3> <a href="#" onclick="say('hi')">tell</a></body></html> END def click(arg) #called from javascript root = document.createElement("div"); root.innerHTML="javascript tells ruby: #{arg}" document.body.appendChild(root) end def document @web_view.mainFrame.DOMDocument end def self.webScriptNameForSelector(sel) #hide : in name sel.to_s.sub(/:$/,'') if is_available_selector?(sel) end def self.isSelectorExcludedFromWebScript(sel) ! is_available_selector?(sel) end def self.isKeyExcludedFromWebScript(key) true end def self.is_available_selector?(sel) ['click:'].include?(sel.to_s) end def start application :name => "MyBridge" do |app| app.delegate = self window :title => "MyBridge", :frame => [10, 620, 330, 230] do |win| win << @web_view=web_view(:layout => FULL) do |wv| wv.mainFrame.loadHTMLString BASE, baseURL: nil wv.frameLoadDelegate=self wso=wv.windowScriptObject #make visible to JS wso.setValue(self, forKey:"TheBridge") end win.will_close { exit } end end end end Application.new.start }}} In this example, clicking on "tell" does not work. It seems, that the selector for "click:" is not found. When logging for example the selector values in {{{ self.isSelectorExcludedFromWebScript(sel) }}}, the "click:" selector is not amongst the results. This is not related to hotcocoa, this example can be simply reworked without using hotcocoa, just with a simple WebView embedded in a NSWindow from Interface Builder. -- Ticket URL: <http://www.macruby.org/trac/ticket/594> MacRuby <http://macruby.org/>
#594: Not all methods visible to objective-c calls ------------------------------+--------------------------------------------- Reporter: michael@… | Owner: lsansonetti@… Type: defect | Status: new Priority: critical | Milestone: Component: MacRuby | Keywords: ------------------------------+--------------------------------------------- Changes (by martinlagardette@…): * priority: blocker => critical Old description:
The following code is taken from http://code.reflectivepixel.com/post/103638573/require-hotcocoa- framework-webkit-class and is just a short example of showing the problem:
{{{ require 'hotcocoa' framework 'webkit' class Application include HotCocoa FULL={:expand => [:width,:height]} BASE=<<-END <html><head><style type="text/css"> * { font-family: Monaco; } </style><script type="text/javascript"> function say(arg) { window.TheBridge.click(arg);} </script> </head><body><h3>Ruby JavaScript Bridge</h3> <a href="#" onclick="say('hi')">tell</a></body></html> END def click(arg) #called from javascript root = document.createElement("div"); root.innerHTML="javascript tells ruby: #{arg}" document.body.appendChild(root) end def document @web_view.mainFrame.DOMDocument end def self.webScriptNameForSelector(sel) #hide : in name sel.to_s.sub(/:$/,'') if is_available_selector?(sel) end def self.isSelectorExcludedFromWebScript(sel) ! is_available_selector?(sel) end def self.isKeyExcludedFromWebScript(key) true end def self.is_available_selector?(sel) ['click:'].include?(sel.to_s) end def start application :name => "MyBridge" do |app| app.delegate = self window :title => "MyBridge", :frame => [10, 620, 330, 230] do |win| win << @web_view=web_view(:layout => FULL) do |wv| wv.mainFrame.loadHTMLString BASE, baseURL: nil wv.frameLoadDelegate=self wso=wv.windowScriptObject #make visible to JS wso.setValue(self, forKey:"TheBridge") end win.will_close { exit } end end end end Application.new.start }}}
In this example, clicking on "tell" does not work. It seems, that the selector for "click:" is not found. When logging for example the selector values in {{{ self.isSelectorExcludedFromWebScript(sel) }}}, the "click:" selector is not amongst the results.
This is not related to hotcocoa, this example can be simply reworked without using hotcocoa, just with a simple WebView embedded in a NSWindow from Interface Builder.
New description: The following code is taken from http://code.reflectivepixel.com/post/103638573/require-hotcocoa-framework- webkit-class and is just a short example of showing the problem: {{{ #!ruby require 'hotcocoa' framework 'webkit' class Application include HotCocoa FULL={:expand => [:width,:height]} BASE=<<-END <html><head><style type="text/css"> * { font-family: Monaco; } </style><script type="text/javascript"> function say(arg) { window.TheBridge.click(arg);} </script> </head><body><h3>Ruby JavaScript Bridge</h3> <a href="#" onclick="say('hi')">tell</a></body></html> END def click(arg) #called from javascript root = document.createElement("div"); root.innerHTML="javascript tells ruby: #{arg}" document.body.appendChild(root) end def document @web_view.mainFrame.DOMDocument end def self.webScriptNameForSelector(sel) #hide : in name sel.to_s.sub(/:$/,'') if is_available_selector?(sel) end def self.isSelectorExcludedFromWebScript(sel) ! is_available_selector?(sel) end def self.isKeyExcludedFromWebScript(key) true end def self.is_available_selector?(sel) ['click:'].include?(sel.to_s) end def start application :name => "MyBridge" do |app| app.delegate = self window :title => "MyBridge", :frame => [10, 620, 330, 230] do |win| win << @web_view=web_view(:layout => FULL) do |wv| wv.mainFrame.loadHTMLString BASE, baseURL: nil wv.frameLoadDelegate=self wso=wv.windowScriptObject #make visible to JS wso.setValue(self, forKey:"TheBridge") end win.will_close { exit } end end end end Application.new.start }}} In this example, clicking on "tell" does not work. It seems, that the selector for "click:" is not found. When logging for example the selector values in {{{ self.isSelectorExcludedFromWebScript(sel) }}} the "click:" selector is not amongst the results. This is not related to hotcocoa, this example can be simply reworked without using hotcocoa, just with a simple WebView embedded in a NSWindow from Interface Builder. -- Comment: I confirm this is not related to HotCocoa. I created a MacRuby project with Xcode + IB, set up a WebKit view, and the issue is happening. The problem comes from how MacRuby handles resolving methods compared to how WebKit retrieves an object's callable methods. For performance reason, MacRuby doesn't register all methods in the ObjC runtime at boot time, and only register them once they are resolved at runtime. This will be changed in a future version (either 0.7 or greater). The workaround for the moment is to call `object.methodSignatureForSelector("method:")`, which will JIT the method, insert it in the ObjC runtime, thus making it visible to WebKit. Attached is the test project (to show it's not related to HotCocoa, and for further resolution). -- Ticket URL: <http://www.macruby.org/trac/ticket/594#comment:1> MacRuby <http://macruby.org/>
#594: Not all methods visible to objective-c calls ------------------------------+--------------------------------------------- Reporter: michael@… | Owner: lsansonetti@… Type: defect | Status: new Priority: critical | Milestone: Component: MacRuby | Keywords: ------------------------------+--------------------------------------------- Comment(by michael@…): Thanks Thibault, great to see progress on this one. As soon as I get home I'll try your mentioned workaround; for now I've wrapped a ObjC class doing this purpose. From what I read on the mailing list, this ticket is scheduled for the 0.6 release, you mentioned that it will be changed in a future version - are there any plans for which milestone this is targeted? -- Ticket URL: <http://www.macruby.org/trac/ticket/594#comment:2> MacRuby <http://macruby.org/>
#594: Not all methods visible to objective-c calls ------------------------------+--------------------------------------------- Reporter: michael@… | Owner: lsansonetti@… Type: defect | Status: new Priority: critical | Milestone: Component: MacRuby | Keywords: ------------------------------+--------------------------------------------- Comment(by martinlagardette@…): On the mailing list, this ticket was identified as "we should fix it for 0.6". However, now that we know what the problem is, we know this won't be fixed for 0.6 as it would involve a major rewrite in the MacRuby runtime. The rewrite will be targeted for at least 0.7, or a later version. -- Ticket URL: <http://www.macruby.org/trac/ticket/594#comment:3> MacRuby <http://macruby.org/>
#594: Not all methods visible to objective-c calls ------------------------------+--------------------------------------------- Reporter: michael@… | Owner: lsansonetti@… Type: defect | Status: new Priority: critical | Milestone: Component: MacRuby | Keywords: ------------------------------+--------------------------------------------- Comment(by jazzbox@…): Yesterday i ran into the same problem. After two hours of unsuccessful investigation I found this ticket (sigh). Luckily there is a workaround which works for me. -- Ticket URL: <http://www.macruby.org/trac/ticket/594#comment:4> MacRuby <http://macruby.org/>
participants (1)
-
MacRuby