]> projects.mako.cc - selectricity-live/blob - vendor/plugins/ym4r_gm/lib/gm_plugin/mapping.rb
licensed under the AGPL
[selectricity-live] / vendor / plugins / ym4r_gm / lib / gm_plugin / mapping.rb
1 module Ym4r\r
2   module GmPlugin\r
3     #The module where all the Ruby-to-JavaScript conversion takes place. It is included by all the classes in the YM4R library.\r
4     module MappingObject\r
5       #The name of the variable in JavaScript space.\r
6       attr_reader :variable\r
7       \r
8       #Creates javascript code for missing methods + takes care of listeners\r
9       def method_missing(name,*args)\r
10         str_name = name.to_s\r
11         if str_name =~ /^on_(.*)/\r
12           if args.length != 1\r
13             raise ArgumentError("Only 1 argument is allowed on on_ methods");\r
14           else\r
15             Variable.new("GEvent.addListener(#{to_javascript},\"#{MappingObject.javascriptify_method($1)}\",#{args[0]})")\r
16           end\r
17         else\r
18           args.collect! do |arg|\r
19             MappingObject.javascriptify_variable(arg)\r
20           end\r
21           Variable.new("#{to_javascript}.#{MappingObject.javascriptify_method(str_name)}(#{args.join(",")})")\r
22         end\r
23       end\r
24             \r
25       #Creates javascript code for array or hash indexing\r
26       def [](index) #index could be an integer or string\r
27         return Variable.new("#{to_javascript}[#{MappingObject.javascriptify_variable(index)}]")\r
28       end\r
29 \r
30       #Transforms a Ruby object into a JavaScript string : MAppingObject, String, Array, Hash and general case (using to_s)\r
31       def self.javascriptify_variable(arg)\r
32         if arg.is_a?(MappingObject)\r
33           arg.to_javascript\r
34         elsif arg.is_a?(String)\r
35           "\"#{MappingObject.escape_javascript(arg)}\""\r
36         elsif arg.is_a?(Array)\r
37           "[" + arg.collect{ |a| MappingObject.javascriptify_variable(a)}.join(",") + "]"\r
38         elsif arg.is_a?(Hash)\r
39           "{" + arg.to_a.collect do |v|\r
40             "#{MappingObject.javascriptify_method(v[0].to_s)} : #{MappingObject.javascriptify_variable(v[1])}"\r
41           end.join(",") + "}"\r
42         elsif arg.nil?\r
43           "undefined"\r
44         else\r
45           arg.to_s\r
46         end\r
47       end\r
48       \r
49       #Escape string to be used in JavaScript. Lifted from rails.\r
50       def self.escape_javascript(javascript)\r
51         javascript.gsub(/\r\n|\n|\r/, "\\n").gsub("\"") { |m| "\\#{m}" }\r
52       end\r
53       \r
54       #Transform a ruby-type method name (like add_overlay) to a JavaScript-style one (like addOverlay).\r
55       def self.javascriptify_method(method_name)\r
56         method_name.gsub(/_(\w)/){|s| $1.upcase}\r
57       end\r
58       \r
59       #Declares a Mapping Object bound to a JavaScript variable of name +variable+.\r
60       def declare(variable)\r
61         @variable = variable\r
62         "var #{@variable} = #{create};"\r
63       end\r
64 \r
65       #declare with a random variable name\r
66       def declare_random(init,size = 8)\r
67         s = init.clone\r
68         6.times { s << (i = Kernel.rand(62); i += ((i < 10) ? 48 : ((i < 36) ? 55 : 61 ))).chr }\r
69         declare(s)\r
70       end\r
71 \r
72       #Checks if the MappinObject has been declared\r
73       def declared?\r
74         !@variable.nil?\r
75       end\r
76       \r
77       #Binds a Mapping object to a previously declared JavaScript variable of name +variable+.\r
78       def assign_to(variable)\r
79         @variable = variable\r
80         "#{@variable} = #{create};"\r
81       end\r
82 \r
83       #Assign the +value+ to the +property+ of the MappingObject\r
84       def set_property(property, value)\r
85         "#{to_javascript}.#{MappingObject.javascriptify_method(property.to_s)} = #{MappingObject.javascriptify_variable(value)}"\r
86       end\r
87 \r
88       #Returns the code to get a +property+ from the MappingObject\r
89       def get_property(property)\r
90         Variable.new("#{to_javascript}.#{MappingObject.javascriptify_method(property.to_s)}")\r
91       end\r
92       \r
93       #Returns a Javascript code representing the object\r
94       def to_javascript\r
95         unless @variable.nil?\r
96           @variable\r
97         else\r
98           create\r
99         end\r
100       end\r
101       \r
102       #Creates a Mapping Object in JavaScript.\r
103       #To be implemented by subclasses if needed\r
104       def create\r
105       end\r
106     end\r
107 \r
108     #Used to bind a ruby variable to an already existing JavaScript one. It doesn't have to be a variable in the sense "var variable" but it can be any valid JavaScript expression that has a value.\r
109     class Variable\r
110       include MappingObject\r
111       \r
112       def initialize(variable)\r
113         @variable = variable\r
114       end\r
115       #Returns the javascript expression contained in the object.\r
116       def create\r
117         @variable\r
118       end\r
119       #Returns the expression inside the Variable followed by a ";"\r
120       def to_s\r
121         @variable + ";"\r
122       end\r
123 \r
124       UNDEFINED = Variable.new("undefined")\r
125     end\r
126   end\r
127 end\r
128 \r

Benjamin Mako Hill || Want to submit a patch?