Removed outer tracks directory.

This commit is contained in:
bsag 2008-05-24 15:57:18 +01:00
parent 649f4a44a4
commit 20940ff348
2274 changed files with 0 additions and 0 deletions

View file

@ -0,0 +1,62 @@
module UJS
# The helper methods in this module can all be passed as arguments to apply_behaviour and allow
# you to reproduce common functionailty such as drag and drop and sorting in a simple way. Think
# of them as the apply_javascript equivilent to the Scriptaculous helpers.
#
# Usage:
#
# apply_behaviour '.products', make_draggable
# apply_behaviour '.help', make_remote_link( :action => 'showhelp' )
# apply_behaviour '.todolist', make_sortable
#
module BehaviourHelper
# Make a link send an Ajax request. options identical to linkt_to_remote except that
# :url defaults to the href attribute of the link.
def make_remote_link(options={})
options[:url] ||= javascript_variable('this.href');
"this.observe('click', function(event) {\n#{remote_function(options)};\nreturn false;\n});"
end
# Make a form submit via an Ajax request. options identical remote_form except that
# :url defaults to the action attribute of the form.
def make_remote_form(options={})
options[:url] ||= javascript_variable('this.action');
options[:with] ||= 'Form.serialize(this)'
"this.observe('submit', function(event) {\n#{remote_function(options)};\nreturn false;\n});"
end
# Observe a form or form field (specified with the type argument) using the given options
# which are the same as observe_form and observe_field.
def make_observed(type, options={})
obs = (type.to_s == 'form') ? 'Form' : 'Form.Element'
if options[:frequency] && options[:frequency] > 0
build_observer_js("#{obs}.Observer", javascript_variable('this'), options)
else
build_observer_js("#{obs}.EventObserver", javascript_variable('this'), options)
end
end
# Makes the children of the element sortable.
def make_sortable(options={})
sortable_element_js(javascript_variable('this'), options)
end
# Makes the element draggable.
def make_draggable(options={})
draggable_element_js(javascript_variable('this'), options)
end
# Makes the element a drop target.
def make_drop_receiving(options={})
drop_receiving_element_js(javascript_variable('this'), options)
end
def make_autocomplete # :nodoc:
end
def make_in_place_editor # :nodoc:
end
end
end

View file

@ -0,0 +1,58 @@
class UJS::BehaviourScript
attr_reader :rules
attr_writer :reapply_after_ajax
def initialize(cache=false, reapply_after_ajax=true)
@rules, @cache, @reapply_after_ajax = [], cache, reapply_after_ajax
end
def add_rule(selector, javascript, cancel_default=false)
javascript = javascript << cancel_default_js if cancel_default
@rules << [selector, javascript] unless rule_exists(selector, javascript)
end
def cache?
@cache
end
def enable_cache
@cache = true
end
def reapply_after_ajax?
@reapply_after_ajax
end
# Renders behaviour block and option JavaScript.
def to_s
(@rules && !@rules.empty?) ? "Event.addBehavior({\n#{rule_js}\n});" + option_js : ''
end
# Uses behaviour script converter to conver to a hash for session storage
def to_hash
UJS::BehaviourScriptConverter.convert_to_hash(self)
end
protected
# Renders a collection of behaviour rules in javascript format
def rule_js
@rules.uniq.collect { |sel, js| behaviour_rule(sel, js) }.join(",\n")
end
# Renders behaviour rule javascript for the behaviours file
def behaviour_rule(selector, behaviour)
"\"#{selector}\": function(event) {\n#{behaviour}\n}"
end
def option_js
reapply_after_ajax? ? '' : "\nEvent.addBehavior.reapplyAfterAjax = false;"
end
def cancel_default_js
" return false;"
end
def rule_exists(selector, javascript)
@rules.detect{|r| r[0] == selector && r[1] == javascript} != nil
end
end

View file

