module Bowline module Desktop module JS #:nodoc: class Script include Bowline::Logging attr_reader :window, :script, :prok def initialize(window, script, prok = nil) @window = window @script = script @prok = prok end alias :windows :window def ready? multiple_windows? ? windows.all?(&:loaded?) : window.loaded? end def call if Desktop.enabled? debug "JS eval on #{window}: #{script}" if multiple_windows? windows.each {|w| w.run_script(script) } raise "Can't return from multiple windows" if prok else result = parse(window.run_script(script)) Thread.new { prok.call(result) } if prok end result else debug "Pseudo JS eval on #{window}: #{script}" prok.call(nil) if prok end end private def multiple_windows? windows.is_a?(Array) end def parse(str) return if str.blank? # This is crazy! The JSON # lib can't parse booleans case str when "true" then true when "false" then false else JSON.parse(str) end rescue => e debug "Parsing: #{str}" raise e end end def setup! #:nodoc: Desktop.on_idle(method(:poll)) end module_function :setup! def eval(window, string, method = nil, &block) script = Script.new(window, string, method||block) if Runtime.main_thread? && script.ready? script.call else scripts << script end end module_function :eval private def poll ready_scripts = scripts.select(&:ready?) ready_scripts.each do |script| script.call scripts.delete(script) end end module_function :poll def scripts @scripts ||= [] end module_function :scripts end end end