red_query 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
|