@ -0,0 +1,23 @@
class UJS::BehaviourScriptConverter
def initialize(script)
@script = script
end
# Converts a BehaviourScript object into a custom hash format
def self.convert_to_hash(script)
self.new(script).to_hash
end
# Converts a hash-converted BehaviourScript back to a BehaviourScript again
def self.convert_from_hash(script_hash)
script = UJS::BehaviourScript.new(script_hash[:options][:cache], script_hash[:options][:reapply_after_ajax])
script_hash[:rules].each { |r| script.add_rule(r[0], r[1]) }
script
end
# Convert behaviour script to a hash
def to_hash
{ :options => { :cache => @script.cache?, :reapply_after_ajax => @script.reapply_after_ajax? },
:rules => @script.rules }
end
end

View file

@ -0,0 +1,55 @@
module UJS::ControllerMethods
def self.included(base)
base.class_eval do
before_filter :store_controller_for_helpers
before_filter :initialise_js_behaviours
after_filter :store_js_behaviours
end
end
# Lets you register javascript behaviours from within
# the controller. For a description of the different options
# available, see UJS::Helpers#apply_behaviour (note:
# this function does not take a block like the view helper version)
def apply_behaviour(selector, behaviour, opts={})
opts.reverse_merge!(:prevent_default => false)
@js_behaviours.add_rule(selector, behaviour, opts[:prevent_default])
end
def cache_behaviours
@js_behaviours.enable_cache
end
def reapply_behaviours_after_ajax=(val)
@js_behaviours.reapply_after_ajax = val
end
# Make American and English spellings both work for apply_behaviour
alias_method :apply_behavior, :apply_behaviour
protected
# Initialises the javascript behaviours
def initialise_js_behaviours
@js_behaviours = UJS::BehaviourScript.new(@cache_behaviours)
end
# Clears the array of registered javascript behaviours
def reset_js_behaviours
session[:js_behaviours] = nil
end
# Returns a BehaviourScript from the behaviours serialized to the session
def js_behaviours
return nil if session[:js_behaviours].nil?
UJS::BehaviourScriptConverter.convert_from_hash(session[:js_behaviours])
end
# Stores all registered javascript behaviours in the session as a hash
def store_js_behaviours
session[:js_behaviours] = @js_behaviours.to_hash
end
def store_controller_for_helpers
ActionView::Helpers.current_controller = self
end
end

View file

