Module: UserEvents
- Included in:
- Element
- Defined in:
- lib/source/redshift/user_events.rb
Overview
The UserEvents
module mixes in methods for handling user-generated events such as mouse gestures and keystrokes. UserEvents
is also responsible for defining new event types based on native events.
Only Document
, Window
, and objects of class Element
respond to UserEvents
methods. See module CodeEvents
for information on defining and handling custom callback events.
Constant Summary collapse
- NATIVE_EVENTS =
{ # mouse buttons :click => 2, :dblclick => 2, :mouseup => 2, :mousedown => 2, :contextmenu => 2, # mouse wheel :mousewheel => 2, :DOMMouseScroll => 2, # mouse movement :mouseover => 2, :mouseout => 2, :mousemove => 2, :selectstart => 2, :selectend => 2, # keyboard :keydown => 2, :keypress => 2, :keyup => 2, # form elements :focus => 2, :blur => 2, :change => 2, :reset => 2, :select => 2, :submit => 2, # window :load => 1, :unload => 1, :beforeunload => 1, :resize => 1, :move => 1, :DOMContentLoaded => 1, :readystatechange => 1, # misc :error => 1, :abort => 1, :scroll => 1 }
- DEFINED_EVENTS =
{ :mouse_enter => {:base => 'mouseover', :condition => proc(`c$UserEvents.mousecheck`) }, :mouse_leave => {:base => 'mouseout', :condition => proc(`c$UserEvents.mousecheck`) }, :mouse_wheel => {:base => gecko? ? 'DOMMouseScroll' : 'mousewheel' } }
Class Method Summary collapse
-
.define(sym, hash = {}) ⇒ Object
call-seq: UserEvents.define(sym, { :base => symbol [, …] }) -> true.
-
.extended(base) ⇒ Object
:nodoc:.
-
.included(base) ⇒ Object
:nodoc:.
Instance Method Summary collapse
-
#add_listener(sym, &block) ⇒ Object
:nodoc:.
-
#listen(sym, &block) ⇒ Object
call-seq: obj.listen(sym) { |element,event| block } -> obj.
-
#remove_listener(sym, &block) ⇒ Object
:nodoc:.
-
#unlisten(sym, &block) ⇒ Object
call-seq: obj.unlisten(sym, &proc) -> obj.
Class Method Details
.define(sym, hash = {}) ⇒ Object
call-seq:
UserEvents.define(sym, { :base => symbol [, ...] }) -> true
Adds a new event type sym to the UserEvents::DEFINED_EVENTS hash with the given options. The following options can be set:
Required
- base
-
A symbol representing the native event type upon which sym will be based.
Optional
- condition
-
A
Proc
object with parameters|element, event|
which, if returningfalse
when evaluated for a given event, kills the event. - on_listen
-
A
Proc
object with parameters|element, listener_proc|
that is evaluated when sym is passed toUserEvents#listen
. - on_unlisten
-
A
Proc
object with parameters|element, listener_proc|
that is evaluated when sym is passed toUserEvents#unlisten
.
condition = proc {|element,event| event.shift? } #=> #<Proc:0x393825>
on_listen = proc {|element,listener_proc| puts "%s responds to shift-click with %s" % [element.inspect, listener_proc] } #=> #<Proc:0x3935da>
UserEvents.define(:shift_click, :base => 'click', :condition => condition, :on_listen => on_listen) #=> true
Document['#example'].listen :shift_click do |element,event|
puts "%s was shift-clicked" % element.inspect
end
produces:
#<Element: DIV id="example"> responds to shift-click with #<Proc:0x3962ae>
shift-clicking element ‘#example’ produces:
#<Element: DIV id="example"> was shift-clicked
106 107 108 109 |
# File 'lib/source/redshift/user_events.rb', line 106 def self.define(sym, hash = {}) DEFINED_EVENTS[sym.to_sym] = hash return true end |
Instance Method Details
#add_listener(sym, &block) ⇒ Object
:nodoc:
168 169 170 171 172 173 |
# File 'lib/source/redshift/user_events.rb', line 168 def add_listener(sym, &block) # :nodoc: `var el=this.__native__,type=sym.__value__,fn=block.__block__` `if(type==='unload'){var old=fn,that=this;fn=function(){that.m$remove_listener($q('unload'),fn);old();};}else{var collected = {};collected[this.__id__]=this}` # TODO: put this element into "collected" `if(el.addEventListener){el.addEventListener(type,fn,false);}else{el.attachEvent('on'+type,fn);}` return self end |
#listen(sym, &block) ⇒ Object
call-seq:
obj.listen(sym) { |element,event| block } -> obj
Adds a listener to obj for a native or defined user event type sym, then returns obj.
Document['#example'].listen :click do |element, event|
puts "%s was clicked" % element.inspect
end
clicking element ‘#example’ produces:
#<Element: DIV id="example"> was clicked
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/source/redshift/user_events.rb', line 133 def listen(sym, &block) type = sym.to_sym events = @events ||= {} events[type] ||= {} return self if events[type][block] custom = DEFINED_EVENTS[type] condition = block real_type = type if custom custom[:on_listen].call(self, block) if custom[:on_listen] if custom[:condition] condition = lambda {|element,event| custom[:condition].call(element,event) ? block.call(element,event) : true } end real_type = (custom[:base] || real_type).to_sym end listener = lambda { block.call(self,nil); } native_event = NATIVE_EVENTS[real_type] if native_event if native_event == 2 listener = lambda do |native_event| event = `$v(native_event)` event.kill! if condition.call(self,event) == false end end self.add_listener(real_type, &listener) end events[type][block] = listener return self end |
#remove_listener(sym, &block) ⇒ Object
:nodoc:
210 211 212 213 214 |
# File 'lib/source/redshift/user_events.rb', line 210 def remove_listener(sym, &block) # :nodoc: `var el=this.__native__,type=sym.__value__,fn=block.__block__` `if(this.removeEventListener){this.removeEventListener(type,fn,false);}else{this.detachEvent('on'+type,fn);}` return self end |
#unlisten(sym, &block) ⇒ Object
call-seq:
obj.unlisten(sym, &proc) -> obj
Unsets the function proc as a listener for event type sym, then returns obj. proc must be the self-same object originally assigned as a listener.
proc_1 = proc {|element,event| puts "%s was clicked" % element.inspect }
proc_2 = proc {|element,event| puts "%s has two listeners" % element.inspect }
elem = Document['#example']
elem.listen(:click, proc_1).listen(:click, proc_2) #=> #<Element: DIV id="example">
elem.unlisten(:click, proc_2) #=> #<Element: DIV id="example">
clicking element ‘#example’ produces:
#<Element: DIV id="example"> was clicked
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/source/redshift/user_events.rb', line 193 def unlisten(sym, &block) type = sym.to_sym events = @events return self unless events && events[type] && events[type][block] listener = events[type].delete(block) custom = DEFINED_EVENTS[type] if custom custom[:on_unlisten].call(self, block) if custom[:on_unlisten] type = (custom[:base] || type).to_sym end self.remove_listener(type, &listener) if NATIVE_EVENTS[type] return self end |