red_query 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/README.rdoc +33 -0
- data/Rakefile +1 -0
- data/lib/red_query.rb +20 -0
- data/lib/red_query/ajax.rb +59 -0
- data/lib/red_query/browser.rb +23 -0
- data/lib/red_query/cookie.rb +144 -0
- data/lib/red_query/document.rb +28 -0
- data/lib/red_query/element.rb +270 -0
- data/lib/red_query/events.rb +40 -0
- data/lib/red_query/history.rb +30 -0
- data/lib/red_query/interval.rb +9 -0
- data/lib/red_query/json.rb +149 -0
- data/lib/red_query/location.rb +5 -0
- data/lib/red_query/observable.rb +35 -0
- data/lib/red_query/returning.rb +4 -0
- data/lib/red_query/singleton.rb +10 -0
- data/lib/red_query/string.rb +14 -0
- data/lib/red_query/timer.rb +9 -0
- data/lib/red_query/version.rb +3 -0
- data/red_query.gemspec +23 -0
- metadata +107 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.rdoc
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# jQuery based Framework for Red
|
2
|
+
|
3
|
+
Provides DOM, Ajax, JSON functionality for Red. Heavy usage of jQuery.
|
4
|
+
Its been developed for my personal fork of Red: http://github.com/julius/red
|
5
|
+
|
6
|
+
## Usage
|
7
|
+
|
8
|
+
Of course you need jQuery and your own source.
|
9
|
+
In addition you need a little startup code.
|
10
|
+
|
11
|
+
``` html
|
12
|
+
<script src="jquery.js"></script>
|
13
|
+
<!-- red_query startup code -->
|
14
|
+
<script type='text/javascript'>
|
15
|
+
jQuery.noConflict();
|
16
|
+
jQuery(document).ready(function(){
|
17
|
+
if (typeof c$Document !== "undefined")
|
18
|
+
c$Document.m$ready_bang();
|
19
|
+
else
|
20
|
+
throw "BIG problem with Red code";
|
21
|
+
});
|
22
|
+
</script>
|
23
|
+
<script src="your_red_file.js"></script>
|
24
|
+
```
|
25
|
+
|
26
|
+
Your main Red file should
|
27
|
+
|
28
|
+
require 'red_query'
|
29
|
+
|
30
|
+
And your compilation should include
|
31
|
+
|
32
|
+
red -I/path/to/red_query your_red_file
|
33
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
data/lib/red_query.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'red_query/version'
|
2
|
+
require 'red_query/observable'
|
3
|
+
require 'red_query/json'
|
4
|
+
require 'red_query/singleton'
|
5
|
+
require 'red_query/string'
|
6
|
+
require 'red_query/returning'
|
7
|
+
|
8
|
+
# ESSENTIALS
|
9
|
+
require 'red_query/ajax'
|
10
|
+
require 'red_query/browser'
|
11
|
+
require 'red_query/cookie'
|
12
|
+
require 'red_query/events'
|
13
|
+
require 'red_query/document'
|
14
|
+
require 'red_query/history'
|
15
|
+
require 'red_query/location'
|
16
|
+
require 'red_query/timer'
|
17
|
+
require 'red_query/interval'
|
18
|
+
|
19
|
+
module RedQuery
|
20
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module Ajax
|
2
|
+
def self.request(options)
|
3
|
+
options[:data] = options[:data] || {}
|
4
|
+
params = options[:data].to_query_string
|
5
|
+
success_callback = Proc.new { |text| options[:success].call(String.new(text)) }
|
6
|
+
error_callback = Proc.new { |msg| options[:problem].call(String.new(msg)) }
|
7
|
+
|
8
|
+
`jQuery.ajax({
|
9
|
+
url:#{options[:url]}.__value__,
|
10
|
+
type:#{options[:method]}.__value__,
|
11
|
+
data:#{params}.__value__,
|
12
|
+
success: function(msg) { return #{success_callback}.m$call(msg); },
|
13
|
+
error: function(xhr,msg) { return #{error_callback}.m$call(msg); }
|
14
|
+
})`
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.requestJSON(options)
|
18
|
+
orig_success = options[:success]
|
19
|
+
options[:success] = Proc.new { |text| orig_success.call(JSON.parse(text)) }
|
20
|
+
|
21
|
+
self.request(options)
|
22
|
+
end
|
23
|
+
|
24
|
+
class ::Hash
|
25
|
+
# call-seq:
|
26
|
+
# hsh.to_query_string -> string
|
27
|
+
#
|
28
|
+
# Returns a string representing _hsh_ formatted as HTTP data.
|
29
|
+
#
|
30
|
+
def to_query_string(base = '')
|
31
|
+
query_string = []
|
32
|
+
self.each do |k,v|
|
33
|
+
if `#{v} === false`
|
34
|
+
v = "false"
|
35
|
+
end
|
36
|
+
if `#{v} === true`
|
37
|
+
v = "true"
|
38
|
+
end
|
39
|
+
next if v.nil?
|
40
|
+
k = base.empty? ? k.to_s : "%s[%s]" % [base,k]
|
41
|
+
case v
|
42
|
+
when Hash
|
43
|
+
result = v.to_query_string(k)
|
44
|
+
when Array
|
45
|
+
qs = {}
|
46
|
+
`for(var i=0,l=v.length;i<l;i++){#{qs[i] = v[i]}}`
|
47
|
+
#v.each_with_index do |v,i|
|
48
|
+
# qs[i] = v
|
49
|
+
#end
|
50
|
+
result = qs.to_query_string(k)
|
51
|
+
else
|
52
|
+
result = "%s=%s" % [k, `$q(encodeURIComponent(v))`]
|
53
|
+
end
|
54
|
+
query_string.push(result)
|
55
|
+
end
|
56
|
+
return query_string.join('&')
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class Browser
|
2
|
+
@@history = nil
|
3
|
+
|
4
|
+
def self.ie?
|
5
|
+
return `jQuery.browser.msie`
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.version
|
9
|
+
`parseInt(jQuery.browser.version)`
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.history
|
13
|
+
if @@history.nil?
|
14
|
+
if Browser.ie? && Browser.version < 8
|
15
|
+
@@history = ::HistoryIE.new
|
16
|
+
else
|
17
|
+
@@history = ::HistoryNormal.new
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
@@history
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
# The excelent Cookie class stolen from Redshift
|
2
|
+
# removed Redshift::Document dependency
|
3
|
+
|
4
|
+
# Class +Cookie+ governs the writing and accessing of cookies in the browser.
|
5
|
+
#
|
6
|
+
# A cookie is a key-value pair stored by your browser as text data. If you
|
7
|
+
# know a cookie's key, you can read or overwrite its value, or reassign any of
|
8
|
+
# a number of parameters.
|
9
|
+
#
|
10
|
+
# Instances of class +Cookie+ are temporary holders for browser-based cookie
|
11
|
+
# data. When you create a new +Cookie+ object using <tt>Cookie.new</tt> or
|
12
|
+
# update an existing +Cookie+ object using <tt>Cookie#update</tt>, class
|
13
|
+
# +Cookie+ writes the key-value pair and the cookie's parameters to the
|
14
|
+
# browser's cookie file. You can then read the value of the cookie immediately
|
15
|
+
# or during subsequent visits using <tt>Cookie.read</tt>.
|
16
|
+
#
|
17
|
+
# The following parameters can be set for a +Cookie+ object:
|
18
|
+
#
|
19
|
+
# *Required*
|
20
|
+
# _key_:: The unique (per domain) identifier by which you identify a cookie.
|
21
|
+
# _value_:: The string of data associated with a given key.
|
22
|
+
#
|
23
|
+
# *Optional*
|
24
|
+
# _duration_:: The amount of time (in days) before the cookie should expire.
|
25
|
+
# _domain_:: The domain to which the cookie should be sent.
|
26
|
+
# _path_:: The path, relative to the domain, where the cookie is active.
|
27
|
+
# _secure_:: If +true+, the browser will use SSL when sending the cookie.
|
28
|
+
#
|
29
|
+
# The browser can hold up to 20 cookies from a single domain.
|
30
|
+
#
|
31
|
+
class Cookie
|
32
|
+
OPTIONS = {
|
33
|
+
:duration => nil,
|
34
|
+
:domain => nil,
|
35
|
+
:path => nil,
|
36
|
+
:secure => false
|
37
|
+
}
|
38
|
+
|
39
|
+
attr_accessor :key, :value, :duration, :domain, :path, :secure, :document
|
40
|
+
|
41
|
+
# call-seq:
|
42
|
+
# Cookie.new(key, value, options = {}) -> cookie
|
43
|
+
#
|
44
|
+
# Returns a new +Cookie+ object with the given parameters and stores the
|
45
|
+
# data in the browser as cookie data. If the browser already has a cookie
|
46
|
+
# that matches _key_, that cookie's parameters will be overwritten.
|
47
|
+
#
|
48
|
+
# Cookie.new(:user_jds, '2237115568') #=> #<Cookie: @key="user_jds" @value="2237115568">
|
49
|
+
# Cookie.read(:user_jds) #=> '2237115568'
|
50
|
+
#
|
51
|
+
# Cookie.new(:user_jds, '8557acb0') #=> #<Cookie: @key="user_jds" @value="8557acb0">
|
52
|
+
# Cookie.read(:user_jds) #=> '8557acb0'
|
53
|
+
#
|
54
|
+
def initialize(key, value, options = {})
|
55
|
+
self.key = key
|
56
|
+
self.update(value, OPTIONS.merge(options))
|
57
|
+
end
|
58
|
+
|
59
|
+
# call-seq:
|
60
|
+
# Cookie.read(key) -> string
|
61
|
+
#
|
62
|
+
# Returns the string value of the cookie named _key_, or +nil+ if no such
|
63
|
+
# cookie exists.
|
64
|
+
#
|
65
|
+
# c = Cookie.new(:user_jds, '2237115568', :domain => '.example.com')
|
66
|
+
#
|
67
|
+
# Cookie.read(:user_jds) #=> '2237115568'
|
68
|
+
#
|
69
|
+
# This method can be used to test whether a cookie with the name _key_
|
70
|
+
# exists in the browser.
|
71
|
+
#
|
72
|
+
# Cookie.new(:user_jds, '8557acb0') unless Cookie.read(:user_jds)
|
73
|
+
#
|
74
|
+
def self.read(key)
|
75
|
+
value = `document.cookie.match('(?:^|;)\\s*' + #{Regexp.escape(key)}.__value__ + '=([^;]*)')`
|
76
|
+
return value ? `$q(decodeURIComponent(value[1]))` : nil
|
77
|
+
end
|
78
|
+
|
79
|
+
# call-seq:
|
80
|
+
# Cookie.store(cookie) -> cookie
|
81
|
+
#
|
82
|
+
# Writes the given cookie to the browser, then returns _cookie_. This method
|
83
|
+
# is called internally by <tt>Cookie.new</tt> and <tt>Cookie#update</tt>.
|
84
|
+
#
|
85
|
+
def self.store(cookie)
|
86
|
+
`var str = cookie.m$key().__value__ + '=' + encodeURIComponent(cookie.m$value().__value__)`
|
87
|
+
`str += '; domain=' + cookie.m$domain().__value__` if cookie.domain
|
88
|
+
`str += '; path=' + cookie.m$path().__value__` if cookie.path
|
89
|
+
if cookie.duration
|
90
|
+
`date = new Date()`
|
91
|
+
`date.setTime(date.getTime() + cookie.m$duration() * 86400000)`
|
92
|
+
`str += '; expires=' + date.toGMTString()`
|
93
|
+
end
|
94
|
+
`str += '; secure'` if cookie.secure
|
95
|
+
|
96
|
+
`document.cookie = str`
|
97
|
+
return cookie
|
98
|
+
end
|
99
|
+
|
100
|
+
# call-seq:
|
101
|
+
# cookie.destroy -> true
|
102
|
+
#
|
103
|
+
# Expires _cookie_, then returns +true+.
|
104
|
+
#
|
105
|
+
# c = Cookie.new(:user_jds, '2237115568', :duration => 14)
|
106
|
+
#
|
107
|
+
# c.destroy #=> true
|
108
|
+
# Cookie.read(:user_jds) #=> nil
|
109
|
+
#
|
110
|
+
def destroy
|
111
|
+
self.update('',:duration => -1)
|
112
|
+
end
|
113
|
+
|
114
|
+
# call-seq:
|
115
|
+
# cookie.inspect -> string
|
116
|
+
#
|
117
|
+
# Returns a string representing _cookie_ and its key-value data.
|
118
|
+
#
|
119
|
+
# c = Cookie.new(:user_jds, '2237115568', :duration => 14)
|
120
|
+
#
|
121
|
+
# c.inspect #=> #<Cookie: @key="user_jds" @value="2237115568">
|
122
|
+
#
|
123
|
+
def inspect
|
124
|
+
"#<Cookie: @key=#{self.key.inspect} @value=#{self.value.inspect}>"
|
125
|
+
end
|
126
|
+
|
127
|
+
# call-seq:
|
128
|
+
# cookie.update(value, options = {}) -> cookie
|
129
|
+
#
|
130
|
+
# Updates _cookie_ with the given parameters, then writes the cookie data to
|
131
|
+
# the browser.
|
132
|
+
#
|
133
|
+
# c = Cookie.new(:user_jds, '2237115568', :duration => 14)
|
134
|
+
#
|
135
|
+
# Cookie.read(:user_jds) #=> '2237115568'
|
136
|
+
# c.update('8557acb0') #=> #<Cookie: @key="user_jds" @value="8557acb0">
|
137
|
+
# Cookie.read(:user_jds) #=> '8557acb0'
|
138
|
+
#
|
139
|
+
def update(value, options = {})
|
140
|
+
self.value = value
|
141
|
+
options.each {|k,v| self.send("#{k}=",v) }
|
142
|
+
Cookie.store(self)
|
143
|
+
end
|
144
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'element'
|
2
|
+
|
3
|
+
module Document
|
4
|
+
def self.as_element
|
5
|
+
return @elem if @elem
|
6
|
+
@elem = Element.new(`jQuery(document)`)
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.[](css_selector)
|
10
|
+
self.query(css_selector)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.find(css_selector)
|
14
|
+
self.query(css_selector)
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.query(css_selector)
|
18
|
+
self.as_element.find(css_selector)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.ready?(&block)
|
22
|
+
@ready_proc = block
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.ready!
|
26
|
+
@ready_proc.call if @ready_proc
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,270 @@
|
|
1
|
+
|
2
|
+
# represents one or more jQuery Elements
|
3
|
+
class Element < Array
|
4
|
+
|
5
|
+
@@element_id_count = 0
|
6
|
+
|
7
|
+
def [](index)
|
8
|
+
Element.new(`jQuery(#{@jq_native}[#{index}])`)
|
9
|
+
end
|
10
|
+
|
11
|
+
def length
|
12
|
+
`#{@jq_native}.length`
|
13
|
+
end
|
14
|
+
|
15
|
+
def size
|
16
|
+
length
|
17
|
+
end
|
18
|
+
|
19
|
+
def each
|
20
|
+
length.times { |i| yield self[i] }
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize(jq_native)
|
24
|
+
`#{self}.__jq_native__ = #{jq_native}`
|
25
|
+
@jq_native = jq_native
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.from_html(html)
|
29
|
+
Element.new(jq_native_from_html(html))
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.jq_native_from_html(html)
|
33
|
+
`jQuery(#{html}.__value__)`
|
34
|
+
end
|
35
|
+
|
36
|
+
# returns attr('id') of element. if none exists, one will be assigned
|
37
|
+
def id
|
38
|
+
id = attr('id')
|
39
|
+
return id unless id == ""
|
40
|
+
|
41
|
+
@@element_id_count += 1
|
42
|
+
id = "red_query_elem_#{@@element_id_count}"
|
43
|
+
attr('id', id)
|
44
|
+
return id
|
45
|
+
end
|
46
|
+
|
47
|
+
def append(elem)
|
48
|
+
`#{@jq_native}.append(#{elem}.__jq_native__)`
|
49
|
+
end
|
50
|
+
|
51
|
+
def prepend(elem)
|
52
|
+
`#{@jq_native}.prepend(#{elem}.__jq_native__)`
|
53
|
+
end
|
54
|
+
|
55
|
+
def after(elem)
|
56
|
+
`#{@jq_native}.after(#{elem}.__jq_native__)`
|
57
|
+
end
|
58
|
+
|
59
|
+
def before(elem)
|
60
|
+
`#{@jq_native}.before(#{elem}.__jq_native__)`
|
61
|
+
end
|
62
|
+
|
63
|
+
def attr(name, value = nil)
|
64
|
+
if value.nil?
|
65
|
+
String.new(`#{@jq_native}.attr(#{name}.__value__)`)
|
66
|
+
else
|
67
|
+
`#{@jq_native}.attr(#{name}.__value__, #{value}.__value__)`
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def click(&block)
|
72
|
+
callback = mouse_event(block)
|
73
|
+
`#{@jq_native}.click(function (event) { return #{callback}.m$call(event); })`
|
74
|
+
end
|
75
|
+
|
76
|
+
def add_class(css_class)
|
77
|
+
`#{@jq_native}.addClass(#{css_class}.__value__)`
|
78
|
+
end
|
79
|
+
|
80
|
+
def has_class(css_class)
|
81
|
+
`#{@jq_native}.hasClass(#{css_class}.__value__)`
|
82
|
+
end
|
83
|
+
|
84
|
+
def remove_class(css_class)
|
85
|
+
`#{@jq_native}.removeClass(#{css_class}.__value__)`
|
86
|
+
end
|
87
|
+
|
88
|
+
def css(key, value = nil, debug = false)
|
89
|
+
if value.nil?
|
90
|
+
String.new(`#{@jq_native}.css(#{key}.__value__)`)
|
91
|
+
else
|
92
|
+
`#{@jq_native}.css(#{key}.__value__, #{value}.__value__)`
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def find(css_selector)
|
97
|
+
e = Element.new(`#{@jq_native}.find(#{css_selector}.__value__)`)
|
98
|
+
# raise "[red_query/Element.find] Not found: #{css_selector}" unless e.length > 0
|
99
|
+
return e
|
100
|
+
end
|
101
|
+
|
102
|
+
def find_first(css_selector)
|
103
|
+
result = find(css_selector)
|
104
|
+
# return nil unless result
|
105
|
+
result[0]
|
106
|
+
end
|
107
|
+
|
108
|
+
def self.[](css_selector)
|
109
|
+
self.find(css_selector)
|
110
|
+
end
|
111
|
+
|
112
|
+
def focus
|
113
|
+
`#{@jq_native}.focus()`
|
114
|
+
end
|
115
|
+
|
116
|
+
def html(value = nil)
|
117
|
+
if value.nil?
|
118
|
+
String.new(`#{@jq_native}.html()`)
|
119
|
+
else
|
120
|
+
`#{@jq_native}.html(#{value}.__value__)`
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def height
|
125
|
+
`#{@jq_native}.height()`
|
126
|
+
end
|
127
|
+
|
128
|
+
def left(pos = nil)
|
129
|
+
if pos.nil?
|
130
|
+
`#{@jq_native}.offset().left`
|
131
|
+
else
|
132
|
+
`#{@jq_native}.left(#{pos})`
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def key_event(block)
|
137
|
+
Proc.new { |native_event|
|
138
|
+
block.call({
|
139
|
+
:code => `#{native_event}.keyCode`,
|
140
|
+
:shift => `#{native_event}.shiftKey`,
|
141
|
+
:ctrl => `#{native_event}.ctrlKey`,
|
142
|
+
:meta => `#{native_event}.metaKey`,
|
143
|
+
:prevent => Proc.new { `#{native_event}.preventDefault()` },
|
144
|
+
})
|
145
|
+
}
|
146
|
+
end
|
147
|
+
|
148
|
+
def key_down(&block)
|
149
|
+
callback = key_event(block)
|
150
|
+
`#{@jq_native}.keydown(function (event) { return #{callback}.m$call(event); })`
|
151
|
+
end
|
152
|
+
|
153
|
+
def key_press(&block)
|
154
|
+
callback = key_event(block)
|
155
|
+
`#{@jq_native}.keydown(function (event) { return #{callback}.m$call(event); })`
|
156
|
+
end
|
157
|
+
|
158
|
+
def key_up(&block)
|
159
|
+
callback = key_event(block)
|
160
|
+
`#{@jq_native}.keydown(function (event) { return #{callback}.m$call(event); })`
|
161
|
+
end
|
162
|
+
|
163
|
+
def mouse_event(block)
|
164
|
+
preventer = Proc.new { `#{native_event}.preventDefault()` }
|
165
|
+
|
166
|
+
Proc.new { |native_event|
|
167
|
+
# `console.log(#{native_event})`
|
168
|
+
block.call({
|
169
|
+
:client_x => `#{native_event}.clientX`,
|
170
|
+
:client_y => `#{native_event}.clientY`,
|
171
|
+
:page_x => `#{native_event}.pageX`,
|
172
|
+
:page_y => `#{native_event}.pageY`,
|
173
|
+
:screen_x => `#{native_event}.screenX`,
|
174
|
+
:screen_y => `#{native_event}.screenY`,
|
175
|
+
:prevent => preventer,
|
176
|
+
})
|
177
|
+
}
|
178
|
+
end
|
179
|
+
|
180
|
+
def mouse_down(&block)
|
181
|
+
callback = mouse_event(block)
|
182
|
+
`#{@jq_native}.mousedown(function (event) { return #{callback}.m$call(event); })`
|
183
|
+
end
|
184
|
+
|
185
|
+
def mouse_up(&block)
|
186
|
+
callback = mouse_event(block)
|
187
|
+
`#{@jq_native}.mouseup(function (event) { return #{callback}.m$call(event); })`
|
188
|
+
end
|
189
|
+
|
190
|
+
def hover(over_block, out_block)
|
191
|
+
over_fn = mouse_event(over_block)
|
192
|
+
out_fn = mouse_event(out_block)
|
193
|
+
`#{@jq_native}.hover(function(event){return #{over_fn}.m$call(event);}, function(event){return #{out_fn}.m$call(event);})`
|
194
|
+
end
|
195
|
+
|
196
|
+
# only for jquery 1.3+
|
197
|
+
# def mouse_enter(&block)
|
198
|
+
# callback = mouse_event(block)
|
199
|
+
# `#{@jq_native}.mouseenter(function (event) { return #{callback}.m$call(event); })`
|
200
|
+
# end
|
201
|
+
#
|
202
|
+
# def mouse_leave(&block)
|
203
|
+
# callback = mouse_event(block)
|
204
|
+
# `#{@jq_native}.mouseleave(function (event) { return #{callback}.m$call(event); })`
|
205
|
+
# end
|
206
|
+
|
207
|
+
def mouse_over(&block)
|
208
|
+
callback = mouse_event(block)
|
209
|
+
`#{@jq_native}.mouseover(function (event) { return #{callback}.m$call(event); })`
|
210
|
+
end
|
211
|
+
|
212
|
+
def mouse_move(&block)
|
213
|
+
callback = mouse_event(block)
|
214
|
+
`#{@jq_native}.mousemove(function (event) { return #{callback}.m$call(event); })`
|
215
|
+
end
|
216
|
+
|
217
|
+
def mouse_out(&block)
|
218
|
+
callback = mouse_event(block)
|
219
|
+
`#{@jq_native}.mouseout(function (event) { return #{callback}.m$call(event); })`
|
220
|
+
end
|
221
|
+
|
222
|
+
def name
|
223
|
+
attr("name")
|
224
|
+
end
|
225
|
+
|
226
|
+
def name=(value)
|
227
|
+
attr("name", value)
|
228
|
+
end
|
229
|
+
|
230
|
+
def remove
|
231
|
+
`#{@jq_native}.remove()`
|
232
|
+
end
|
233
|
+
|
234
|
+
def submit(&block)
|
235
|
+
`#{@jq_native}.submit(function () { return #{block.call} })`
|
236
|
+
end
|
237
|
+
|
238
|
+
def top(pos = nil)
|
239
|
+
if pos.nil?
|
240
|
+
`#{@jq_native}.offset().top`
|
241
|
+
else
|
242
|
+
`#{@jq_native}.top(#{pos})`
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
def scroll_top(pos = nil)
|
247
|
+
if pos.nil?
|
248
|
+
`#{@jq_native}.scrollTop()`
|
249
|
+
else
|
250
|
+
# `#{@jq_native}.scrollTop(#{pos})`
|
251
|
+
`#{@jq_native}.animate({scrollTop: #{pos}}, 500, "swing")`
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
def value(str = nil)
|
256
|
+
if str.nil?
|
257
|
+
String.new(`#{@jq_native}.val()`)
|
258
|
+
else
|
259
|
+
`#{@jq_native}.val(str.__value__)`
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
def width
|
264
|
+
`#{@jq_native}.width()`
|
265
|
+
end
|
266
|
+
|
267
|
+
def parent
|
268
|
+
Element.new(`jQuery(#{@jq_native}.parent().get(0))`)
|
269
|
+
end
|
270
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Events
|
2
|
+
# Defines allowed Events
|
3
|
+
# eg:
|
4
|
+
# class Foo
|
5
|
+
# include Events
|
6
|
+
# def initialize
|
7
|
+
# init_events :bar, :bat, :bitz
|
8
|
+
# end
|
9
|
+
# end
|
10
|
+
def init_events(*event_names)
|
11
|
+
@events = {}
|
12
|
+
event_names.each { |name| @events[name] = [] }
|
13
|
+
end
|
14
|
+
|
15
|
+
def add_events(*event_names)
|
16
|
+
event_names.each { |name|
|
17
|
+
@events[name] = []
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
def has_event?(event_name)
|
22
|
+
!!@events[event_name]
|
23
|
+
end
|
24
|
+
|
25
|
+
# registers Proc for given _event_name_
|
26
|
+
#
|
27
|
+
# eg:
|
28
|
+
# foo = Foo.new (Foo includes Events)
|
29
|
+
# foo.on("bar") { |event| puts event[:stuff] }
|
30
|
+
def on(event_name, &block)
|
31
|
+
raise "invalid event '#{event_name.inspect}' on #{self.class}" if @events[event_name].nil?
|
32
|
+
@events[event_name].push(block)
|
33
|
+
end
|
34
|
+
|
35
|
+
# fires event to all Procs registered for given _event_name_
|
36
|
+
def fire(event_name, event = nil)
|
37
|
+
raise "invalid event '#{event_name.inspect}' on #{self.class}" if @events[event_name].nil?
|
38
|
+
@events[event_name].each { |block| block.call(event) }
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class HistoryNormal
|
2
|
+
def set(hash)
|
3
|
+
`location.hash = "#" + #{hash}.__value__`
|
4
|
+
true
|
5
|
+
end
|
6
|
+
|
7
|
+
def get
|
8
|
+
String.new(`location.hash.substr(1)`)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class HistoryIE
|
13
|
+
def initialize
|
14
|
+
@iframe = Element.from_html('<iframe style="display:none" src="javascript:false;"></iframe>')
|
15
|
+
Document.query('head')[0].append(@iframe)
|
16
|
+
end
|
17
|
+
|
18
|
+
def set(hash)
|
19
|
+
`var d = #{@iframe}.__jq_native__.contentWindow.document;
|
20
|
+
d.open();
|
21
|
+
d.close();
|
22
|
+
d.location.hash = #{hash}.__value__;
|
23
|
+
`
|
24
|
+
true
|
25
|
+
end
|
26
|
+
|
27
|
+
def get
|
28
|
+
String.new(`#{@iframe}.contentWindow.document.location.hash`)
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
class JSON
|
2
|
+
# ======= Parsing =============================================
|
3
|
+
def self.parse(text)
|
4
|
+
raise "[JSON.parse] empty JSON-String" if text == ""
|
5
|
+
json_native = `eval("("+#{text}.__value__+")");`
|
6
|
+
JSON.translate(json_native)
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.classify(js_native)
|
10
|
+
type = String.new(`typeof #{js_native}`)
|
11
|
+
if (type == 'object' && `!#{js_native}`)
|
12
|
+
return "null"
|
13
|
+
end
|
14
|
+
if (type == 'object' && `Object.prototype.toString.apply(#{js_native}) === '[object Array]'`)
|
15
|
+
return "array"
|
16
|
+
end
|
17
|
+
type
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.translate_array(js_native)
|
21
|
+
js_natives = []
|
22
|
+
`for (var i=0; i<#{js_native}.length; i++) { #{js_natives}.push(#{js_native}[i]); }`
|
23
|
+
|
24
|
+
js_natives.collect { |x| JSON.translate(x) }
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.translate_object(js_native)
|
28
|
+
stuff = []
|
29
|
+
`for(var member in #{js_native}){#{stuff}.push(new Array($q(member), #{js_native}[member]));}`
|
30
|
+
|
31
|
+
obj = {}
|
32
|
+
stuff.each { |x|
|
33
|
+
key = x[0]
|
34
|
+
value = x[1]
|
35
|
+
obj[key] = JSON.translate(value)
|
36
|
+
}
|
37
|
+
return obj
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.translate(js_native)
|
41
|
+
type = JSON.classify(js_native)
|
42
|
+
if (type == 'string')
|
43
|
+
return String.new(js_native)
|
44
|
+
end
|
45
|
+
|
46
|
+
if (type == 'number' || type == 'boolean')
|
47
|
+
return js_native
|
48
|
+
end
|
49
|
+
|
50
|
+
if (type == 'array')
|
51
|
+
return JSON.translate_array(js_native)
|
52
|
+
end
|
53
|
+
|
54
|
+
if (type == 'object')
|
55
|
+
return JSON.translate_object(js_native)
|
56
|
+
end
|
57
|
+
|
58
|
+
return nil
|
59
|
+
end
|
60
|
+
|
61
|
+
# ======= Stringify =============================================
|
62
|
+
def self.classify_ruby(stuff)
|
63
|
+
if (stuff.class)
|
64
|
+
return stuff.class.inspect.split("::").last
|
65
|
+
end
|
66
|
+
"Boolean"
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.stringify_string(str)
|
70
|
+
`
|
71
|
+
var cx = /[\\u0000\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]/g,
|
72
|
+
escapable = /[\\\\\\"\\x00-\\x1f\\x7f-\\x9f\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]/g,
|
73
|
+
gap,
|
74
|
+
indent,
|
75
|
+
meta = { // table of character substitutions
|
76
|
+
'\\b': '\\\\b',
|
77
|
+
'\\t': '\\\\t',
|
78
|
+
'\\n': '\\\\n',
|
79
|
+
'\\f': '\\\\f',
|
80
|
+
'\\r': '\\\\r',
|
81
|
+
'"' : '\\\\"',
|
82
|
+
'\\\\': '\\\\\\\\'
|
83
|
+
},
|
84
|
+
rep;
|
85
|
+
|
86
|
+
|
87
|
+
function quote(string) {
|
88
|
+
escapable.lastIndex = 0;
|
89
|
+
return escapable.test(string) ?
|
90
|
+
'"' + string.replace(escapable, function (a) {
|
91
|
+
var c = meta[a];
|
92
|
+
return typeof c === 'string' ? c :
|
93
|
+
'\\\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
|
94
|
+
}) + '"' :
|
95
|
+
'"' + string + '"';
|
96
|
+
}
|
97
|
+
|
98
|
+
`
|
99
|
+
value = String.new(`quote(#{str}.__value__)`)
|
100
|
+
end
|
101
|
+
|
102
|
+
def self.stringify_array(stuff)
|
103
|
+
stuff.map! { |elem| JSON.stringify(elem) }
|
104
|
+
return '[' + stuff.join(',') + ']'
|
105
|
+
end
|
106
|
+
|
107
|
+
def self.stringify_hash(stuff)
|
108
|
+
pairs = []
|
109
|
+
stuff.each { |key, value| pairs.push(JSON.stringify(key) + ':' + JSON.stringify(value)) }
|
110
|
+
return '{' + pairs.join(',') + '}'
|
111
|
+
end
|
112
|
+
|
113
|
+
def self.stringify(stuff)
|
114
|
+
type = JSON.classify_ruby(stuff)
|
115
|
+
|
116
|
+
if (type == "Numeric" || type == "Boolean")
|
117
|
+
return stuff.inspect
|
118
|
+
end
|
119
|
+
|
120
|
+
if (type == "String")
|
121
|
+
return JSON.stringify_string(stuff)
|
122
|
+
end
|
123
|
+
|
124
|
+
if (type == "Symbol")
|
125
|
+
return JSON.stringify_string(stuff.to_s)
|
126
|
+
end
|
127
|
+
|
128
|
+
if (type == "Array")
|
129
|
+
return JSON.stringify_array(stuff)
|
130
|
+
end
|
131
|
+
|
132
|
+
if (type == "Hash")
|
133
|
+
return JSON.stringify_hash(stuff)
|
134
|
+
end
|
135
|
+
|
136
|
+
"null"
|
137
|
+
end
|
138
|
+
|
139
|
+
def self.generate(stuff)
|
140
|
+
self.stringify(stuff)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
|
145
|
+
class Hash
|
146
|
+
def to_json
|
147
|
+
JSON.generate(self)
|
148
|
+
end
|
149
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Observable
|
2
|
+
def add_observer(observer)
|
3
|
+
@_observers = [] unless @_observers
|
4
|
+
@_observers.push(observer)
|
5
|
+
end
|
6
|
+
|
7
|
+
def changed(state=true)
|
8
|
+
@_observe_state = state
|
9
|
+
end
|
10
|
+
|
11
|
+
def changed?
|
12
|
+
!!@_observe_state
|
13
|
+
end
|
14
|
+
|
15
|
+
def count_observers
|
16
|
+
return @_observers.size if @_observers
|
17
|
+
0
|
18
|
+
end
|
19
|
+
|
20
|
+
def delete_observers
|
21
|
+
@_observers = []
|
22
|
+
end
|
23
|
+
|
24
|
+
def delete_observer(observer)
|
25
|
+
return unless @_observers
|
26
|
+
@_observers.delete(observer)
|
27
|
+
end
|
28
|
+
|
29
|
+
def notify_observers(a, b, c, d, e, f, g, h)
|
30
|
+
return unless @_observers
|
31
|
+
@_observers.each { |o| o.update(a, b, c, d, e, f, g, h) }
|
32
|
+
@_observe_state = false
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
|
2
|
+
# useful web extensions for strings
|
3
|
+
|
4
|
+
class String
|
5
|
+
|
6
|
+
# encodes string to URI-Component
|
7
|
+
def to_uri_component
|
8
|
+
String.new(`encodeURIComponent(#{self}.__value__)`)
|
9
|
+
end
|
10
|
+
|
11
|
+
def substr(index, length)
|
12
|
+
String.new(`#{self}.__value__.substr(#{index}, #{length})`)
|
13
|
+
end
|
14
|
+
end
|
data/red_query.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
$:.push File.expand_path('../lib', __FILE__)
|
3
|
+
require 'red_query/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = 'red_query'
|
7
|
+
s.version = RedQuery::VERSION
|
8
|
+
s.authors = ['Julius Eckert']
|
9
|
+
s.email = ['eckert.julius@gmail.com']
|
10
|
+
s.homepage = ''
|
11
|
+
s.summary = %q{Provides DOM, Ajax, JSON functionality for Red. Heavy usage of jQuery.}
|
12
|
+
s.description = %q{Provides DOM, Ajax, JSON functionality for Red. Heavy usage of jQuery.}
|
13
|
+
|
14
|
+
s.rubyforge_project = 'red_query'
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ['lib']
|
20
|
+
|
21
|
+
s.add_dependency 'red'
|
22
|
+
s.add_development_dependency 'rake'
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: red_query
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Julius Eckert
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2011-08-12 00:00:00 +02:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - ">="
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
segments:
|
26
|
+
- 0
|
27
|
+
version: "0"
|
28
|
+
requirement: *id001
|
29
|
+
name: red
|
30
|
+
prerelease: false
|
31
|
+
type: :runtime
|
32
|
+
- !ruby/object:Gem::Dependency
|
33
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
34
|
+
requirements:
|
35
|
+
- - ">="
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
segments:
|
38
|
+
- 0
|
39
|
+
version: "0"
|
40
|
+
requirement: *id002
|
41
|
+
name: rake
|
42
|
+
prerelease: false
|
43
|
+
type: :development
|
44
|
+
description: Provides DOM, Ajax, JSON functionality for Red. Heavy usage of jQuery.
|
45
|
+
email:
|
46
|
+
- eckert.julius@gmail.com
|
47
|
+
executables: []
|
48
|
+
|
49
|
+
extensions: []
|
50
|
+
|
51
|
+
extra_rdoc_files: []
|
52
|
+
|
53
|
+
files:
|
54
|
+
- .gitignore
|
55
|
+
- Gemfile
|
56
|
+
- README.rdoc
|
57
|
+
- Rakefile
|
58
|
+
- lib/red_query.rb
|
59
|
+
- lib/red_query/ajax.rb
|
60
|
+
- lib/red_query/browser.rb
|
61
|
+
- lib/red_query/cookie.rb
|
62
|
+
- lib/red_query/document.rb
|
63
|
+
- lib/red_query/element.rb
|
64
|
+
- lib/red_query/events.rb
|
65
|
+
- lib/red_query/history.rb
|
66
|
+
- lib/red_query/interval.rb
|
67
|
+
- lib/red_query/json.rb
|
68
|
+
- lib/red_query/location.rb
|
69
|
+
- lib/red_query/observable.rb
|
70
|
+
- lib/red_query/returning.rb
|
71
|
+
- lib/red_query/singleton.rb
|
72
|
+
- lib/red_query/string.rb
|
73
|
+
- lib/red_query/timer.rb
|
74
|
+
- lib/red_query/version.rb
|
75
|
+
- red_query.gemspec
|
76
|
+
has_rdoc: true
|
77
|
+
homepage: ""
|
78
|
+
licenses: []
|
79
|
+
|
80
|
+
post_install_message:
|
81
|
+
rdoc_options: []
|
82
|
+
|
83
|
+
require_paths:
|
84
|
+
- lib
|
85
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
segments:
|
90
|
+
- 0
|
91
|
+
version: "0"
|
92
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
segments:
|
97
|
+
- 0
|
98
|
+
version: "0"
|
99
|
+
requirements: []
|
100
|
+
|
101
|
+
rubyforge_project: red_query
|
102
|
+
rubygems_version: 1.3.6
|
103
|
+
signing_key:
|
104
|
+
specification_version: 3
|
105
|
+
summary: Provides DOM, Ajax, JSON functionality for Red. Heavy usage of jQuery.
|
106
|
+
test_files: []
|
107
|
+
|