@ -0,0 +1,152 @@
require File.dirname(__FILE__) + '/behaviour_helper'
require File.dirname(__FILE__) + '/javascript_proxies'
module UJS::Helpers
include UJS::BehaviourHelper
include UJS::JavascriptProxies
# This is the core functionality of the plugin;
# it allows you to attach javascript behaviour to your page
# elements in an unobtrusive fashion. It takes three options:
# * +selector+ - CSS selector and event. For a full overview of
# the selector syntax, see the event:Selectors website.
# http://encytemedia.com/event-selectors
# * +behaviour+ - The javascript that you want to attach to the element
# and event specified by +selector+ as a string of javascript.
# * +opts+ - A hash of additional options.
#
# Attaching a behaviour to an element on your page is as simple as
# specifying the element and the event you want the behaviour attached
# to, using the CSS selector format, and passing in a string of javascript:
#
# <% apply_behaviour "#coollink:click", "alert('Hello World')" %>
#
# You can also make use of any of the built-in Rails helpers that
# generate Javascript:
#
# <% apply_behaviour "#coolink:click", visual_effect(:highlight, "coollink") %>
#
# You will have access to two javascript variables inside your javascript string:
# * +this+: returns a reference to the HTML element that the behaviour was attached to
# * +event+: the event the behaviour was attached to:
#
# <% apply_behaviour "#coollink:click", "alert('You clicked ' this.id); Event.stop(event)" %>
#
# The following options can be set using the opts hash:
#
# * <tt>:external</tt> - If true, the behaviour will be attached to the external behaviour file.
# If false, it will be rendered directly in the page inside +script+ tags. Defaults to true.
#
# When setting <tt>:external</tt> to false, you <em>must</em> call the register_js_behaviour from
# within ERb <em>output</em> blocks. If <tt>:external</tt> is true, you can use either output or non-output blocks.
#
# If you set :prevent_default to true the default action of the event is stopped (similar to calling event.stop).
# This is very useful for hijacking links in order to provide some other behaviour.
#
# You can also pass a block to the function instead of a string of javascript -
# the block will be passed in a JavascriptGenerator object (+page+), the element (optional)
# and the event (optional). You can use the Javascript generator
# to write your attached behaviour using Ruby:
#
# <% apply_behaviour "#coollink:click" do |page, element, event|
# page.alert("Hi there, I'm going to fade away...")
# page.visual_effect :fade, element
# end %>
def apply_behaviour(selector, *args, &block) #:yields: page, element, event
opts = args.last.is_a?(Hash) ? args.pop : {}
set_default_external!(opts)
behaviour = normalise_behaviour_string(args.first || '')
if block_given?
generator = new_javascript_generator
args = [generator, element_proxy(generator), event_proxy(generator)][0..block.arity-1]
@template.instance_exec(*args, &block)
behaviour = generator.to_s
end
if !opts[:external]
render_inline_behaviour_block(selector, behaviour, opts)
else
@controller.apply_behaviour(selector, behaviour, opts) and return ''
end
end
# Allow you to apply multiple behaviours with block syntax.
#
# apply_behaviours do
# on 'a:click', 'alert("boo")'
# on 'abbr:mouseover', 'showAbbr(this)'
# end
def apply_behaviours(&block)
mapper = BehaviourMapper.new(self).instance_eval &block
mapper.to_s
end
# Make sure American and English spellings both work
alias_method :apply_behavior, :apply_behaviour
alias_method :apply_behaviors, :apply_behaviours
protected
# A convenient mapper class for applying
# multiple behaviours at once.
class BehaviourMapper
def initialize(base)
@base = base
@output = ''
end
def on(*args, &block)
@output << @base.apply_behaviour(*args, &block)
end
# delegate all other method calls to the view
def method_missing(meth, *args)
@base.send meth, *args
end
def to_s
@output
end
end
# Renders a block of javascript behaviours inside +script+ tags
# directly within the page
def render_inline_behaviour_block(selector, behaviour, opts)
script = UJS::BehaviourScript.new
script.add_rule(selector, behaviour)
javascript_tag(script.to_s)
end
# Use this to set the default :external option for helper calls.
# it set external to false if its an xhr request or false if it's a normal request.
def set_default_external!(options)
options.reverse_merge!(:external => !current_controller.request.xhr?)
end
# Returns a new JavascriptArgumentProxy for the element the behaviour
# has been applied to.
def element_proxy(generator)
UJS::JavascriptProxies::JavascriptArgumentProxy.new(UJS::JavascriptProxies::ReferencedJavascriptElementProxy, generator, 'this')
end
# Returns a new JavascriptArgumentProxy for the event the behaviour has
# been applied to.
def event_proxy(generator)
UJS::JavascriptProxies::JavascriptArgumentProxy.new(UJS::JavascriptProxies::JavascriptEventProxy, generator, 'event')
end
# Returns a new JavasScriptGenerator object
def new_javascript_generator
ActionView::Helpers::PrototypeHelper::JavaScriptGenerator.new(@template) { }
end
def current_controller
@controller
end
def normalise_behaviour_string(behaviour)
behaviour << ';' unless behaviour =~ /;$/
behaviour
end
end

View file

@ -0,0 +1,57 @@
module ActionView
module Helpers
class JavaScriptProxy
public :method_missing
protected
def wrap(function, *args)
args = [function_chain[-1].chomp(';')].concat(args.collect(&:to_json)).join(', ')
replace_line("#{function.to_s}(#{args});")
end
def replace_line(new_line)
function_chain[-1] = new_line
end
end
end
end
module UJS
module JavascriptProxies
class ReferencedJavascriptElementProxy < ActionView::Helpers::JavaScriptElementProxy
def initialize(generator, var)
@generator = generator
@generator << var
end
def reload; end
end
class JavascriptArgumentProxy
def initialize(proxy, *contructor_args)
@proxy, @args = proxy, contructor_args
end
def method_missing(meth, *args)
proxy = @proxy.new(*@args)
proxy.__send__(meth, *args)
end
end
class JavascriptEventProxy < ActionView::Helpers::JavaScriptProxy
def stop
wrap('Event.stop')
end
def element
wrap('Event.element')
end
end
end
end