mirror of
https://github.com/redmine/redmine.git
synced 2025-11-15 09:46:02 +01:00
Unpacked OpenID gem. #699
git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2437 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
153
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/README
vendored
Normal file
153
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/README
vendored
Normal file
@@ -0,0 +1,153 @@
|
||||
== Welcome to Rails
|
||||
|
||||
Rails is a web-application and persistence framework that includes everything
|
||||
needed to create database-backed web-applications according to the
|
||||
Model-View-Control pattern of separation. This pattern splits the view (also
|
||||
called the presentation) into "dumb" templates that are primarily responsible
|
||||
for inserting pre-built data in between HTML tags. The model contains the
|
||||
"smart" domain objects (such as Account, Product, Person, Post) that holds all
|
||||
the business logic and knows how to persist themselves to a database. The
|
||||
controller handles the incoming requests (such as Save New Account, Update
|
||||
Product, Show Post) by manipulating the model and directing data to the view.
|
||||
|
||||
In Rails, the model is handled by what's called an object-relational mapping
|
||||
layer entitled Active Record. This layer allows you to present the data from
|
||||
database rows as objects and embellish these data objects with business logic
|
||||
methods. You can read more about Active Record in
|
||||
link:files/vendor/rails/activerecord/README.html.
|
||||
|
||||
The controller and view are handled by the Action Pack, which handles both
|
||||
layers by its two parts: Action View and Action Controller. These two layers
|
||||
are bundled in a single package due to their heavy interdependence. This is
|
||||
unlike the relationship between the Active Record and Action Pack that is much
|
||||
more separate. Each of these packages can be used independently outside of
|
||||
Rails. You can read more about Action Pack in
|
||||
link:files/vendor/rails/actionpack/README.html.
|
||||
|
||||
|
||||
== Getting started
|
||||
|
||||
1. Run the WEBrick servlet: <tt>ruby script/server</tt> (run with --help for options)
|
||||
...or if you have lighttpd installed: <tt>ruby script/lighttpd</tt> (it's faster)
|
||||
2. Go to http://localhost:3000/ and get "Congratulations, you've put Ruby on Rails!"
|
||||
3. Follow the guidelines on the "Congratulations, you've put Ruby on Rails!" screen
|
||||
|
||||
|
||||
== Example for Apache conf
|
||||
|
||||
<VirtualHost *:80>
|
||||
ServerName rails
|
||||
DocumentRoot /path/application/public/
|
||||
ErrorLog /path/application/log/server.log
|
||||
|
||||
<Directory /path/application/public/>
|
||||
Options ExecCGI FollowSymLinks
|
||||
AllowOverride all
|
||||
Allow from all
|
||||
Order allow,deny
|
||||
</Directory>
|
||||
</VirtualHost>
|
||||
|
||||
NOTE: Be sure that CGIs can be executed in that directory as well. So ExecCGI
|
||||
should be on and ".cgi" should respond. All requests from 127.0.0.1 go
|
||||
through CGI, so no Apache restart is necessary for changes. All other requests
|
||||
go through FCGI (or mod_ruby), which requires a restart to show changes.
|
||||
|
||||
|
||||
== Debugging Rails
|
||||
|
||||
Have "tail -f" commands running on both the server.log, production.log, and
|
||||
test.log files. Rails will automatically display debugging and runtime
|
||||
information to these files. Debugging info will also be shown in the browser
|
||||
on requests from 127.0.0.1.
|
||||
|
||||
|
||||
== Breakpoints
|
||||
|
||||
Breakpoint support is available through the script/breakpointer client. This
|
||||
means that you can break out of execution at any point in the code, investigate
|
||||
and change the model, AND then resume execution! Example:
|
||||
|
||||
class WeblogController < ActionController::Base
|
||||
def index
|
||||
@posts = Post.find_all
|
||||
breakpoint "Breaking out from the list"
|
||||
end
|
||||
end
|
||||
|
||||
So the controller will accept the action, run the first line, then present you
|
||||
with a IRB prompt in the breakpointer window. Here you can do things like:
|
||||
|
||||
Executing breakpoint "Breaking out from the list" at .../webrick_server.rb:16 in 'breakpoint'
|
||||
|
||||
>> @posts.inspect
|
||||
=> "[#<Post:0x14a6be8 @attributes={\"title\"=>nil, \"body\"=>nil, \"id\"=>\"1\"}>,
|
||||
#<Post:0x14a6620 @attributes={\"title\"=>\"Rails you know!\", \"body\"=>\"Only ten..\", \"id\"=>\"2\"}>]"
|
||||
>> @posts.first.title = "hello from a breakpoint"
|
||||
=> "hello from a breakpoint"
|
||||
|
||||
...and even better is that you can examine how your runtime objects actually work:
|
||||
|
||||
>> f = @posts.first
|
||||
=> #<Post:0x13630c4 @attributes={"title"=>nil, "body"=>nil, "id"=>"1"}>
|
||||
>> f.
|
||||
Display all 152 possibilities? (y or n)
|
||||
|
||||
Finally, when you're ready to resume execution, you press CTRL-D
|
||||
|
||||
|
||||
== Console
|
||||
|
||||
You can interact with the domain model by starting the console through script/console.
|
||||
Here you'll have all parts of the application configured, just like it is when the
|
||||
application is running. You can inspect domain models, change values, and save to the
|
||||
database. Starting the script without arguments will launch it in the development environment.
|
||||
Passing an argument will specify a different environment, like <tt>console production</tt>.
|
||||
|
||||
|
||||
== Description of contents
|
||||
|
||||
app
|
||||
Holds all the code that's specific to this particular application.
|
||||
|
||||
app/controllers
|
||||
Holds controllers that should be named like weblog_controller.rb for
|
||||
automated URL mapping. All controllers should descend from
|
||||
ActionController::Base.
|
||||
|
||||
app/models
|
||||
Holds models that should be named like post.rb.
|
||||
Most models will descend from ActiveRecord::Base.
|
||||
|
||||
app/views
|
||||
Holds the template files for the view that should be named like
|
||||
weblog/index.rhtml for the WeblogController#index action. All views use eRuby
|
||||
syntax. This directory can also be used to keep stylesheets, images, and so on
|
||||
that can be symlinked to public.
|
||||
|
||||
app/helpers
|
||||
Holds view helpers that should be named like weblog_helper.rb.
|
||||
|
||||
config
|
||||
Configuration files for the Rails environment, the routing map, the database, and other dependencies.
|
||||
|
||||
components
|
||||
Self-contained mini-applications that can bundle together controllers, models, and views.
|
||||
|
||||
lib
|
||||
Application specific libraries. Basically, any kind of custom code that doesn't
|
||||
belong under controllers, models, or helpers. This directory is in the load path.
|
||||
|
||||
public
|
||||
The directory available for the web server. Contains subdirectories for images, stylesheets,
|
||||
and javascripts. Also contains the dispatchers and the default HTML files.
|
||||
|
||||
script
|
||||
Helper scripts for automation and generation.
|
||||
|
||||
test
|
||||
Unit and functional tests along with fixtures.
|
||||
|
||||
vendor
|
||||
External libraries that the application depends on. Also includes the plugins subdirectory.
|
||||
This directory is in the load path.
|
||||
10
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/Rakefile
vendored
Normal file
10
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/Rakefile
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
||||
# for example lib/tasks/switchtower.rake, and they will automatically be available to Rake.
|
||||
|
||||
require(File.join(File.dirname(__FILE__), 'config', 'boot'))
|
||||
|
||||
require 'rake'
|
||||
require 'rake/testtask'
|
||||
require 'rake/rdoctask'
|
||||
|
||||
require 'tasks/rails'
|
||||
4
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/app/controllers/application.rb
vendored
Normal file
4
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/app/controllers/application.rb
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
# Filters added to this controller will be run for all controllers in the application.
|
||||
# Likewise, all the methods added will be available for all controllers.
|
||||
class ApplicationController < ActionController::Base
|
||||
end
|
||||
122
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/app/controllers/consumer_controller.rb
vendored
Normal file
122
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/app/controllers/consumer_controller.rb
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
require 'pathname'
|
||||
|
||||
require "openid"
|
||||
require 'openid/extensions/sreg'
|
||||
require 'openid/extensions/pape'
|
||||
require 'openid/store/filesystem'
|
||||
|
||||
class ConsumerController < ApplicationController
|
||||
layout nil
|
||||
|
||||
def index
|
||||
# render an openid form
|
||||
end
|
||||
|
||||
def start
|
||||
begin
|
||||
identifier = params[:openid_identifier]
|
||||
if identifier.nil?
|
||||
flash[:error] = "Enter an OpenID identifier"
|
||||
redirect_to :action => 'index'
|
||||
return
|
||||
end
|
||||
oidreq = consumer.begin(identifier)
|
||||
rescue OpenID::OpenIDError => e
|
||||
flash[:error] = "Discovery failed for #{identifier}: #{e}"
|
||||
redirect_to :action => 'index'
|
||||
return
|
||||
end
|
||||
if params[:use_sreg]
|
||||
sregreq = OpenID::SReg::Request.new
|
||||
# required fields
|
||||
sregreq.request_fields(['email','nickname'], true)
|
||||
# optional fields
|
||||
sregreq.request_fields(['dob', 'fullname'], false)
|
||||
oidreq.add_extension(sregreq)
|
||||
oidreq.return_to_args['did_sreg'] = 'y'
|
||||
end
|
||||
if params[:use_pape]
|
||||
papereq = OpenID::PAPE::Request.new
|
||||
papereq.add_policy_uri(OpenID::PAPE::AUTH_PHISHING_RESISTANT)
|
||||
papereq.max_auth_age = 2*60*60
|
||||
oidreq.add_extension(papereq)
|
||||
oidreq.return_to_args['did_pape'] = 'y'
|
||||
end
|
||||
if params[:force_post]
|
||||
oidreq.return_to_args['force_post']='x'*2048
|
||||
end
|
||||
return_to = url_for :action => 'complete', :only_path => false
|
||||
realm = url_for :action => 'index', :only_path => false
|
||||
|
||||
if oidreq.send_redirect?(realm, return_to, params[:immediate])
|
||||
redirect_to oidreq.redirect_url(realm, return_to, params[:immediate])
|
||||
else
|
||||
render :text => oidreq.html_markup(realm, return_to, params[:immediate], {'id' => 'openid_form'})
|
||||
end
|
||||
end
|
||||
|
||||
def complete
|
||||
# FIXME - url_for some action is not necessarily the current URL.
|
||||
current_url = url_for(:action => 'complete', :only_path => false)
|
||||
parameters = params.reject{|k,v|request.path_parameters[k]}
|
||||
oidresp = consumer.complete(parameters, current_url)
|
||||
case oidresp.status
|
||||
when OpenID::Consumer::FAILURE
|
||||
if oidresp.display_identifier
|
||||
flash[:error] = ("Verification of #{oidresp.display_identifier}"\
|
||||
" failed: #{oidresp.message}")
|
||||
else
|
||||
flash[:error] = "Verification failed: #{oidresp.message}"
|
||||
end
|
||||
when OpenID::Consumer::SUCCESS
|
||||
flash[:success] = ("Verification of #{oidresp.display_identifier}"\
|
||||
" succeeded.")
|
||||
if params[:did_sreg]
|
||||
sreg_resp = OpenID::SReg::Response.from_success_response(oidresp)
|
||||
sreg_message = "Simple Registration data was requested"
|
||||
if sreg_resp.empty?
|
||||
sreg_message << ", but none was returned."
|
||||
else
|
||||
sreg_message << ". The following data were sent:"
|
||||
sreg_resp.data.each {|k,v|
|
||||
sreg_message << "<br/><b>#{k}</b>: #{v}"
|
||||
}
|
||||
end
|
||||
flash[:sreg_results] = sreg_message
|
||||
end
|
||||
if params[:did_pape]
|
||||
pape_resp = OpenID::PAPE::Response.from_success_response(oidresp)
|
||||
pape_message = "A phishing resistant authentication method was requested"
|
||||
if pape_resp.auth_policies.member? OpenID::PAPE::AUTH_PHISHING_RESISTANT
|
||||
pape_message << ", and the server reported one."
|
||||
else
|
||||
pape_message << ", but the server did not report one."
|
||||
end
|
||||
if pape_resp.auth_time
|
||||
pape_message << "<br><b>Authentication time:</b> #{pape_resp.auth_time} seconds"
|
||||
end
|
||||
if pape_resp.nist_auth_level
|
||||
pape_message << "<br><b>NIST Auth Level:</b> #{pape_resp.nist_auth_level}"
|
||||
end
|
||||
flash[:pape_results] = pape_message
|
||||
end
|
||||
when OpenID::Consumer::SETUP_NEEDED
|
||||
flash[:alert] = "Immediate request failed - Setup Needed"
|
||||
when OpenID::Consumer::CANCEL
|
||||
flash[:alert] = "OpenID transaction cancelled."
|
||||
else
|
||||
end
|
||||
redirect_to :action => 'index'
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def consumer
|
||||
if @consumer.nil?
|
||||
dir = Pathname.new(RAILS_ROOT).join('db').join('cstore')
|
||||
store = OpenID::Store::Filesystem.new(dir)
|
||||
@consumer = OpenID::Consumer.new(session, store)
|
||||
end
|
||||
return @consumer
|
||||
end
|
||||
end
|
||||
45
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/app/controllers/login_controller.rb
vendored
Normal file
45
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/app/controllers/login_controller.rb
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
# Controller for handling the login, logout process for "users" of our
|
||||
# little server. Users have no password. This is just an example.
|
||||
|
||||
require 'openid'
|
||||
|
||||
class LoginController < ApplicationController
|
||||
|
||||
layout 'server'
|
||||
|
||||
def base_url
|
||||
url_for(:controller => 'login', :action => nil, :only_path => false)
|
||||
end
|
||||
|
||||
def index
|
||||
response.headers['X-XRDS-Location'] = url_for(:controller => "server",
|
||||
:action => "idp_xrds",
|
||||
:only_path => false)
|
||||
@base_url = base_url
|
||||
# just show the login page
|
||||
end
|
||||
|
||||
def submit
|
||||
user = params[:username]
|
||||
|
||||
# if we get a user, log them in by putting their username in
|
||||
# the session hash.
|
||||
unless user.nil?
|
||||
session[:username] = user unless user.nil?
|
||||
session[:approvals] = []
|
||||
flash[:notice] = "Your OpenID URL is <b>#{base_url}user/#{user}</b><br/><br/>Proceed to step 2 below."
|
||||
else
|
||||
flash[:error] = "Sorry, couldn't log you in. Try again."
|
||||
end
|
||||
|
||||
redirect_to :action => 'index'
|
||||
end
|
||||
|
||||
def logout
|
||||
# delete the username from the session hash
|
||||
session[:username] = nil
|
||||
session[:approvals] = nil
|
||||
redirect_to :action => 'index'
|
||||
end
|
||||
|
||||
end
|
||||
265
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/app/controllers/server_controller.rb
vendored
Normal file
265
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/app/controllers/server_controller.rb
vendored
Normal file
@@ -0,0 +1,265 @@
|
||||
require 'pathname'
|
||||
|
||||
# load the openid library, first trying rubygems
|
||||
#begin
|
||||
# require "rubygems"
|
||||
# require_gem "ruby-openid", ">= 1.0"
|
||||
#rescue LoadError
|
||||
require "openid"
|
||||
require "openid/consumer/discovery"
|
||||
require 'openid/extensions/sreg'
|
||||
require 'openid/extensions/pape'
|
||||
require 'openid/store/filesystem'
|
||||
#end
|
||||
|
||||
class ServerController < ApplicationController
|
||||
|
||||
include ServerHelper
|
||||
include OpenID::Server
|
||||
layout nil
|
||||
|
||||
def index
|
||||
begin
|
||||
oidreq = server.decode_request(params)
|
||||
rescue ProtocolError => e
|
||||
# invalid openid request, so just display a page with an error message
|
||||
render :text => e.to_s, :status => 500
|
||||
return
|
||||
end
|
||||
|
||||
# no openid.mode was given
|
||||
unless oidreq
|
||||
render :text => "This is an OpenID server endpoint."
|
||||
return
|
||||
end
|
||||
|
||||
oidresp = nil
|
||||
|
||||
if oidreq.kind_of?(CheckIDRequest)
|
||||
|
||||
identity = oidreq.identity
|
||||
|
||||
if oidreq.id_select
|
||||
if oidreq.immediate
|
||||
oidresp = oidreq.answer(false)
|
||||
elsif session[:username].nil?
|
||||
# The user hasn't logged in.
|
||||
show_decision_page(oidreq)
|
||||
return
|
||||
else
|
||||
# Else, set the identity to the one the user is using.
|
||||
identity = url_for_user
|
||||
end
|
||||
end
|
||||
|
||||
if oidresp
|
||||
nil
|
||||
elsif self.is_authorized(identity, oidreq.trust_root)
|
||||
oidresp = oidreq.answer(true, nil, identity)
|
||||
|
||||
# add the sreg response if requested
|
||||
add_sreg(oidreq, oidresp)
|
||||
# ditto pape
|
||||
add_pape(oidreq, oidresp)
|
||||
|
||||
elsif oidreq.immediate
|
||||
server_url = url_for :action => 'index'
|
||||
oidresp = oidreq.answer(false, server_url)
|
||||
|
||||
else
|
||||
show_decision_page(oidreq)
|
||||
return
|
||||
end
|
||||
|
||||
else
|
||||
oidresp = server.handle_request(oidreq)
|
||||
end
|
||||
|
||||
self.render_response(oidresp)
|
||||
end
|
||||
|
||||
def show_decision_page(oidreq, message="Do you trust this site with your identity?")
|
||||
session[:last_oidreq] = oidreq
|
||||
@oidreq = oidreq
|
||||
|
||||
if message
|
||||
flash[:notice] = message
|
||||
end
|
||||
|
||||
render :template => 'server/decide', :layout => 'server'
|
||||
end
|
||||
|
||||
def user_page
|
||||
# Yadis content-negotiation: we want to return the xrds if asked for.
|
||||
accept = request.env['HTTP_ACCEPT']
|
||||
|
||||
# This is not technically correct, and should eventually be updated
|
||||
# to do real Accept header parsing and logic. Though I expect it will work
|
||||
# 99% of the time.
|
||||
if accept and accept.include?('application/xrds+xml')
|
||||
user_xrds
|
||||
return
|
||||
end
|
||||
|
||||
# content negotiation failed, so just render the user page
|
||||
xrds_url = url_for(:controller=>'user',:action=>params[:username])+'/xrds'
|
||||
identity_page = <<EOS
|
||||
<html><head>
|
||||
<meta http-equiv="X-XRDS-Location" content="#{xrds_url}" />
|
||||
<link rel="openid.server" href="#{url_for :action => 'index'}" />
|
||||
</head><body><p>OpenID identity page for #{params[:username]}</p>
|
||||
</body></html>
|
||||
EOS
|
||||
|
||||
# Also add the Yadis location header, so that they don't have
|
||||
# to parse the html unless absolutely necessary.
|
||||
response.headers['X-XRDS-Location'] = xrds_url
|
||||
render :text => identity_page
|
||||
end
|
||||
|
||||
def user_xrds
|
||||
types = [
|
||||
OpenID::OPENID_2_0_TYPE,
|
||||
OpenID::OPENID_1_0_TYPE,
|
||||
OpenID::SREG_URI,
|
||||
]
|
||||
|
||||
render_xrds(types)
|
||||
end
|
||||
|
||||
def idp_xrds
|
||||
types = [
|
||||
OpenID::OPENID_IDP_2_0_TYPE,
|
||||
]
|
||||
|
||||
render_xrds(types)
|
||||
end
|
||||
|
||||
def decision
|
||||
oidreq = session[:last_oidreq]
|
||||
session[:last_oidreq] = nil
|
||||
|
||||
if params[:yes].nil?
|
||||
redirect_to oidreq.cancel_url
|
||||
return
|
||||
else
|
||||
id_to_send = params[:id_to_send]
|
||||
|
||||
identity = oidreq.identity
|
||||
if oidreq.id_select
|
||||
if id_to_send and id_to_send != ""
|
||||
session[:username] = id_to_send
|
||||
session[:approvals] = []
|
||||
identity = url_for_user
|
||||
else
|
||||
msg = "You must enter a username to in order to send " +
|
||||
"an identifier to the Relying Party."
|
||||
show_decision_page(oidreq, msg)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
if session[:approvals]
|
||||
session[:approvals] << oidreq.trust_root
|
||||
else
|
||||
session[:approvals] = [oidreq.trust_root]
|
||||
end
|
||||
oidresp = oidreq.answer(true, nil, identity)
|
||||
add_sreg(oidreq, oidresp)
|
||||
add_pape(oidreq, oidresp)
|
||||
return self.render_response(oidresp)
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def server
|
||||
if @server.nil?
|
||||
server_url = url_for :action => 'index', :only_path => false
|
||||
dir = Pathname.new(RAILS_ROOT).join('db').join('openid-store')
|
||||
store = OpenID::Store::Filesystem.new(dir)
|
||||
@server = Server.new(store, server_url)
|
||||
end
|
||||
return @server
|
||||
end
|
||||
|
||||
def approved(trust_root)
|
||||
return false if session[:approvals].nil?
|
||||
return session[:approvals].member?(trust_root)
|
||||
end
|
||||
|
||||
def is_authorized(identity_url, trust_root)
|
||||
return (session[:username] and (identity_url == url_for_user) and self.approved(trust_root))
|
||||
end
|
||||
|
||||
def render_xrds(types)
|
||||
type_str = ""
|
||||
|
||||
types.each { |uri|
|
||||
type_str += "<Type>#{uri}</Type>\n "
|
||||
}
|
||||
|
||||
yadis = <<EOS
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xrds:XRDS
|
||||
xmlns:xrds="xri://$xrds"
|
||||
xmlns="xri://$xrd*($v*2.0)">
|
||||
<XRD>
|
||||
<Service priority="0">
|
||||
#{type_str}
|
||||
<URI>#{url_for(:controller => 'server', :only_path => false)}</URI>
|
||||
</Service>
|
||||
</XRD>
|
||||
</xrds:XRDS>
|
||||
EOS
|
||||
|
||||
response.headers['content-type'] = 'application/xrds+xml'
|
||||
render :text => yadis
|
||||
end
|
||||
|
||||
def add_sreg(oidreq, oidresp)
|
||||
# check for Simple Registration arguments and respond
|
||||
sregreq = OpenID::SReg::Request.from_openid_request(oidreq)
|
||||
|
||||
return if sregreq.nil?
|
||||
# In a real application, this data would be user-specific,
|
||||
# and the user should be asked for permission to release
|
||||
# it.
|
||||
sreg_data = {
|
||||
'nickname' => session[:username],
|
||||
'fullname' => 'Mayor McCheese',
|
||||
'email' => 'mayor@example.com'
|
||||
}
|
||||
|
||||
sregresp = OpenID::SReg::Response.extract_response(sregreq, sreg_data)
|
||||
oidresp.add_extension(sregresp)
|
||||
end
|
||||
|
||||
def add_pape(oidreq, oidresp)
|
||||
papereq = OpenID::PAPE::Request.from_openid_request(oidreq)
|
||||
return if papereq.nil?
|
||||
paperesp = OpenID::PAPE::Response.new
|
||||
paperesp.nist_auth_level = 0 # we don't even do auth at all!
|
||||
oidresp.add_extension(paperesp)
|
||||
end
|
||||
|
||||
def render_response(oidresp)
|
||||
if oidresp.needs_signing
|
||||
signed_response = server.signatory.sign(oidresp)
|
||||
end
|
||||
web_response = server.encode_response(oidresp)
|
||||
|
||||
case web_response.code
|
||||
when HTTP_OK
|
||||
render :text => web_response.body, :status => 200
|
||||
|
||||
when HTTP_REDIRECT
|
||||
redirect_to web_response.headers['location']
|
||||
|
||||
else
|
||||
render :text => web_response.body, :status => 400
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
3
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/app/helpers/application_helper.rb
vendored
Normal file
3
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/app/helpers/application_helper.rb
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
# Methods added to this helper will be available to all templates in the application.
|
||||
module ApplicationHelper
|
||||
end
|
||||
2
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/app/helpers/login_helper.rb
vendored
Normal file
2
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/app/helpers/login_helper.rb
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
module LoginHelper
|
||||
end
|
||||
9
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/app/helpers/server_helper.rb
vendored
Normal file
9
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/app/helpers/server_helper.rb
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
module ServerHelper
|
||||
|
||||
def url_for_user
|
||||
url_for :controller => 'user', :action => session[:username]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
81
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/app/views/consumer/index.rhtml
vendored
Normal file
81
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/app/views/consumer/index.rhtml
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Rails OpenID Example Relying Party</title>
|
||||
</head>
|
||||
<style type="text/css">
|
||||
* {
|
||||
font-family: verdana,sans-serif;
|
||||
}
|
||||
body {
|
||||
width: 50em;
|
||||
margin: 1em;
|
||||
}
|
||||
div {
|
||||
padding: .5em;
|
||||
}
|
||||
.alert {
|
||||
border: 1px solid #e7dc2b;
|
||||
background: #fff888;
|
||||
}
|
||||
.error {
|
||||
border: 1px solid #ff0000;
|
||||
background: #ffaaaa;
|
||||
}
|
||||
.success {
|
||||
border: 1px solid #00ff00;
|
||||
background: #aaffaa;
|
||||
}
|
||||
#verify-form {
|
||||
border: 1px solid #777777;
|
||||
background: #dddddd;
|
||||
margin-top: 1em;
|
||||
padding-bottom: 0em;
|
||||
}
|
||||
input.openid {
|
||||
background: url( /images/openid_login_bg.gif ) no-repeat;
|
||||
background-position: 0 50%;
|
||||
background-color: #fff;
|
||||
padding-left: 18px;
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
<h1>Rails OpenID Example Relying Party</h1>
|
||||
<% if flash[:alert] %>
|
||||
<div class='alert'>
|
||||
<%= h(flash[:alert]) %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% if flash[:error] %>
|
||||
<div class='error'>
|
||||
<%= h(flash[:error]) %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% if flash[:success] %>
|
||||
<div class='success'>
|
||||
<%= h(flash[:success]) %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% if flash[:sreg_results] %>
|
||||
<div class='alert'>
|
||||
<%= flash[:sreg_results] %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% if flash[:pape_results] %>
|
||||
<div class='alert'>
|
||||
<%= flash[:pape_results] %>
|
||||
</div>
|
||||
<% end %>
|
||||
<div id="verify-form">
|
||||
<form method="get" accept-charset="UTF-8"
|
||||
action='<%= url_for :action => 'start' %>'>
|
||||
Identifier:
|
||||
<input type="text" class="openid" name="openid_identifier" />
|
||||
<input type="submit" value="Verify" /><br />
|
||||
<input type="checkbox" name="immediate" id="immediate" /><label for="immediate">Use immediate mode</label><br/>
|
||||
<input type="checkbox" name="use_sreg" id="use_sreg" /><label for="use_sreg">Request registration data</label><br/>
|
||||
<input type="checkbox" name="use_pape" id="use_pape" /><label for="use_pape">Request phishing-resistent auth policy (PAPE)</label><br/>
|
||||
<input type="checkbox" name="force_post" id="force_post" /><label for="force_post">Force the transaction to use POST by adding 2K of extra data</label>
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
68
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/app/views/layouts/server.rhtml
vendored
Normal file
68
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/app/views/layouts/server.rhtml
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
<html>
|
||||
<head><title>OpenID Server Example</title></head>
|
||||
<style type="text/css">
|
||||
* {
|
||||
font-family: verdana,sans-serif;
|
||||
}
|
||||
body {
|
||||
width: 50em;
|
||||
margin: 1em;
|
||||
}
|
||||
div {
|
||||
padding: .5em;
|
||||
}
|
||||
table {
|
||||
margin: none;
|
||||
padding: none;
|
||||
}
|
||||
.notice {
|
||||
border: 1px solid #60964f;
|
||||
background: #b3dca7;
|
||||
}
|
||||
.error {
|
||||
border: 1px solid #ff0000;
|
||||
background: #ffaaaa;
|
||||
}
|
||||
#login-form {
|
||||
border: 1px solid #777777;
|
||||
background: #dddddd;
|
||||
margin-top: 1em;
|
||||
padding-bottom: 0em;
|
||||
}
|
||||
table {
|
||||
padding: 1em;
|
||||
}
|
||||
li {margin-bottom: .5em;}
|
||||
span.openid:before {
|
||||
content: url(<%= @base_url %>images/openid_login_bg.gif) ;
|
||||
}
|
||||
span.openid {
|
||||
font-size: smaller;
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
|
||||
|
||||
|
||||
<% if session[:username] %>
|
||||
<div style="float:right;">
|
||||
Welcome, <%= session[:username] %> | <%= link_to('Log out', :controller => 'login', :action => 'logout') %><br />
|
||||
<span class="openid"><%= @base_url %>user/<%= session[:username] %></span>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<h3>Ruby OpenID Server Example</h3>
|
||||
|
||||
<hr/>
|
||||
|
||||
<% if flash[:notice] or flash[:error] %>
|
||||
<div class="<%= flash[:notice].nil? ? 'error' : 'notice' %>">
|
||||
<%= flash[:error] or flash[:notice] %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= @content_for_layout %>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
56
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/app/views/login/index.rhtml
vendored
Normal file
56
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/app/views/login/index.rhtml
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
|
||||
|
||||
<% if session[:username].nil? %>
|
||||
|
||||
<div id="login-form">
|
||||
<form method="get" action="<%= url_for :controller => 'login', :action => 'submit' %>">
|
||||
Type a username:
|
||||
<input type="text" name="username" />
|
||||
<input type="submit" value="Log In" />
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
<% end %>
|
||||
|
||||
<p> Welcome to the Ruby OpenID example. This code is a starting point
|
||||
for developers wishing to implement an OpenID provider or relying
|
||||
party. We've used the <a href="http://rubyonrails.org/">Rails</a>
|
||||
platform to demonstrate, but the library code is not Rails specific.</p>
|
||||
|
||||
<h2>To use the example provider</h2>
|
||||
<p>
|
||||
<ol>
|
||||
|
||||
<li>Enter a username in the form above. You will be "Logged In"
|
||||
to the server, at which point you may authenticate using an OpenID
|
||||
consumer. Your OpenID URL will be displayed after you log
|
||||
in.<p>The server will automatically create an identity page for
|
||||
you at <%= @base_url %>user/<i>name</i></p></li>
|
||||
|
||||
<li><p>Because WEBrick can only handle one thing at a time, you'll need to
|
||||
run another instance of the example on another port if you want to use
|
||||
a relying party to use with this example provider:</p>
|
||||
<blockquote>
|
||||
<code>script/server --port=3001</code>
|
||||
</blockquote>
|
||||
|
||||
<p>(The RP needs to be able to access the provider, so unless you're
|
||||
running this example on a public IP, you can't use the live example
|
||||
at <a href="http://openidenabled.com/">openidenabled.com</a> on
|
||||
your local provider.)</p>
|
||||
</li>
|
||||
|
||||
<li>Point your browser to this new instance and follow the directions
|
||||
below.</li>
|
||||
<!-- Fun fact: 'url_for :port => 3001' doesn't work very well. -->
|
||||
</ol>
|
||||
|
||||
</p>
|
||||
|
||||
<h2>To use the example relying party</h2>
|
||||
|
||||
<p>Visit <a href="<%= url_for :controller => 'consumer' %>">/consumer</a>
|
||||
and enter your OpenID.</p>
|
||||
</p>
|
||||
|
||||
26
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/app/views/server/decide.rhtml
vendored
Normal file
26
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/app/views/server/decide.rhtml
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<form method="post" action="<%= url_for :controller => 'server', :action => 'decision' %>">
|
||||
|
||||
<table>
|
||||
<tr><td>Site:</td><td><%= @oidreq.trust_root %></td></tr>
|
||||
|
||||
<% if @oidreq.id_select %>
|
||||
<tr>
|
||||
<td colspan="2">
|
||||
You entered the server identifier at the relying party.
|
||||
You'll need to send an identifier of your choosing. Enter a
|
||||
username below.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Identity to send:</td>
|
||||
<td><input type="text" name="id_to_send" size="25" /></td>
|
||||
</tr>
|
||||
<% else %>
|
||||
<tr><td>Identity:</td><td><%= @oidreq.identity %></td></tr>
|
||||
<% end %>
|
||||
</table>
|
||||
|
||||
<input type="submit" name="yes" value="yes" />
|
||||
<input type="submit" name="no" value="no" />
|
||||
|
||||
</form>
|
||||
19
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/config/boot.rb
vendored
Normal file
19
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/config/boot.rb
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
# Don't change this file. Configuration is done in config/environment.rb and config/environments/*.rb
|
||||
|
||||
unless defined?(RAILS_ROOT)
|
||||
root_path = File.join(File.dirname(__FILE__), '..')
|
||||
unless RUBY_PLATFORM =~ /mswin32/
|
||||
require 'pathname'
|
||||
root_path = Pathname.new(root_path).cleanpath(true).to_s
|
||||
end
|
||||
RAILS_ROOT = root_path
|
||||
end
|
||||
|
||||
if File.directory?("#{RAILS_ROOT}/vendor/rails")
|
||||
require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer"
|
||||
else
|
||||
require 'rubygems'
|
||||
require 'initializer'
|
||||
end
|
||||
|
||||
Rails::Initializer.run(:set_load_path)
|
||||
54
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/config/environment.rb
vendored
Normal file
54
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/config/environment.rb
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
# Be sure to restart your web server when you modify this file.
|
||||
|
||||
# Uncomment below to force Rails into production mode when
|
||||
# you don't control web/app server and can't set it the proper way
|
||||
# ENV['RAILS_ENV'] ||= 'production'
|
||||
|
||||
# Bootstrap the Rails environment, frameworks, and default configuration
|
||||
require File.join(File.dirname(__FILE__), 'boot')
|
||||
|
||||
Rails::Initializer.run do |config|
|
||||
# Settings in config/environments/* take precedence those specified here
|
||||
|
||||
# Skip frameworks you're not going to use
|
||||
# config.frameworks -= [ :action_web_service, :action_mailer ]
|
||||
|
||||
# Add additional load paths for your own custom dirs
|
||||
# config.load_paths += %W( #{RAILS_ROOT}/extras )
|
||||
|
||||
# Force all environments to use the same logger level
|
||||
# (by default production uses :info, the others :debug)
|
||||
# config.log_level = :debug
|
||||
|
||||
# Use the database for sessions instead of the file system
|
||||
# (create the session table with 'rake create_sessions_table')
|
||||
# config.action_controller.session_store = :active_record_store
|
||||
|
||||
# Enable page/fragment caching by setting a file-based store
|
||||
# (remember to create the caching directory and make it readable to the application)
|
||||
# config.action_controller.fragment_cache_store = :file_store, "#{RAILS_ROOT}/cache"
|
||||
|
||||
# Activate observers that should always be running
|
||||
# config.active_record.observers = :cacher, :garbage_collector
|
||||
|
||||
# Make Active Record use UTC-base instead of local time
|
||||
# config.active_record.default_timezone = :utc
|
||||
|
||||
# Use Active Record's schema dumper instead of SQL when creating the test database
|
||||
# (enables use of different database adapters for development and test environments)
|
||||
# config.active_record.schema_format = :ruby
|
||||
|
||||
# See Rails::Configuration for more options
|
||||
end
|
||||
|
||||
# Add new inflection rules using the following format
|
||||
# (all these examples are active by default):
|
||||
# Inflector.inflections do |inflect|
|
||||
# inflect.plural /^(ox)$/i, '\1en'
|
||||
# inflect.singular /^(ox)en/i, '\1'
|
||||
# inflect.irregular 'person', 'people'
|
||||
# inflect.uncountable %w( fish sheep )
|
||||
# end
|
||||
|
||||
# Include your application configuration below
|
||||
ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS[:session_key] = '_session_id_2'
|
||||
19
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/config/environments/development.rb
vendored
Normal file
19
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/config/environments/development.rb
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
# Settings specified here will take precedence over those in config/environment.rb
|
||||
|
||||
# In the development environment your application's code is reloaded on
|
||||
# every request. This slows down response time but is perfect for development
|
||||
# since you don't have to restart the webserver when you make code changes.
|
||||
config.cache_classes = false
|
||||
|
||||
# Log error messages when you accidentally call methods on nil.
|
||||
config.whiny_nils = true
|
||||
|
||||
# Enable the breakpoint server that script/breakpointer connects to
|
||||
config.breakpoint_server = true
|
||||
|
||||
# Show full error reports and disable caching
|
||||
config.action_controller.consider_all_requests_local = true
|
||||
config.action_controller.perform_caching = false
|
||||
|
||||
# Don't care if the mailer can't send
|
||||
config.action_mailer.raise_delivery_errors = false
|
||||
19
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/config/environments/production.rb
vendored
Normal file
19
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/config/environments/production.rb
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
# Settings specified here will take precedence over those in config/environment.rb
|
||||
|
||||
# The production environment is meant for finished, "live" apps.
|
||||
# Code is not reloaded between requests
|
||||
config.cache_classes = true
|
||||
|
||||
# Use a different logger for distributed setups
|
||||
# config.logger = SyslogLogger.new
|
||||
|
||||
|
||||
# Full error reports are disabled and caching is turned on
|
||||
config.action_controller.consider_all_requests_local = false
|
||||
config.action_controller.perform_caching = true
|
||||
|
||||
# Enable serving of images, stylesheets, and javascripts from an asset server
|
||||
# config.action_controller.asset_host = "http://assets.example.com"
|
||||
|
||||
# Disable delivery errors if you bad email addresses should just be ignored
|
||||
# config.action_mailer.raise_delivery_errors = false
|
||||
19
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/config/environments/test.rb
vendored
Normal file
19
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/config/environments/test.rb
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
# Settings specified here will take precedence over those in config/environment.rb
|
||||
|
||||
# The test environment is used exclusively to run your application's
|
||||
# test suite. You never need to work with it otherwise. Remember that
|
||||
# your test database is "scratch space" for the test suite and is wiped
|
||||
# and recreated between test runs. Don't rely on the data there!
|
||||
config.cache_classes = true
|
||||
|
||||
# Log error messages when you accidentally call methods on nil.
|
||||
config.whiny_nils = true
|
||||
|
||||
# Show full error reports and disable caching
|
||||
config.action_controller.consider_all_requests_local = true
|
||||
config.action_controller.perform_caching = false
|
||||
|
||||
# Tell ActionMailer not to deliver emails to the real world.
|
||||
# The :test delivery method accumulates sent emails in the
|
||||
# ActionMailer::Base.deliveries array.
|
||||
config.action_mailer.delivery_method = :test
|
||||
24
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/config/routes.rb
vendored
Normal file
24
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/config/routes.rb
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
ActionController::Routing::Routes.draw do |map|
|
||||
# Add your own custom routes here.
|
||||
# The priority is based upon order of creation: first created -> highest priority.
|
||||
|
||||
# Here's a sample route:
|
||||
# map.connect 'products/:id', :controller => 'catalog', :action => 'view'
|
||||
# Keep in mind you can assign values other than :controller and :action
|
||||
|
||||
# You can have the root of your site routed by hooking up ''
|
||||
# -- just remember to delete public/index.html.
|
||||
# map.connect '', :controller => "welcome"
|
||||
|
||||
map.connect '', :controller => 'login'
|
||||
map.connect 'server/xrds', :controller => 'server', :action => 'idp_xrds'
|
||||
map.connect 'user/:username', :controller => 'server', :action => 'user_page'
|
||||
map.connect 'user/:username/xrds', :controller => 'server', :action => 'user_xrds'
|
||||
|
||||
# Allow downloading Web Service WSDL as a file with an extension
|
||||
# instead of a file named 'wsdl'
|
||||
map.connect ':controller/service.wsdl', :action => 'wsdl'
|
||||
|
||||
# Install the default route as the lowest priority.
|
||||
map.connect ':controller/:action/:id'
|
||||
end
|
||||
2
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/doc/README_FOR_APP
vendored
Normal file
2
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/doc/README_FOR_APP
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
Use this README file to introduce your application and point to useful places in the API for learning more.
|
||||
Run "rake appdoc" to generate API documentation for your models and controllers.
|
||||
8
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/public/404.html
vendored
Normal file
8
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/public/404.html
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||
"http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<body>
|
||||
<h1>File not found</h1>
|
||||
<p>Change this error message for pages not found in public/404.html</p>
|
||||
</body>
|
||||
</html>
|
||||
8
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/public/500.html
vendored
Normal file
8
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/public/500.html
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
|
||||
"http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
<body>
|
||||
<h1>Application error (Apache)</h1>
|
||||
<p>Change this error message for exceptions thrown outside of an action (like in Dispatcher setups or broken Ruby code) in public/500.html</p>
|
||||
</body>
|
||||
</html>
|
||||
12
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/public/dispatch.cgi
vendored
Normal file
12
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/public/dispatch.cgi
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
#!/usr/bin/ruby1.8
|
||||
|
||||
#!/usr/local/bin/ruby
|
||||
|
||||
require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT)
|
||||
|
||||
# If you're using RubyGems and mod_ruby, this require should be changed to an absolute path one, like:
|
||||
# "/usr/local/lib/ruby/gems/1.8/gems/rails-0.8.0/lib/dispatcher" -- otherwise performance is severely impaired
|
||||
require "dispatcher"
|
||||
|
||||
ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) } if defined?(Apache::RubyRun)
|
||||
Dispatcher.dispatch
|
||||
26
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/public/dispatch.fcgi
vendored
Normal file
26
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/public/dispatch.fcgi
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/ruby1.8
|
||||
|
||||
#!/usr/local/bin/ruby
|
||||
#
|
||||
# You may specify the path to the FastCGI crash log (a log of unhandled
|
||||
# exceptions which forced the FastCGI instance to exit, great for debugging)
|
||||
# and the number of requests to process before running garbage collection.
|
||||
#
|
||||
# By default, the FastCGI crash log is RAILS_ROOT/log/fastcgi.crash.log
|
||||
# and the GC period is nil (turned off). A reasonable number of requests
|
||||
# could range from 10-100 depending on the memory footprint of your app.
|
||||
#
|
||||
# Example:
|
||||
# # Default log path, normal GC behavior.
|
||||
# RailsFCGIHandler.process!
|
||||
#
|
||||
# # Default log path, 50 requests between GC.
|
||||
# RailsFCGIHandler.process! nil, 50
|
||||
#
|
||||
# # Custom log path, normal GC behavior.
|
||||
# RailsFCGIHandler.process! '/var/log/myapp_fcgi_crash.log'
|
||||
#
|
||||
require File.dirname(__FILE__) + "/../config/environment"
|
||||
require 'fcgi_handler'
|
||||
|
||||
RailsFCGIHandler.process!
|
||||
12
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/public/dispatch.rb
vendored
Normal file
12
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/public/dispatch.rb
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
#!/usr/bin/ruby1.8
|
||||
|
||||
#!/usr/local/bin/ruby
|
||||
|
||||
require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT)
|
||||
|
||||
# If you're using RubyGems and mod_ruby, this require should be changed to an absolute path one, like:
|
||||
# "/usr/local/lib/ruby/gems/1.8/gems/rails-0.8.0/lib/dispatcher" -- otherwise performance is severely impaired
|
||||
require "dispatcher"
|
||||
|
||||
ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) } if defined?(Apache::RubyRun)
|
||||
Dispatcher.dispatch
|
||||
0
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/public/favicon.ico
vendored
Normal file
0
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/public/favicon.ico
vendored
Normal file
BIN
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/public/images/openid_login_bg.gif
vendored
Normal file
BIN
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/public/images/openid_login_bg.gif
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 237 B |
750
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/public/javascripts/controls.js
vendored
Normal file
750
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/public/javascripts/controls.js
vendored
Normal file
@@ -0,0 +1,750 @@
|
||||
// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
|
||||
// (c) 2005 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
|
||||
// (c) 2005 Jon Tirsen (http://www.tirsen.com)
|
||||
// Contributors:
|
||||
// Richard Livsey
|
||||
// Rahul Bhargava
|
||||
// Rob Wills
|
||||
//
|
||||
// See scriptaculous.js for full license.
|
||||
|
||||
// Autocompleter.Base handles all the autocompletion functionality
|
||||
// that's independent of the data source for autocompletion. This
|
||||
// includes drawing the autocompletion menu, observing keyboard
|
||||
// and mouse events, and similar.
|
||||
//
|
||||
// Specific autocompleters need to provide, at the very least,
|
||||
// a getUpdatedChoices function that will be invoked every time
|
||||
// the text inside the monitored textbox changes. This method
|
||||
// should get the text for which to provide autocompletion by
|
||||
// invoking this.getToken(), NOT by directly accessing
|
||||
// this.element.value. This is to allow incremental tokenized
|
||||
// autocompletion. Specific auto-completion logic (AJAX, etc)
|
||||
// belongs in getUpdatedChoices.
|
||||
//
|
||||
// Tokenized incremental autocompletion is enabled automatically
|
||||
// when an autocompleter is instantiated with the 'tokens' option
|
||||
// in the options parameter, e.g.:
|
||||
// new Ajax.Autocompleter('id','upd', '/url/', { tokens: ',' });
|
||||
// will incrementally autocomplete with a comma as the token.
|
||||
// Additionally, ',' in the above example can be replaced with
|
||||
// a token array, e.g. { tokens: [',', '\n'] } which
|
||||
// enables autocompletion on multiple tokens. This is most
|
||||
// useful when one of the tokens is \n (a newline), as it
|
||||
// allows smart autocompletion after linebreaks.
|
||||
|
||||
var Autocompleter = {}
|
||||
Autocompleter.Base = function() {};
|
||||
Autocompleter.Base.prototype = {
|
||||
baseInitialize: function(element, update, options) {
|
||||
this.element = $(element);
|
||||
this.update = $(update);
|
||||
this.hasFocus = false;
|
||||
this.changed = false;
|
||||
this.active = false;
|
||||
this.index = 0;
|
||||
this.entryCount = 0;
|
||||
|
||||
if (this.setOptions)
|
||||
this.setOptions(options);
|
||||
else
|
||||
this.options = options || {};
|
||||
|
||||
this.options.paramName = this.options.paramName || this.element.name;
|
||||
this.options.tokens = this.options.tokens || [];
|
||||
this.options.frequency = this.options.frequency || 0.4;
|
||||
this.options.minChars = this.options.minChars || 1;
|
||||
this.options.onShow = this.options.onShow ||
|
||||
function(element, update){
|
||||
if(!update.style.position || update.style.position=='absolute') {
|
||||
update.style.position = 'absolute';
|
||||
Position.clone(element, update, {setHeight: false, offsetTop: element.offsetHeight});
|
||||
}
|
||||
Effect.Appear(update,{duration:0.15});
|
||||
};
|
||||
this.options.onHide = this.options.onHide ||
|
||||
function(element, update){ new Effect.Fade(update,{duration:0.15}) };
|
||||
|
||||
if (typeof(this.options.tokens) == 'string')
|
||||
this.options.tokens = new Array(this.options.tokens);
|
||||
|
||||
this.observer = null;
|
||||
|
||||
this.element.setAttribute('autocomplete','off');
|
||||
|
||||
Element.hide(this.update);
|
||||
|
||||
Event.observe(this.element, "blur", this.onBlur.bindAsEventListener(this));
|
||||
Event.observe(this.element, "keypress", this.onKeyPress.bindAsEventListener(this));
|
||||
},
|
||||
|
||||
show: function() {
|
||||
if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update);
|
||||
if(!this.iefix &&
|
||||
(navigator.appVersion.indexOf('MSIE')>0) &&
|
||||
(navigator.userAgent.indexOf('Opera')<0) &&
|
||||
(Element.getStyle(this.update, 'position')=='absolute')) {
|
||||
new Insertion.After(this.update,
|
||||
'<iframe id="' + this.update.id + '_iefix" '+
|
||||
'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' +
|
||||
'src="javascript:false;" frameborder="0" scrolling="no"></iframe>');
|
||||
this.iefix = $(this.update.id+'_iefix');
|
||||
}
|
||||
if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50);
|
||||
},
|
||||
|
||||
fixIEOverlapping: function() {
|
||||
Position.clone(this.update, this.iefix);
|
||||
this.iefix.style.zIndex = 1;
|
||||
this.update.style.zIndex = 2;
|
||||
Element.show(this.iefix);
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
this.stopIndicator();
|
||||
if(Element.getStyle(this.update, 'display')!='none') this.options.onHide(this.element, this.update);
|
||||
if(this.iefix) Element.hide(this.iefix);
|
||||
},
|
||||
|
||||
startIndicator: function() {
|
||||
if(this.options.indicator) Element.show(this.options.indicator);
|
||||
},
|
||||
|
||||
stopIndicator: function() {
|
||||
if(this.options.indicator) Element.hide(this.options.indicator);
|
||||
},
|
||||
|
||||
onKeyPress: function(event) {
|
||||
if(this.active)
|
||||
switch(event.keyCode) {
|
||||
case Event.KEY_TAB:
|
||||
case Event.KEY_RETURN:
|
||||
this.selectEntry();
|
||||
Event.stop(event);
|
||||
case Event.KEY_ESC:
|
||||
this.hide();
|
||||
this.active = false;
|
||||
Event.stop(event);
|
||||
return;
|
||||
case Event.KEY_LEFT:
|
||||
case Event.KEY_RIGHT:
|
||||
return;
|
||||
case Event.KEY_UP:
|
||||
this.markPrevious();
|
||||
this.render();
|
||||
if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event);
|
||||
return;
|
||||
case Event.KEY_DOWN:
|
||||
this.markNext();
|
||||
this.render();
|
||||
if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event);
|
||||
return;
|
||||
}
|
||||
else
|
||||
if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN)
|
||||
return;
|
||||
|
||||
this.changed = true;
|
||||
this.hasFocus = true;
|
||||
|
||||
if(this.observer) clearTimeout(this.observer);
|
||||
this.observer =
|
||||
setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000);
|
||||
},
|
||||
|
||||
onHover: function(event) {
|
||||
var element = Event.findElement(event, 'LI');
|
||||
if(this.index != element.autocompleteIndex)
|
||||
{
|
||||
this.index = element.autocompleteIndex;
|
||||
this.render();
|
||||
}
|
||||
Event.stop(event);
|
||||
},
|
||||
|
||||
onClick: function(event) {
|
||||
var element = Event.findElement(event, 'LI');
|
||||
this.index = element.autocompleteIndex;
|
||||
this.selectEntry();
|
||||
this.hide();
|
||||
},
|
||||
|
||||
onBlur: function(event) {
|
||||
// needed to make click events working
|
||||
setTimeout(this.hide.bind(this), 250);
|
||||
this.hasFocus = false;
|
||||
this.active = false;
|
||||
},
|
||||
|
||||
render: function() {
|
||||
if(this.entryCount > 0) {
|
||||
for (var i = 0; i < this.entryCount; i++)
|
||||
this.index==i ?
|
||||
Element.addClassName(this.getEntry(i),"selected") :
|
||||
Element.removeClassName(this.getEntry(i),"selected");
|
||||
|
||||
if(this.hasFocus) {
|
||||
this.show();
|
||||
this.active = true;
|
||||
}
|
||||
} else {
|
||||
this.active = false;
|
||||
this.hide();
|
||||
}
|
||||
},
|
||||
|
||||
markPrevious: function() {
|
||||
if(this.index > 0) this.index--
|
||||
else this.index = this.entryCount-1;
|
||||
},
|
||||
|
||||
markNext: function() {
|
||||
if(this.index < this.entryCount-1) this.index++
|
||||
else this.index = 0;
|
||||
},
|
||||
|
||||
getEntry: function(index) {
|
||||
return this.update.firstChild.childNodes[index];
|
||||
},
|
||||
|
||||
getCurrentEntry: function() {
|
||||
return this.getEntry(this.index);
|
||||
},
|
||||
|
||||
selectEntry: function() {
|
||||
this.active = false;
|
||||
this.updateElement(this.getCurrentEntry());
|
||||
},
|
||||
|
||||
updateElement: function(selectedElement) {
|
||||
if (this.options.updateElement) {
|
||||
this.options.updateElement(selectedElement);
|
||||
return;
|
||||
}
|
||||
|
||||
var value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal');
|
||||
var lastTokenPos = this.findLastToken();
|
||||
if (lastTokenPos != -1) {
|
||||
var newValue = this.element.value.substr(0, lastTokenPos + 1);
|
||||
var whitespace = this.element.value.substr(lastTokenPos + 1).match(/^\s+/);
|
||||
if (whitespace)
|
||||
newValue += whitespace[0];
|
||||
this.element.value = newValue + value;
|
||||
} else {
|
||||
this.element.value = value;
|
||||
}
|
||||
this.element.focus();
|
||||
|
||||
if (this.options.afterUpdateElement)
|
||||
this.options.afterUpdateElement(this.element, selectedElement);
|
||||
},
|
||||
|
||||
updateChoices: function(choices) {
|
||||
if(!this.changed && this.hasFocus) {
|
||||
this.update.innerHTML = choices;
|
||||
Element.cleanWhitespace(this.update);
|
||||
Element.cleanWhitespace(this.update.firstChild);
|
||||
|
||||
if(this.update.firstChild && this.update.firstChild.childNodes) {
|
||||
this.entryCount =
|
||||
this.update.firstChild.childNodes.length;
|
||||
for (var i = 0; i < this.entryCount; i++) {
|
||||
var entry = this.getEntry(i);
|
||||
entry.autocompleteIndex = i;
|
||||
this.addObservers(entry);
|
||||
}
|
||||
} else {
|
||||
this.entryCount = 0;
|
||||
}
|
||||
|
||||
this.stopIndicator();
|
||||
|
||||
this.index = 0;
|
||||
this.render();
|
||||
}
|
||||
},
|
||||
|
||||
addObservers: function(element) {
|
||||
Event.observe(element, "mouseover", this.onHover.bindAsEventListener(this));
|
||||
Event.observe(element, "click", this.onClick.bindAsEventListener(this));
|
||||
},
|
||||
|
||||
onObserverEvent: function() {
|
||||
this.changed = false;
|
||||
if(this.getToken().length>=this.options.minChars) {
|
||||
this.startIndicator();
|
||||
this.getUpdatedChoices();
|
||||
} else {
|
||||
this.active = false;
|
||||
this.hide();
|
||||
}
|
||||
},
|
||||
|
||||
getToken: function() {
|
||||
var tokenPos = this.findLastToken();
|
||||
if (tokenPos != -1)
|
||||
var ret = this.element.value.substr(tokenPos + 1).replace(/^\s+/,'').replace(/\s+$/,'');
|
||||
else
|
||||
var ret = this.element.value;
|
||||
|
||||
return /\n/.test(ret) ? '' : ret;
|
||||
},
|
||||
|
||||
findLastToken: function() {
|
||||
var lastTokenPos = -1;
|
||||
|
||||
for (var i=0; i<this.options.tokens.length; i++) {
|
||||
var thisTokenPos = this.element.value.lastIndexOf(this.options.tokens[i]);
|
||||
if (thisTokenPos > lastTokenPos)
|
||||
lastTokenPos = thisTokenPos;
|
||||
}
|
||||
return lastTokenPos;
|
||||
}
|
||||
}
|
||||
|
||||
Ajax.Autocompleter = Class.create();
|
||||
Object.extend(Object.extend(Ajax.Autocompleter.prototype, Autocompleter.Base.prototype), {
|
||||
initialize: function(element, update, url, options) {
|
||||
this.baseInitialize(element, update, options);
|
||||
this.options.asynchronous = true;
|
||||
this.options.onComplete = this.onComplete.bind(this);
|
||||
this.options.defaultParams = this.options.parameters || null;
|
||||
this.url = url;
|
||||
},
|
||||
|
||||
getUpdatedChoices: function() {
|
||||
entry = encodeURIComponent(this.options.paramName) + '=' +
|
||||
encodeURIComponent(this.getToken());
|
||||
|
||||
this.options.parameters = this.options.callback ?
|
||||
this.options.callback(this.element, entry) : entry;
|
||||
|
||||
if(this.options.defaultParams)
|
||||
this.options.parameters += '&' + this.options.defaultParams;
|
||||
|
||||
new Ajax.Request(this.url, this.options);
|
||||
},
|
||||
|
||||
onComplete: function(request) {
|
||||
this.updateChoices(request.responseText);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// The local array autocompleter. Used when you'd prefer to
|
||||
// inject an array of autocompletion options into the page, rather
|
||||
// than sending out Ajax queries, which can be quite slow sometimes.
|
||||
//
|
||||
// The constructor takes four parameters. The first two are, as usual,
|
||||
// the id of the monitored textbox, and id of the autocompletion menu.
|
||||
// The third is the array you want to autocomplete from, and the fourth
|
||||
// is the options block.
|
||||
//
|
||||
// Extra local autocompletion options:
|
||||
// - choices - How many autocompletion choices to offer
|
||||
//
|
||||
// - partialSearch - If false, the autocompleter will match entered
|
||||
// text only at the beginning of strings in the
|
||||
// autocomplete array. Defaults to true, which will
|
||||
// match text at the beginning of any *word* in the
|
||||
// strings in the autocomplete array. If you want to
|
||||
// search anywhere in the string, additionally set
|
||||
// the option fullSearch to true (default: off).
|
||||
//
|
||||
// - fullSsearch - Search anywhere in autocomplete array strings.
|
||||
//
|
||||
// - partialChars - How many characters to enter before triggering
|
||||
// a partial match (unlike minChars, which defines
|
||||
// how many characters are required to do any match
|
||||
// at all). Defaults to 2.
|
||||
//
|
||||
// - ignoreCase - Whether to ignore case when autocompleting.
|
||||
// Defaults to true.
|
||||
//
|
||||
// It's possible to pass in a custom function as the 'selector'
|
||||
// option, if you prefer to write your own autocompletion logic.
|
||||
// In that case, the other options above will not apply unless
|
||||
// you support them.
|
||||
|
||||
Autocompleter.Local = Class.create();
|
||||
Autocompleter.Local.prototype = Object.extend(new Autocompleter.Base(), {
|
||||
initialize: function(element, update, array, options) {
|
||||
this.baseInitialize(element, update, options);
|
||||
this.options.array = array;
|
||||
},
|
||||
|
||||
getUpdatedChoices: function() {
|
||||
this.updateChoices(this.options.selector(this));
|
||||
},
|
||||
|
||||
setOptions: function(options) {
|
||||
this.options = Object.extend({
|
||||
choices: 10,
|
||||
partialSearch: true,
|
||||
partialChars: 2,
|
||||
ignoreCase: true,
|
||||
fullSearch: false,
|
||||
selector: function(instance) {
|
||||
var ret = []; // Beginning matches
|
||||
var partial = []; // Inside matches
|
||||
var entry = instance.getToken();
|
||||
var count = 0;
|
||||
|
||||
for (var i = 0; i < instance.options.array.length &&
|
||||
ret.length < instance.options.choices ; i++) {
|
||||
|
||||
var elem = instance.options.array[i];
|
||||
var foundPos = instance.options.ignoreCase ?
|
||||
elem.toLowerCase().indexOf(entry.toLowerCase()) :
|
||||
elem.indexOf(entry);
|
||||
|
||||
while (foundPos != -1) {
|
||||
if (foundPos == 0 && elem.length != entry.length) {
|
||||
ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" +
|
||||
elem.substr(entry.length) + "</li>");
|
||||
break;
|
||||
} else if (entry.length >= instance.options.partialChars &&
|
||||
instance.options.partialSearch && foundPos != -1) {
|
||||
if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) {
|
||||
partial.push("<li>" + elem.substr(0, foundPos) + "<strong>" +
|
||||
elem.substr(foundPos, entry.length) + "</strong>" + elem.substr(
|
||||
foundPos + entry.length) + "</li>");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
foundPos = instance.options.ignoreCase ?
|
||||
elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) :
|
||||
elem.indexOf(entry, foundPos + 1);
|
||||
|
||||
}
|
||||
}
|
||||
if (partial.length)
|
||||
ret = ret.concat(partial.slice(0, instance.options.choices - ret.length))
|
||||
return "<ul>" + ret.join('') + "</ul>";
|
||||
}
|
||||
}, options || {});
|
||||
}
|
||||
});
|
||||
|
||||
// AJAX in-place editor
|
||||
//
|
||||
// see documentation on http://wiki.script.aculo.us/scriptaculous/show/Ajax.InPlaceEditor
|
||||
|
||||
// Use this if you notice weird scrolling problems on some browsers,
|
||||
// the DOM might be a bit confused when this gets called so do this
|
||||
// waits 1 ms (with setTimeout) until it does the activation
|
||||
Field.scrollFreeActivate = function(field) {
|
||||
setTimeout(function() {
|
||||
Field.activate(field);
|
||||
}, 1);
|
||||
}
|
||||
|
||||
Ajax.InPlaceEditor = Class.create();
|
||||
Ajax.InPlaceEditor.defaultHighlightColor = "#FFFF99";
|
||||
Ajax.InPlaceEditor.prototype = {
|
||||
initialize: function(element, url, options) {
|
||||
this.url = url;
|
||||
this.element = $(element);
|
||||
|
||||
this.options = Object.extend({
|
||||
okText: "ok",
|
||||
cancelText: "cancel",
|
||||
savingText: "Saving...",
|
||||
clickToEditText: "Click to edit",
|
||||
okText: "ok",
|
||||
rows: 1,
|
||||
onComplete: function(transport, element) {
|
||||
new Effect.Highlight(element, {startcolor: this.options.highlightcolor});
|
||||
},
|
||||
onFailure: function(transport) {
|
||||
alert("Error communicating with the server: " + transport.responseText.stripTags());
|
||||
},
|
||||
callback: function(form) {
|
||||
return Form.serialize(form);
|
||||
},
|
||||
handleLineBreaks: true,
|
||||
loadingText: 'Loading...',
|
||||
savingClassName: 'inplaceeditor-saving',
|
||||
loadingClassName: 'inplaceeditor-loading',
|
||||
formClassName: 'inplaceeditor-form',
|
||||
highlightcolor: Ajax.InPlaceEditor.defaultHighlightColor,
|
||||
highlightendcolor: "#FFFFFF",
|
||||
externalControl: null,
|
||||
ajaxOptions: {}
|
||||
}, options || {});
|
||||
|
||||
if(!this.options.formId && this.element.id) {
|
||||
this.options.formId = this.element.id + "-inplaceeditor";
|
||||
if ($(this.options.formId)) {
|
||||
// there's already a form with that name, don't specify an id
|
||||
this.options.formId = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.options.externalControl) {
|
||||
this.options.externalControl = $(this.options.externalControl);
|
||||
}
|
||||
|
||||
this.originalBackground = Element.getStyle(this.element, 'background-color');
|
||||
if (!this.originalBackground) {
|
||||
this.originalBackground = "transparent";
|
||||
}
|
||||
|
||||
this.element.title = this.options.clickToEditText;
|
||||
|
||||
this.onclickListener = this.enterEditMode.bindAsEventListener(this);
|
||||
this.mouseoverListener = this.enterHover.bindAsEventListener(this);
|
||||
this.mouseoutListener = this.leaveHover.bindAsEventListener(this);
|
||||
Event.observe(this.element, 'click', this.onclickListener);
|
||||
Event.observe(this.element, 'mouseover', this.mouseoverListener);
|
||||
Event.observe(this.element, 'mouseout', this.mouseoutListener);
|
||||
if (this.options.externalControl) {
|
||||
Event.observe(this.options.externalControl, 'click', this.onclickListener);
|
||||
Event.observe(this.options.externalControl, 'mouseover', this.mouseoverListener);
|
||||
Event.observe(this.options.externalControl, 'mouseout', this.mouseoutListener);
|
||||
}
|
||||
},
|
||||
enterEditMode: function(evt) {
|
||||
if (this.saving) return;
|
||||
if (this.editing) return;
|
||||
this.editing = true;
|
||||
this.onEnterEditMode();
|
||||
if (this.options.externalControl) {
|
||||
Element.hide(this.options.externalControl);
|
||||
}
|
||||
Element.hide(this.element);
|
||||
this.createForm();
|
||||
this.element.parentNode.insertBefore(this.form, this.element);
|
||||
Field.scrollFreeActivate(this.editField);
|
||||
// stop the event to avoid a page refresh in Safari
|
||||
if (evt) {
|
||||
Event.stop(evt);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
createForm: function() {
|
||||
this.form = document.createElement("form");
|
||||
this.form.id = this.options.formId;
|
||||
Element.addClassName(this.form, this.options.formClassName)
|
||||
this.form.onsubmit = this.onSubmit.bind(this);
|
||||
|
||||
this.createEditField();
|
||||
|
||||
if (this.options.textarea) {
|
||||
var br = document.createElement("br");
|
||||
this.form.appendChild(br);
|
||||
}
|
||||
|
||||
okButton = document.createElement("input");
|
||||
okButton.type = "submit";
|
||||
okButton.value = this.options.okText;
|
||||
this.form.appendChild(okButton);
|
||||
|
||||
cancelLink = document.createElement("a");
|
||||
cancelLink.href = "#";
|
||||
cancelLink.appendChild(document.createTextNode(this.options.cancelText));
|
||||
cancelLink.onclick = this.onclickCancel.bind(this);
|
||||
this.form.appendChild(cancelLink);
|
||||
},
|
||||
hasHTMLLineBreaks: function(string) {
|
||||
if (!this.options.handleLineBreaks) return false;
|
||||
return string.match(/<br/i) || string.match(/<p>/i);
|
||||
},
|
||||
convertHTMLLineBreaks: function(string) {
|
||||
return string.replace(/<br>/gi, "\n").replace(/<br\/>/gi, "\n").replace(/<\/p>/gi, "\n").replace(/<p>/gi, "");
|
||||
},
|
||||
createEditField: function() {
|
||||
var text;
|
||||
if(this.options.loadTextURL) {
|
||||
text = this.options.loadingText;
|
||||
} else {
|
||||
text = this.getText();
|
||||
}
|
||||
|
||||
if (this.options.rows == 1 && !this.hasHTMLLineBreaks(text)) {
|
||||
this.options.textarea = false;
|
||||
var textField = document.createElement("input");
|
||||
textField.type = "text";
|
||||
textField.name = "value";
|
||||
textField.value = text;
|
||||
textField.style.backgroundColor = this.options.highlightcolor;
|
||||
var size = this.options.size || this.options.cols || 0;
|
||||
if (size != 0) textField.size = size;
|
||||
this.editField = textField;
|
||||
} else {
|
||||
this.options.textarea = true;
|
||||
var textArea = document.createElement("textarea");
|
||||
textArea.name = "value";
|
||||
textArea.value = this.convertHTMLLineBreaks(text);
|
||||
textArea.rows = this.options.rows;
|
||||
textArea.cols = this.options.cols || 40;
|
||||
this.editField = textArea;
|
||||
}
|
||||
|
||||
if(this.options.loadTextURL) {
|
||||
this.loadExternalText();
|
||||
}
|
||||
this.form.appendChild(this.editField);
|
||||
},
|
||||
getText: function() {
|
||||
return this.element.innerHTML;
|
||||
},
|
||||
loadExternalText: function() {
|
||||
Element.addClassName(this.form, this.options.loadingClassName);
|
||||
this.editField.disabled = true;
|
||||
new Ajax.Request(
|
||||
this.options.loadTextURL,
|
||||
Object.extend({
|
||||
asynchronous: true,
|
||||
onComplete: this.onLoadedExternalText.bind(this)
|
||||
}, this.options.ajaxOptions)
|
||||
);
|
||||
},
|
||||
onLoadedExternalText: function(transport) {
|
||||
Element.removeClassName(this.form, this.options.loadingClassName);
|
||||
this.editField.disabled = false;
|
||||
this.editField.value = transport.responseText.stripTags();
|
||||
},
|
||||
onclickCancel: function() {
|
||||
this.onComplete();
|
||||
this.leaveEditMode();
|
||||
return false;
|
||||
},
|
||||
onFailure: function(transport) {
|
||||
this.options.onFailure(transport);
|
||||
if (this.oldInnerHTML) {
|
||||
this.element.innerHTML = this.oldInnerHTML;
|
||||
this.oldInnerHTML = null;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
onSubmit: function() {
|
||||
// onLoading resets these so we need to save them away for the Ajax call
|
||||
var form = this.form;
|
||||
var value = this.editField.value;
|
||||
|
||||
// do this first, sometimes the ajax call returns before we get a chance to switch on Saving...
|
||||
// which means this will actually switch on Saving... *after* we've left edit mode causing Saving...
|
||||
// to be displayed indefinitely
|
||||
this.onLoading();
|
||||
|
||||
new Ajax.Updater(
|
||||
{
|
||||
success: this.element,
|
||||
// don't update on failure (this could be an option)
|
||||
failure: null
|
||||
},
|
||||
this.url,
|
||||
Object.extend({
|
||||
parameters: this.options.callback(form, value),
|
||||
onComplete: this.onComplete.bind(this),
|
||||
onFailure: this.onFailure.bind(this)
|
||||
}, this.options.ajaxOptions)
|
||||
);
|
||||
// stop the event to avoid a page refresh in Safari
|
||||
if (arguments.length > 1) {
|
||||
Event.stop(arguments[0]);
|
||||
}
|
||||
return false;
|
||||
},
|
||||
onLoading: function() {
|
||||
this.saving = true;
|
||||
this.removeForm();
|
||||
this.leaveHover();
|
||||
this.showSaving();
|
||||
},
|
||||
showSaving: function() {
|
||||
this.oldInnerHTML = this.element.innerHTML;
|
||||
this.element.innerHTML = this.options.savingText;
|
||||
Element.addClassName(this.element, this.options.savingClassName);
|
||||
this.element.style.backgroundColor = this.originalBackground;
|
||||
Element.show(this.element);
|
||||
},
|
||||
removeForm: function() {
|
||||
if(this.form) {
|
||||
if (this.form.parentNode) Element.remove(this.form);
|
||||
this.form = null;
|
||||
}
|
||||
},
|
||||
enterHover: function() {
|
||||
if (this.saving) return;
|
||||
this.element.style.backgroundColor = this.options.highlightcolor;
|
||||
if (this.effect) {
|
||||
this.effect.cancel();
|
||||
}
|
||||
Element.addClassName(this.element, this.options.hoverClassName)
|
||||
},
|
||||
leaveHover: function() {
|
||||
if (this.options.backgroundColor) {
|
||||
this.element.style.backgroundColor = this.oldBackground;
|
||||
}
|
||||
Element.removeClassName(this.element, this.options.hoverClassName)
|
||||
if (this.saving) return;
|
||||
this.effect = new Effect.Highlight(this.element, {
|
||||
startcolor: this.options.highlightcolor,
|
||||
endcolor: this.options.highlightendcolor,
|
||||
restorecolor: this.originalBackground
|
||||
});
|
||||
},
|
||||
leaveEditMode: function() {
|
||||
Element.removeClassName(this.element, this.options.savingClassName);
|
||||
this.removeForm();
|
||||
this.leaveHover();
|
||||
this.element.style.backgroundColor = this.originalBackground;
|
||||
Element.show(this.element);
|
||||
if (this.options.externalControl) {
|
||||
Element.show(this.options.externalControl);
|
||||
}
|
||||
this.editing = false;
|
||||
this.saving = false;
|
||||
this.oldInnerHTML = null;
|
||||
this.onLeaveEditMode();
|
||||
},
|
||||
onComplete: function(transport) {
|
||||
this.leaveEditMode();
|
||||
this.options.onComplete.bind(this)(transport, this.element);
|
||||
},
|
||||
onEnterEditMode: function() {},
|
||||
onLeaveEditMode: function() {},
|
||||
dispose: function() {
|
||||
if (this.oldInnerHTML) {
|
||||
this.element.innerHTML = this.oldInnerHTML;
|
||||
}
|
||||
this.leaveEditMode();
|
||||
Event.stopObserving(this.element, 'click', this.onclickListener);
|
||||
Event.stopObserving(this.element, 'mouseover', this.mouseoverListener);
|
||||
Event.stopObserving(this.element, 'mouseout', this.mouseoutListener);
|
||||
if (this.options.externalControl) {
|
||||
Event.stopObserving(this.options.externalControl, 'click', this.onclickListener);
|
||||
Event.stopObserving(this.options.externalControl, 'mouseover', this.mouseoverListener);
|
||||
Event.stopObserving(this.options.externalControl, 'mouseout', this.mouseoutListener);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Delayed observer, like Form.Element.Observer,
|
||||
// but waits for delay after last key input
|
||||
// Ideal for live-search fields
|
||||
|
||||
Form.Element.DelayedObserver = Class.create();
|
||||
Form.Element.DelayedObserver.prototype = {
|
||||
initialize: function(element, delay, callback) {
|
||||
this.delay = delay || 0.5;
|
||||
this.element = $(element);
|
||||
this.callback = callback;
|
||||
this.timer = null;
|
||||
this.lastValue = $F(this.element);
|
||||
Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this));
|
||||
},
|
||||
delayedListener: function(event) {
|
||||
if(this.lastValue == $F(this.element)) return;
|
||||
if(this.timer) clearTimeout(this.timer);
|
||||
this.timer = setTimeout(this.onTimerEvent.bind(this), this.delay * 1000);
|
||||
this.lastValue = $F(this.element);
|
||||
},
|
||||
onTimerEvent: function() {
|
||||
this.timer = null;
|
||||
this.callback(this.element, $F(this.element));
|
||||
}
|
||||
};
|
||||
584
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/public/javascripts/dragdrop.js
vendored
Normal file
584
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/public/javascripts/dragdrop.js
vendored
Normal file
@@ -0,0 +1,584 @@
|
||||
// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
|
||||
//
|
||||
// See scriptaculous.js for full license.
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
var Droppables = {
|
||||
drops: [],
|
||||
|
||||
remove: function(element) {
|
||||
this.drops = this.drops.reject(function(d) { return d.element==$(element) });
|
||||
},
|
||||
|
||||
add: function(element) {
|
||||
element = $(element);
|
||||
var options = Object.extend({
|
||||
greedy: true,
|
||||
hoverclass: null
|
||||
}, arguments[1] || {});
|
||||
|
||||
// cache containers
|
||||
if(options.containment) {
|
||||
options._containers = [];
|
||||
var containment = options.containment;
|
||||
if((typeof containment == 'object') &&
|
||||
(containment.constructor == Array)) {
|
||||
containment.each( function(c) { options._containers.push($(c)) });
|
||||
} else {
|
||||
options._containers.push($(containment));
|
||||
}
|
||||
}
|
||||
|
||||
if(options.accept) options.accept = [options.accept].flatten();
|
||||
|
||||
Element.makePositioned(element); // fix IE
|
||||
options.element = element;
|
||||
|
||||
this.drops.push(options);
|
||||
},
|
||||
|
||||
isContained: function(element, drop) {
|
||||
var parentNode = element.parentNode;
|
||||
return drop._containers.detect(function(c) { return parentNode == c });
|
||||
},
|
||||
|
||||
isAffected: function(point, element, drop) {
|
||||
return (
|
||||
(drop.element!=element) &&
|
||||
((!drop._containers) ||
|
||||
this.isContained(element, drop)) &&
|
||||
((!drop.accept) ||
|
||||
(Element.classNames(element).detect(
|
||||
function(v) { return drop.accept.include(v) } ) )) &&
|
||||
Position.within(drop.element, point[0], point[1]) );
|
||||
},
|
||||
|
||||
deactivate: function(drop) {
|
||||
if(drop.hoverclass)
|
||||
Element.removeClassName(drop.element, drop.hoverclass);
|
||||
this.last_active = null;
|
||||
},
|
||||
|
||||
activate: function(drop) {
|
||||
if(drop.hoverclass)
|
||||
Element.addClassName(drop.element, drop.hoverclass);
|
||||
this.last_active = drop;
|
||||
},
|
||||
|
||||
show: function(point, element) {
|
||||
if(!this.drops.length) return;
|
||||
|
||||
if(this.last_active) this.deactivate(this.last_active);
|
||||
this.drops.each( function(drop) {
|
||||
if(Droppables.isAffected(point, element, drop)) {
|
||||
if(drop.onHover)
|
||||
drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element));
|
||||
if(drop.greedy) {
|
||||
Droppables.activate(drop);
|
||||
throw $break;
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
fire: function(event, element) {
|
||||
if(!this.last_active) return;
|
||||
Position.prepare();
|
||||
|
||||
if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active))
|
||||
if (this.last_active.onDrop)
|
||||
this.last_active.onDrop(element, this.last_active.element, event);
|
||||
},
|
||||
|
||||
reset: function() {
|
||||
if(this.last_active)
|
||||
this.deactivate(this.last_active);
|
||||
}
|
||||
}
|
||||
|
||||
var Draggables = {
|
||||
drags: [],
|
||||
observers: [],
|
||||
|
||||
register: function(draggable) {
|
||||
if(this.drags.length == 0) {
|
||||
this.eventMouseUp = this.endDrag.bindAsEventListener(this);
|
||||
this.eventMouseMove = this.updateDrag.bindAsEventListener(this);
|
||||
this.eventKeypress = this.keyPress.bindAsEventListener(this);
|
||||
|
||||
Event.observe(document, "mouseup", this.eventMouseUp);
|
||||
Event.observe(document, "mousemove", this.eventMouseMove);
|
||||
Event.observe(document, "keypress", this.eventKeypress);
|
||||
}
|
||||
this.drags.push(draggable);
|
||||
},
|
||||
|
||||
unregister: function(draggable) {
|
||||
this.drags = this.drags.reject(function(d) { return d==draggable });
|
||||
if(this.drags.length == 0) {
|
||||
Event.stopObserving(document, "mouseup", this.eventMouseUp);
|
||||
Event.stopObserving(document, "mousemove", this.eventMouseMove);
|
||||
Event.stopObserving(document, "keypress", this.eventKeypress);
|
||||
}
|
||||
},
|
||||
|
||||
activate: function(draggable) {
|
||||
window.focus(); // allows keypress events if window isn't currently focused, fails for Safari
|
||||
this.activeDraggable = draggable;
|
||||
},
|
||||
|
||||
deactivate: function(draggbale) {
|
||||
this.activeDraggable = null;
|
||||
},
|
||||
|
||||
updateDrag: function(event) {
|
||||
if(!this.activeDraggable) return;
|
||||
var pointer = [Event.pointerX(event), Event.pointerY(event)];
|
||||
// Mozilla-based browsers fire successive mousemove events with
|
||||
// the same coordinates, prevent needless redrawing (moz bug?)
|
||||
if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return;
|
||||
this._lastPointer = pointer;
|
||||
this.activeDraggable.updateDrag(event, pointer);
|
||||
},
|
||||
|
||||
endDrag: function(event) {
|
||||
if(!this.activeDraggable) return;
|
||||
this._lastPointer = null;
|
||||
this.activeDraggable.endDrag(event);
|
||||
},
|
||||
|
||||
keyPress: function(event) {
|
||||
if(this.activeDraggable)
|
||||
this.activeDraggable.keyPress(event);
|
||||
},
|
||||
|
||||
addObserver: function(observer) {
|
||||
this.observers.push(observer);
|
||||
this._cacheObserverCallbacks();
|
||||
},
|
||||
|
||||
removeObserver: function(element) { // element instead of observer fixes mem leaks
|
||||
this.observers = this.observers.reject( function(o) { return o.element==element });
|
||||
this._cacheObserverCallbacks();
|
||||
},
|
||||
|
||||
notify: function(eventName, draggable, event) { // 'onStart', 'onEnd', 'onDrag'
|
||||
if(this[eventName+'Count'] > 0)
|
||||
this.observers.each( function(o) {
|
||||
if(o[eventName]) o[eventName](eventName, draggable, event);
|
||||
});
|
||||
},
|
||||
|
||||
_cacheObserverCallbacks: function() {
|
||||
['onStart','onEnd','onDrag'].each( function(eventName) {
|
||||
Draggables[eventName+'Count'] = Draggables.observers.select(
|
||||
function(o) { return o[eventName]; }
|
||||
).length;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
var Draggable = Class.create();
|
||||
Draggable.prototype = {
|
||||
initialize: function(element) {
|
||||
var options = Object.extend({
|
||||
handle: false,
|
||||
starteffect: function(element) {
|
||||
new Effect.Opacity(element, {duration:0.2, from:1.0, to:0.7});
|
||||
},
|
||||
reverteffect: function(element, top_offset, left_offset) {
|
||||
var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02;
|
||||
element._revert = new Effect.MoveBy(element, -top_offset, -left_offset, {duration:dur});
|
||||
},
|
||||
endeffect: function(element) {
|
||||
new Effect.Opacity(element, {duration:0.2, from:0.7, to:1.0});
|
||||
},
|
||||
zindex: 1000,
|
||||
revert: false,
|
||||
snap: false // false, or xy or [x,y] or function(x,y){ return [x,y] }
|
||||
}, arguments[1] || {});
|
||||
|
||||
this.element = $(element);
|
||||
|
||||
if(options.handle && (typeof options.handle == 'string'))
|
||||
this.handle = Element.childrenWithClassName(this.element, options.handle)[0];
|
||||
if(!this.handle) this.handle = $(options.handle);
|
||||
if(!this.handle) this.handle = this.element;
|
||||
|
||||
Element.makePositioned(this.element); // fix IE
|
||||
|
||||
this.delta = this.currentDelta();
|
||||
this.options = options;
|
||||
this.dragging = false;
|
||||
|
||||
this.eventMouseDown = this.initDrag.bindAsEventListener(this);
|
||||
Event.observe(this.handle, "mousedown", this.eventMouseDown);
|
||||
|
||||
Draggables.register(this);
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
Event.stopObserving(this.handle, "mousedown", this.eventMouseDown);
|
||||
Draggables.unregister(this);
|
||||
},
|
||||
|
||||
currentDelta: function() {
|
||||
return([
|
||||
parseInt(this.element.style.left || '0'),
|
||||
parseInt(this.element.style.top || '0')]);
|
||||
},
|
||||
|
||||
initDrag: function(event) {
|
||||
if(Event.isLeftClick(event)) {
|
||||
// abort on form elements, fixes a Firefox issue
|
||||
var src = Event.element(event);
|
||||
if(src.tagName && (
|
||||
src.tagName=='INPUT' ||
|
||||
src.tagName=='SELECT' ||
|
||||
src.tagName=='BUTTON' ||
|
||||
src.tagName=='TEXTAREA')) return;
|
||||
|
||||
if(this.element._revert) {
|
||||
this.element._revert.cancel();
|
||||
this.element._revert = null;
|
||||
}
|
||||
|
||||
var pointer = [Event.pointerX(event), Event.pointerY(event)];
|
||||
var pos = Position.cumulativeOffset(this.element);
|
||||
this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) });
|
||||
|
||||
Draggables.activate(this);
|
||||
Event.stop(event);
|
||||
}
|
||||
},
|
||||
|
||||
startDrag: function(event) {
|
||||
this.dragging = true;
|
||||
|
||||
if(this.options.zindex) {
|
||||
this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0);
|
||||
this.element.style.zIndex = this.options.zindex;
|
||||
}
|
||||
|
||||
if(this.options.ghosting) {
|
||||
this._clone = this.element.cloneNode(true);
|
||||
Position.absolutize(this.element);
|
||||
this.element.parentNode.insertBefore(this._clone, this.element);
|
||||
}
|
||||
|
||||
Draggables.notify('onStart', this, event);
|
||||
if(this.options.starteffect) this.options.starteffect(this.element);
|
||||
},
|
||||
|
||||
updateDrag: function(event, pointer) {
|
||||
if(!this.dragging) this.startDrag(event);
|
||||
Position.prepare();
|
||||
Droppables.show(pointer, this.element);
|
||||
Draggables.notify('onDrag', this, event);
|
||||
this.draw(pointer);
|
||||
if(this.options.change) this.options.change(this);
|
||||
|
||||
// fix AppleWebKit rendering
|
||||
if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
|
||||
Event.stop(event);
|
||||
},
|
||||
|
||||
finishDrag: function(event, success) {
|
||||
this.dragging = false;
|
||||
|
||||
if(this.options.ghosting) {
|
||||
Position.relativize(this.element);
|
||||
Element.remove(this._clone);
|
||||
this._clone = null;
|
||||
}
|
||||
|
||||
if(success) Droppables.fire(event, this.element);
|
||||
Draggables.notify('onEnd', this, event);
|
||||
|
||||
var revert = this.options.revert;
|
||||
if(revert && typeof revert == 'function') revert = revert(this.element);
|
||||
|
||||
var d = this.currentDelta();
|
||||
if(revert && this.options.reverteffect) {
|
||||
this.options.reverteffect(this.element,
|
||||
d[1]-this.delta[1], d[0]-this.delta[0]);
|
||||
} else {
|
||||
this.delta = d;
|
||||
}
|
||||
|
||||
if(this.options.zindex)
|
||||
this.element.style.zIndex = this.originalZ;
|
||||
|
||||
if(this.options.endeffect)
|
||||
this.options.endeffect(this.element);
|
||||
|
||||
Draggables.deactivate(this);
|
||||
Droppables.reset();
|
||||
},
|
||||
|
||||
keyPress: function(event) {
|
||||
if(!event.keyCode==Event.KEY_ESC) return;
|
||||
this.finishDrag(event, false);
|
||||
Event.stop(event);
|
||||
},
|
||||
|
||||
endDrag: function(event) {
|
||||
if(!this.dragging) return;
|
||||
this.finishDrag(event, true);
|
||||
Event.stop(event);
|
||||
},
|
||||
|
||||
draw: function(point) {
|
||||
var pos = Position.cumulativeOffset(this.element);
|
||||
var d = this.currentDelta();
|
||||
pos[0] -= d[0]; pos[1] -= d[1];
|
||||
|
||||
var p = [0,1].map(function(i){ return (point[i]-pos[i]-this.offset[i]) }.bind(this));
|
||||
|
||||
if(this.options.snap) {
|
||||
if(typeof this.options.snap == 'function') {
|
||||
p = this.options.snap(p[0],p[1]);
|
||||
} else {
|
||||
if(this.options.snap instanceof Array) {
|
||||
p = p.map( function(v, i) {
|
||||
return Math.round(v/this.options.snap[i])*this.options.snap[i] }.bind(this))
|
||||
} else {
|
||||
p = p.map( function(v) {
|
||||
return Math.round(v/this.options.snap)*this.options.snap }.bind(this))
|
||||
}
|
||||
}}
|
||||
|
||||
var style = this.element.style;
|
||||
if((!this.options.constraint) || (this.options.constraint=='horizontal'))
|
||||
style.left = p[0] + "px";
|
||||
if((!this.options.constraint) || (this.options.constraint=='vertical'))
|
||||
style.top = p[1] + "px";
|
||||
if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
var SortableObserver = Class.create();
|
||||
SortableObserver.prototype = {
|
||||
initialize: function(element, observer) {
|
||||
this.element = $(element);
|
||||
this.observer = observer;
|
||||
this.lastValue = Sortable.serialize(this.element);
|
||||
},
|
||||
|
||||
onStart: function() {
|
||||
this.lastValue = Sortable.serialize(this.element);
|
||||
},
|
||||
|
||||
onEnd: function() {
|
||||
Sortable.unmark();
|
||||
if(this.lastValue != Sortable.serialize(this.element))
|
||||
this.observer(this.element)
|
||||
}
|
||||
}
|
||||
|
||||
var Sortable = {
|
||||
sortables: new Array(),
|
||||
|
||||
options: function(element){
|
||||
element = $(element);
|
||||
return this.sortables.detect(function(s) { return s.element == element });
|
||||
},
|
||||
|
||||
destroy: function(element){
|
||||
element = $(element);
|
||||
this.sortables.findAll(function(s) { return s.element == element }).each(function(s){
|
||||
Draggables.removeObserver(s.element);
|
||||
s.droppables.each(function(d){ Droppables.remove(d) });
|
||||
s.draggables.invoke('destroy');
|
||||
});
|
||||
this.sortables = this.sortables.reject(function(s) { return s.element == element });
|
||||
},
|
||||
|
||||
create: function(element) {
|
||||
element = $(element);
|
||||
var options = Object.extend({
|
||||
element: element,
|
||||
tag: 'li', // assumes li children, override with tag: 'tagname'
|
||||
dropOnEmpty: false,
|
||||
tree: false, // fixme: unimplemented
|
||||
overlap: 'vertical', // one of 'vertical', 'horizontal'
|
||||
constraint: 'vertical', // one of 'vertical', 'horizontal', false
|
||||
containment: element, // also takes array of elements (or id's); or false
|
||||
handle: false, // or a CSS class
|
||||
only: false,
|
||||
hoverclass: null,
|
||||
ghosting: false,
|
||||
format: null,
|
||||
onChange: Prototype.emptyFunction,
|
||||
onUpdate: Prototype.emptyFunction
|
||||
}, arguments[1] || {});
|
||||
|
||||
// clear any old sortable with same element
|
||||
this.destroy(element);
|
||||
|
||||
// build options for the draggables
|
||||
var options_for_draggable = {
|
||||
revert: true,
|
||||
ghosting: options.ghosting,
|
||||
constraint: options.constraint,
|
||||
handle: options.handle };
|
||||
|
||||
if(options.starteffect)
|
||||
options_for_draggable.starteffect = options.starteffect;
|
||||
|
||||
if(options.reverteffect)
|
||||
options_for_draggable.reverteffect = options.reverteffect;
|
||||
else
|
||||
if(options.ghosting) options_for_draggable.reverteffect = function(element) {
|
||||
element.style.top = 0;
|
||||
element.style.left = 0;
|
||||
};
|
||||
|
||||
if(options.endeffect)
|
||||
options_for_draggable.endeffect = options.endeffect;
|
||||
|
||||
if(options.zindex)
|
||||
options_for_draggable.zindex = options.zindex;
|
||||
|
||||
// build options for the droppables
|
||||
var options_for_droppable = {
|
||||
overlap: options.overlap,
|
||||
containment: options.containment,
|
||||
hoverclass: options.hoverclass,
|
||||
onHover: Sortable.onHover,
|
||||
greedy: !options.dropOnEmpty
|
||||
}
|
||||
|
||||
// fix for gecko engine
|
||||
Element.cleanWhitespace(element);
|
||||
|
||||
options.draggables = [];
|
||||
options.droppables = [];
|
||||
|
||||
// make it so
|
||||
|
||||
// drop on empty handling
|
||||
if(options.dropOnEmpty) {
|
||||
Droppables.add(element,
|
||||
{containment: options.containment, onHover: Sortable.onEmptyHover, greedy: false});
|
||||
options.droppables.push(element);
|
||||
}
|
||||
|
||||
(this.findElements(element, options) || []).each( function(e) {
|
||||
// handles are per-draggable
|
||||
var handle = options.handle ?
|
||||
Element.childrenWithClassName(e, options.handle)[0] : e;
|
||||
options.draggables.push(
|
||||
new Draggable(e, Object.extend(options_for_draggable, { handle: handle })));
|
||||
Droppables.add(e, options_for_droppable);
|
||||
options.droppables.push(e);
|
||||
});
|
||||
|
||||
// keep reference
|
||||
this.sortables.push(options);
|
||||
|
||||
// for onupdate
|
||||
Draggables.addObserver(new SortableObserver(element, options.onUpdate));
|
||||
|
||||
},
|
||||
|
||||
// return all suitable-for-sortable elements in a guaranteed order
|
||||
findElements: function(element, options) {
|
||||
if(!element.hasChildNodes()) return null;
|
||||
var elements = [];
|
||||
$A(element.childNodes).each( function(e) {
|
||||
if(e.tagName && e.tagName.toUpperCase()==options.tag.toUpperCase() &&
|
||||
(!options.only || (Element.hasClassName(e, options.only))))
|
||||
elements.push(e);
|
||||
if(options.tree) {
|
||||
var grandchildren = this.findElements(e, options);
|
||||
if(grandchildren) elements.push(grandchildren);
|
||||
}
|
||||
});
|
||||
|
||||
return (elements.length>0 ? elements.flatten() : null);
|
||||
},
|
||||
|
||||
onHover: function(element, dropon, overlap) {
|
||||
if(overlap>0.5) {
|
||||
Sortable.mark(dropon, 'before');
|
||||
if(dropon.previousSibling != element) {
|
||||
var oldParentNode = element.parentNode;
|
||||
element.style.visibility = "hidden"; // fix gecko rendering
|
||||
dropon.parentNode.insertBefore(element, dropon);
|
||||
if(dropon.parentNode!=oldParentNode)
|
||||
Sortable.options(oldParentNode).onChange(element);
|
||||
Sortable.options(dropon.parentNode).onChange(element);
|
||||
}
|
||||
} else {
|
||||
Sortable.mark(dropon, 'after');
|
||||
var nextElement = dropon.nextSibling || null;
|
||||
if(nextElement != element) {
|
||||
var oldParentNode = element.parentNode;
|
||||
element.style.visibility = "hidden"; // fix gecko rendering
|
||||
dropon.parentNode.insertBefore(element, nextElement);
|
||||
if(dropon.parentNode!=oldParentNode)
|
||||
Sortable.options(oldParentNode).onChange(element);
|
||||
Sortable.options(dropon.parentNode).onChange(element);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
onEmptyHover: function(element, dropon) {
|
||||
if(element.parentNode!=dropon) {
|
||||
var oldParentNode = element.parentNode;
|
||||
dropon.appendChild(element);
|
||||
Sortable.options(oldParentNode).onChange(element);
|
||||
Sortable.options(dropon).onChange(element);
|
||||
}
|
||||
},
|
||||
|
||||
unmark: function() {
|
||||
if(Sortable._marker) Element.hide(Sortable._marker);
|
||||
},
|
||||
|
||||
mark: function(dropon, position) {
|
||||
// mark on ghosting only
|
||||
var sortable = Sortable.options(dropon.parentNode);
|
||||
if(sortable && !sortable.ghosting) return;
|
||||
|
||||
if(!Sortable._marker) {
|
||||
Sortable._marker = $('dropmarker') || document.createElement('DIV');
|
||||
Element.hide(Sortable._marker);
|
||||
Element.addClassName(Sortable._marker, 'dropmarker');
|
||||
Sortable._marker.style.position = 'absolute';
|
||||
document.getElementsByTagName("body").item(0).appendChild(Sortable._marker);
|
||||
}
|
||||
var offsets = Position.cumulativeOffset(dropon);
|
||||
Sortable._marker.style.left = offsets[0] + 'px';
|
||||
Sortable._marker.style.top = offsets[1] + 'px';
|
||||
|
||||
if(position=='after')
|
||||
if(sortable.overlap == 'horizontal')
|
||||
Sortable._marker.style.left = (offsets[0]+dropon.clientWidth) + 'px';
|
||||
else
|
||||
Sortable._marker.style.top = (offsets[1]+dropon.clientHeight) + 'px';
|
||||
|
||||
Element.show(Sortable._marker);
|
||||
},
|
||||
|
||||
serialize: function(element) {
|
||||
element = $(element);
|
||||
var sortableOptions = this.options(element);
|
||||
var options = Object.extend({
|
||||
tag: sortableOptions.tag,
|
||||
only: sortableOptions.only,
|
||||
name: element.id,
|
||||
format: sortableOptions.format || /^[^_]*_(.*)$/
|
||||
}, arguments[1] || {});
|
||||
return $(this.findElements(element, options) || []).map( function(item) {
|
||||
return (encodeURIComponent(options.name) + "[]=" +
|
||||
encodeURIComponent(item.id.match(options.format) ? item.id.match(options.format)[1] : ''));
|
||||
}).join("&");
|
||||
}
|
||||
}
|
||||
854
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/public/javascripts/effects.js
vendored
Normal file
854
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/public/javascripts/effects.js
vendored
Normal file
@@ -0,0 +1,854 @@
|
||||
// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
|
||||
// Contributors:
|
||||
// Justin Palmer (http://encytemedia.com/)
|
||||
// Mark Pilgrim (http://diveintomark.org/)
|
||||
// Martin Bialasinki
|
||||
//
|
||||
// See scriptaculous.js for full license.
|
||||
|
||||
/* ------------- element ext -------------- */
|
||||
|
||||
// converts rgb() and #xxx to #xxxxxx format,
|
||||
// returns self (or first argument) if not convertable
|
||||
String.prototype.parseColor = function() {
|
||||
var color = '#';
|
||||
if(this.slice(0,4) == 'rgb(') {
|
||||
var cols = this.slice(4,this.length-1).split(',');
|
||||
var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);
|
||||
} else {
|
||||
if(this.slice(0,1) == '#') {
|
||||
if(this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();
|
||||
if(this.length==7) color = this.toLowerCase();
|
||||
}
|
||||
}
|
||||
return(color.length==7 ? color : (arguments[0] || this));
|
||||
}
|
||||
|
||||
Element.collectTextNodesIgnoreClass = function(element, ignoreclass) {
|
||||
var children = $(element).childNodes;
|
||||
var text = '';
|
||||
var classtest = new RegExp('^([^ ]+ )*' + ignoreclass+ '( [^ ]+)*$','i');
|
||||
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
if(children[i].nodeType==3) {
|
||||
text+=children[i].nodeValue;
|
||||
} else {
|
||||
if((!children[i].className.match(classtest)) && children[i].hasChildNodes())
|
||||
text += Element.collectTextNodesIgnoreClass(children[i], ignoreclass);
|
||||
}
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
Element.setStyle = function(element, style) {
|
||||
element = $(element);
|
||||
for(k in style) element.style[k.camelize()] = style[k];
|
||||
}
|
||||
|
||||
Element.setContentZoom = function(element, percent) {
|
||||
Element.setStyle(element, {fontSize: (percent/100) + 'em'});
|
||||
if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
|
||||
}
|
||||
|
||||
Element.getOpacity = function(element){
|
||||
var opacity;
|
||||
if (opacity = Element.getStyle(element, 'opacity'))
|
||||
return parseFloat(opacity);
|
||||
if (opacity = (Element.getStyle(element, 'filter') || '').match(/alpha\(opacity=(.*)\)/))
|
||||
if(opacity[1]) return parseFloat(opacity[1]) / 100;
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
Element.setOpacity = function(element, value){
|
||||
element= $(element);
|
||||
if (value == 1){
|
||||
Element.setStyle(element, { opacity:
|
||||
(/Gecko/.test(navigator.userAgent) && !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ?
|
||||
0.999999 : null });
|
||||
if(/MSIE/.test(navigator.userAgent))
|
||||
Element.setStyle(element, {filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'')});
|
||||
} else {
|
||||
if(value < 0.00001) value = 0;
|
||||
Element.setStyle(element, {opacity: value});
|
||||
if(/MSIE/.test(navigator.userAgent))
|
||||
Element.setStyle(element,
|
||||
{ filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'') +
|
||||
'alpha(opacity='+value*100+')' });
|
||||
}
|
||||
}
|
||||
|
||||
Element.getInlineOpacity = function(element){
|
||||
return $(element).style.opacity || '';
|
||||
}
|
||||
|
||||
Element.childrenWithClassName = function(element, className) {
|
||||
return $A($(element).getElementsByTagName('*')).select(
|
||||
function(c) { return Element.hasClassName(c, className) });
|
||||
}
|
||||
|
||||
Array.prototype.call = function() {
|
||||
var args = arguments;
|
||||
this.each(function(f){ f.apply(this, args) });
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
var Effect = {
|
||||
tagifyText: function(element) {
|
||||
var tagifyStyle = 'position:relative';
|
||||
if(/MSIE/.test(navigator.userAgent)) tagifyStyle += ';zoom:1';
|
||||
element = $(element);
|
||||
$A(element.childNodes).each( function(child) {
|
||||
if(child.nodeType==3) {
|
||||
child.nodeValue.toArray().each( function(character) {
|
||||
element.insertBefore(
|
||||
Builder.node('span',{style: tagifyStyle},
|
||||
character == ' ' ? String.fromCharCode(160) : character),
|
||||
child);
|
||||
});
|
||||
Element.remove(child);
|
||||
}
|
||||
});
|
||||
},
|
||||
multiple: function(element, effect) {
|
||||
var elements;
|
||||
if(((typeof element == 'object') ||
|
||||
(typeof element == 'function')) &&
|
||||
(element.length))
|
||||
elements = element;
|
||||
else
|
||||
elements = $(element).childNodes;
|
||||
|
||||
var options = Object.extend({
|
||||
speed: 0.1,
|
||||
delay: 0.0
|
||||
}, arguments[2] || {});
|
||||
var masterDelay = options.delay;
|
||||
|
||||
$A(elements).each( function(element, index) {
|
||||
new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay }));
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
var Effect2 = Effect; // deprecated
|
||||
|
||||
/* ------------- transitions ------------- */
|
||||
|
||||
Effect.Transitions = {}
|
||||
|
||||
Effect.Transitions.linear = function(pos) {
|
||||
return pos;
|
||||
}
|
||||
Effect.Transitions.sinoidal = function(pos) {
|
||||
return (-Math.cos(pos*Math.PI)/2) + 0.5;
|
||||
}
|
||||
Effect.Transitions.reverse = function(pos) {
|
||||
return 1-pos;
|
||||
}
|
||||
Effect.Transitions.flicker = function(pos) {
|
||||
return ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4;
|
||||
}
|
||||
Effect.Transitions.wobble = function(pos) {
|
||||
return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5;
|
||||
}
|
||||
Effect.Transitions.pulse = function(pos) {
|
||||
return (Math.floor(pos*10) % 2 == 0 ?
|
||||
(pos*10-Math.floor(pos*10)) : 1-(pos*10-Math.floor(pos*10)));
|
||||
}
|
||||
Effect.Transitions.none = function(pos) {
|
||||
return 0;
|
||||
}
|
||||
Effect.Transitions.full = function(pos) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ------------- core effects ------------- */
|
||||
|
||||
Effect.Queue = {
|
||||
effects: [],
|
||||
_each: function(iterator) {
|
||||
this.effects._each(iterator);
|
||||
},
|
||||
interval: null,
|
||||
add: function(effect) {
|
||||
var timestamp = new Date().getTime();
|
||||
|
||||
switch(effect.options.queue) {
|
||||
case 'front':
|
||||
// move unstarted effects after this effect
|
||||
this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) {
|
||||
e.startOn += effect.finishOn;
|
||||
e.finishOn += effect.finishOn;
|
||||
});
|
||||
break;
|
||||
case 'end':
|
||||
// start effect after last queued effect has finished
|
||||
timestamp = this.effects.pluck('finishOn').max() || timestamp;
|
||||
break;
|
||||
}
|
||||
|
||||
effect.startOn += timestamp;
|
||||
effect.finishOn += timestamp;
|
||||
this.effects.push(effect);
|
||||
if(!this.interval)
|
||||
this.interval = setInterval(this.loop.bind(this), 40);
|
||||
},
|
||||
remove: function(effect) {
|
||||
this.effects = this.effects.reject(function(e) { return e==effect });
|
||||
if(this.effects.length == 0) {
|
||||
clearInterval(this.interval);
|
||||
this.interval = null;
|
||||
}
|
||||
},
|
||||
loop: function() {
|
||||
var timePos = new Date().getTime();
|
||||
this.effects.invoke('loop', timePos);
|
||||
}
|
||||
}
|
||||
Object.extend(Effect.Queue, Enumerable);
|
||||
|
||||
Effect.Base = function() {};
|
||||
Effect.Base.prototype = {
|
||||
position: null,
|
||||
setOptions: function(options) {
|
||||
this.options = Object.extend({
|
||||
transition: Effect.Transitions.sinoidal,
|
||||
duration: 1.0, // seconds
|
||||
fps: 25.0, // max. 25fps due to Effect.Queue implementation
|
||||
sync: false, // true for combining
|
||||
from: 0.0,
|
||||
to: 1.0,
|
||||
delay: 0.0,
|
||||
queue: 'parallel'
|
||||
}, options || {});
|
||||
},
|
||||
start: function(options) {
|
||||
this.setOptions(options || {});
|
||||
this.currentFrame = 0;
|
||||
this.state = 'idle';
|
||||
this.startOn = this.options.delay*1000;
|
||||
this.finishOn = this.startOn + (this.options.duration*1000);
|
||||
this.event('beforeStart');
|
||||
if(!this.options.sync) Effect.Queue.add(this);
|
||||
},
|
||||
loop: function(timePos) {
|
||||
if(timePos >= this.startOn) {
|
||||
if(timePos >= this.finishOn) {
|
||||
this.render(1.0);
|
||||
this.cancel();
|
||||
this.event('beforeFinish');
|
||||
if(this.finish) this.finish();
|
||||
this.event('afterFinish');
|
||||
return;
|
||||
}
|
||||
var pos = (timePos - this.startOn) / (this.finishOn - this.startOn);
|
||||
var frame = Math.round(pos * this.options.fps * this.options.duration);
|
||||
if(frame > this.currentFrame) {
|
||||
this.render(pos);
|
||||
this.currentFrame = frame;
|
||||
}
|
||||
}
|
||||
},
|
||||
render: function(pos) {
|
||||
if(this.state == 'idle') {
|
||||
this.state = 'running';
|
||||
this.event('beforeSetup');
|
||||
if(this.setup) this.setup();
|
||||
this.event('afterSetup');
|
||||
}
|
||||
if(this.state == 'running') {
|
||||
if(this.options.transition) pos = this.options.transition(pos);
|
||||
pos *= (this.options.to-this.options.from);
|
||||
pos += this.options.from;
|
||||
this.position = pos;
|
||||
this.event('beforeUpdate');
|
||||
if(this.update) this.update(pos);
|
||||
this.event('afterUpdate');
|
||||
}
|
||||
},
|
||||
cancel: function() {
|
||||
if(!this.options.sync) Effect.Queue.remove(this);
|
||||
this.state = 'finished';
|
||||
},
|
||||
event: function(eventName) {
|
||||
if(this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this);
|
||||
if(this.options[eventName]) this.options[eventName](this);
|
||||
},
|
||||
inspect: function() {
|
||||
return '#<Effect:' + $H(this).inspect() + ',options:' + $H(this.options).inspect() + '>';
|
||||
}
|
||||
}
|
||||
|
||||
Effect.Parallel = Class.create();
|
||||
Object.extend(Object.extend(Effect.Parallel.prototype, Effect.Base.prototype), {
|
||||
initialize: function(effects) {
|
||||
this.effects = effects || [];
|
||||
this.start(arguments[1]);
|
||||
},
|
||||
update: function(position) {
|
||||
this.effects.invoke('render', position);
|
||||
},
|
||||
finish: function(position) {
|
||||
this.effects.each( function(effect) {
|
||||
effect.render(1.0);
|
||||
effect.cancel();
|
||||
effect.event('beforeFinish');
|
||||
if(effect.finish) effect.finish(position);
|
||||
effect.event('afterFinish');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
Effect.Opacity = Class.create();
|
||||
Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), {
|
||||
initialize: function(element) {
|
||||
this.element = $(element);
|
||||
// make this work on IE on elements without 'layout'
|
||||
if(/MSIE/.test(navigator.userAgent) && (!this.element.hasLayout))
|
||||
Element.setStyle(this.element, {zoom: 1});
|
||||
var options = Object.extend({
|
||||
from: Element.getOpacity(this.element) || 0.0,
|
||||
to: 1.0
|
||||
}, arguments[1] || {});
|
||||
this.start(options);
|
||||
},
|
||||
update: function(position) {
|
||||
Element.setOpacity(this.element, position);
|
||||
}
|
||||
});
|
||||
|
||||
Effect.MoveBy = Class.create();
|
||||
Object.extend(Object.extend(Effect.MoveBy.prototype, Effect.Base.prototype), {
|
||||
initialize: function(element, toTop, toLeft) {
|
||||
this.element = $(element);
|
||||
this.toTop = toTop;
|
||||
this.toLeft = toLeft;
|
||||
this.start(arguments[3]);
|
||||
},
|
||||
setup: function() {
|
||||
// Bug in Opera: Opera returns the "real" position of a static element or
|
||||
// relative element that does not have top/left explicitly set.
|
||||
// ==> Always set top and left for position relative elements in your stylesheets
|
||||
// (to 0 if you do not need them)
|
||||
Element.makePositioned(this.element);
|
||||
this.originalTop = parseFloat(Element.getStyle(this.element,'top') || '0');
|
||||
this.originalLeft = parseFloat(Element.getStyle(this.element,'left') || '0');
|
||||
},
|
||||
update: function(position) {
|
||||
Element.setStyle(this.element, {
|
||||
top: this.toTop * position + this.originalTop + 'px',
|
||||
left: this.toLeft * position + this.originalLeft + 'px'
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
Effect.Scale = Class.create();
|
||||
Object.extend(Object.extend(Effect.Scale.prototype, Effect.Base.prototype), {
|
||||
initialize: function(element, percent) {
|
||||
this.element = $(element)
|
||||
var options = Object.extend({
|
||||
scaleX: true,
|
||||
scaleY: true,
|
||||
scaleContent: true,
|
||||
scaleFromCenter: false,
|
||||
scaleMode: 'box', // 'box' or 'contents' or {} with provided values
|
||||
scaleFrom: 100.0,
|
||||
scaleTo: percent
|
||||
}, arguments[2] || {});
|
||||
this.start(options);
|
||||
},
|
||||
setup: function() {
|
||||
this.restoreAfterFinish = this.options.restoreAfterFinish || false;
|
||||
this.elementPositioning = Element.getStyle(this.element,'position');
|
||||
|
||||
this.originalStyle = {};
|
||||
['top','left','width','height','fontSize'].each( function(k) {
|
||||
this.originalStyle[k] = this.element.style[k];
|
||||
}.bind(this));
|
||||
|
||||
this.originalTop = this.element.offsetTop;
|
||||
this.originalLeft = this.element.offsetLeft;
|
||||
|
||||
var fontSize = Element.getStyle(this.element,'font-size') || '100%';
|
||||
['em','px','%'].each( function(fontSizeType) {
|
||||
if(fontSize.indexOf(fontSizeType)>0) {
|
||||
this.fontSize = parseFloat(fontSize);
|
||||
this.fontSizeType = fontSizeType;
|
||||
}
|
||||
}.bind(this));
|
||||
|
||||
this.factor = (this.options.scaleTo - this.options.scaleFrom)/100;
|
||||
|
||||
this.dims = null;
|
||||
if(this.options.scaleMode=='box')
|
||||
this.dims = [this.element.offsetHeight, this.element.offsetWidth];
|
||||
if(/^content/.test(this.options.scaleMode))
|
||||
this.dims = [this.element.scrollHeight, this.element.scrollWidth];
|
||||
if(!this.dims)
|
||||
this.dims = [this.options.scaleMode.originalHeight,
|
||||
this.options.scaleMode.originalWidth];
|
||||
},
|
||||
update: function(position) {
|
||||
var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position);
|
||||
if(this.options.scaleContent && this.fontSize)
|
||||
Element.setStyle(this.element, {fontSize: this.fontSize * currentScale + this.fontSizeType });
|
||||
this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale);
|
||||
},
|
||||
finish: function(position) {
|
||||
if (this.restoreAfterFinish) Element.setStyle(this.element, this.originalStyle);
|
||||
},
|
||||
setDimensions: function(height, width) {
|
||||
var d = {};
|
||||
if(this.options.scaleX) d.width = width + 'px';
|
||||
if(this.options.scaleY) d.height = height + 'px';
|
||||
if(this.options.scaleFromCenter) {
|
||||
var topd = (height - this.dims[0])/2;
|
||||
var leftd = (width - this.dims[1])/2;
|
||||
if(this.elementPositioning == 'absolute') {
|
||||
if(this.options.scaleY) d.top = this.originalTop-topd + 'px';
|
||||
if(this.options.scaleX) d.left = this.originalLeft-leftd + 'px';
|
||||
} else {
|
||||
if(this.options.scaleY) d.top = -topd + 'px';
|
||||
if(this.options.scaleX) d.left = -leftd + 'px';
|
||||
}
|
||||
}
|
||||
Element.setStyle(this.element, d);
|
||||
}
|
||||
});
|
||||
|
||||
Effect.Highlight = Class.create();
|
||||
Object.extend(Object.extend(Effect.Highlight.prototype, Effect.Base.prototype), {
|
||||
initialize: function(element) {
|
||||
this.element = $(element);
|
||||
var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || {});
|
||||
this.start(options);
|
||||
},
|
||||
setup: function() {
|
||||
// Prevent executing on elements not in the layout flow
|
||||
if(Element.getStyle(this.element, 'display')=='none') { this.cancel(); return; }
|
||||
// Disable background image during the effect
|
||||
this.oldStyle = {
|
||||
backgroundImage: Element.getStyle(this.element, 'background-image') };
|
||||
Element.setStyle(this.element, {backgroundImage: 'none'});
|
||||
if(!this.options.endcolor)
|
||||
this.options.endcolor = Element.getStyle(this.element, 'background-color').parseColor('#ffffff');
|
||||
if(!this.options.restorecolor)
|
||||
this.options.restorecolor = Element.getStyle(this.element, 'background-color');
|
||||
// init color calculations
|
||||
this._base = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this));
|
||||
this._delta = $R(0,2).map(function(i){ return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i] }.bind(this));
|
||||
},
|
||||
update: function(position) {
|
||||
Element.setStyle(this.element,{backgroundColor: $R(0,2).inject('#',function(m,v,i){
|
||||
return m+(Math.round(this._base[i]+(this._delta[i]*position)).toColorPart()); }.bind(this)) });
|
||||
},
|
||||
finish: function() {
|
||||
Element.setStyle(this.element, Object.extend(this.oldStyle, {
|
||||
backgroundColor: this.options.restorecolor
|
||||
}));
|
||||
}
|
||||
});
|
||||
|
||||
Effect.ScrollTo = Class.create();
|
||||
Object.extend(Object.extend(Effect.ScrollTo.prototype, Effect.Base.prototype), {
|
||||
initialize: function(element) {
|
||||
this.element = $(element);
|
||||
this.start(arguments[1] || {});
|
||||
},
|
||||
setup: function() {
|
||||
Position.prepare();
|
||||
var offsets = Position.cumulativeOffset(this.element);
|
||||
if(this.options.offset) offsets[1] += this.options.offset;
|
||||
var max = window.innerHeight ?
|
||||
window.height - window.innerHeight :
|
||||
document.body.scrollHeight -
|
||||
(document.documentElement.clientHeight ?
|
||||
document.documentElement.clientHeight : document.body.clientHeight);
|
||||
this.scrollStart = Position.deltaY;
|
||||
this.delta = (offsets[1] > max ? max : offsets[1]) - this.scrollStart;
|
||||
},
|
||||
update: function(position) {
|
||||
Position.prepare();
|
||||
window.scrollTo(Position.deltaX,
|
||||
this.scrollStart + (position*this.delta));
|
||||
}
|
||||
});
|
||||
|
||||
/* ------------- combination effects ------------- */
|
||||
|
||||
Effect.Fade = function(element) {
|
||||
var oldOpacity = Element.getInlineOpacity(element);
|
||||
var options = Object.extend({
|
||||
from: Element.getOpacity(element) || 1.0,
|
||||
to: 0.0,
|
||||
afterFinishInternal: function(effect) { with(Element) {
|
||||
if(effect.options.to!=0) return;
|
||||
hide(effect.element);
|
||||
setStyle(effect.element, {opacity: oldOpacity}); }}
|
||||
}, arguments[1] || {});
|
||||
return new Effect.Opacity(element,options);
|
||||
}
|
||||
|
||||
Effect.Appear = function(element) {
|
||||
var options = Object.extend({
|
||||
from: (Element.getStyle(element, 'display') == 'none' ? 0.0 : Element.getOpacity(element) || 0.0),
|
||||
to: 1.0,
|
||||
beforeSetup: function(effect) { with(Element) {
|
||||
setOpacity(effect.element, effect.options.from);
|
||||
show(effect.element); }}
|
||||
}, arguments[1] || {});
|
||||
return new Effect.Opacity(element,options);
|
||||
}
|
||||
|
||||
Effect.Puff = function(element) {
|
||||
element = $(element);
|
||||
var oldStyle = { opacity: Element.getInlineOpacity(element), position: Element.getStyle(element, 'position') };
|
||||
return new Effect.Parallel(
|
||||
[ new Effect.Scale(element, 200,
|
||||
{ sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }),
|
||||
new Effect.Opacity(element, { sync: true, to: 0.0 } ) ],
|
||||
Object.extend({ duration: 1.0,
|
||||
beforeSetupInternal: function(effect) { with(Element) {
|
||||
setStyle(effect.effects[0].element, {position: 'absolute'}); }},
|
||||
afterFinishInternal: function(effect) { with(Element) {
|
||||
hide(effect.effects[0].element);
|
||||
setStyle(effect.effects[0].element, oldStyle); }}
|
||||
}, arguments[1] || {})
|
||||
);
|
||||
}
|
||||
|
||||
Effect.BlindUp = function(element) {
|
||||
element = $(element);
|
||||
Element.makeClipping(element);
|
||||
return new Effect.Scale(element, 0,
|
||||
Object.extend({ scaleContent: false,
|
||||
scaleX: false,
|
||||
restoreAfterFinish: true,
|
||||
afterFinishInternal: function(effect) { with(Element) {
|
||||
[hide, undoClipping].call(effect.element); }}
|
||||
}, arguments[1] || {})
|
||||
);
|
||||
}
|
||||
|
||||
Effect.BlindDown = function(element) {
|
||||
element = $(element);
|
||||
var oldHeight = Element.getStyle(element, 'height');
|
||||
var elementDimensions = Element.getDimensions(element);
|
||||
return new Effect.Scale(element, 100,
|
||||
Object.extend({ scaleContent: false,
|
||||
scaleX: false,
|
||||
scaleFrom: 0,
|
||||
scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
|
||||
restoreAfterFinish: true,
|
||||
afterSetup: function(effect) { with(Element) {
|
||||
makeClipping(effect.element);
|
||||
setStyle(effect.element, {height: '0px'});
|
||||
show(effect.element);
|
||||
}},
|
||||
afterFinishInternal: function(effect) { with(Element) {
|
||||
undoClipping(effect.element);
|
||||
setStyle(effect.element, {height: oldHeight});
|
||||
}}
|
||||
}, arguments[1] || {})
|
||||
);
|
||||
}
|
||||
|
||||
Effect.SwitchOff = function(element) {
|
||||
element = $(element);
|
||||
var oldOpacity = Element.getInlineOpacity(element);
|
||||
return new Effect.Appear(element, {
|
||||
duration: 0.4,
|
||||
from: 0,
|
||||
transition: Effect.Transitions.flicker,
|
||||
afterFinishInternal: function(effect) {
|
||||
new Effect.Scale(effect.element, 1, {
|
||||
duration: 0.3, scaleFromCenter: true,
|
||||
scaleX: false, scaleContent: false, restoreAfterFinish: true,
|
||||
beforeSetup: function(effect) { with(Element) {
|
||||
[makePositioned,makeClipping].call(effect.element);
|
||||
}},
|
||||
afterFinishInternal: function(effect) { with(Element) {
|
||||
[hide,undoClipping,undoPositioned].call(effect.element);
|
||||
setStyle(effect.element, {opacity: oldOpacity});
|
||||
}}
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Effect.DropOut = function(element) {
|
||||
element = $(element);
|
||||
var oldStyle = {
|
||||
top: Element.getStyle(element, 'top'),
|
||||
left: Element.getStyle(element, 'left'),
|
||||
opacity: Element.getInlineOpacity(element) };
|
||||
return new Effect.Parallel(
|
||||
[ new Effect.MoveBy(element, 100, 0, { sync: true }),
|
||||
new Effect.Opacity(element, { sync: true, to: 0.0 }) ],
|
||||
Object.extend(
|
||||
{ duration: 0.5,
|
||||
beforeSetup: function(effect) { with(Element) {
|
||||
makePositioned(effect.effects[0].element); }},
|
||||
afterFinishInternal: function(effect) { with(Element) {
|
||||
[hide, undoPositioned].call(effect.effects[0].element);
|
||||
setStyle(effect.effects[0].element, oldStyle); }}
|
||||
}, arguments[1] || {}));
|
||||
}
|
||||
|
||||
Effect.Shake = function(element) {
|
||||
element = $(element);
|
||||
var oldStyle = {
|
||||
top: Element.getStyle(element, 'top'),
|
||||
left: Element.getStyle(element, 'left') };
|
||||
return new Effect.MoveBy(element, 0, 20,
|
||||
{ duration: 0.05, afterFinishInternal: function(effect) {
|
||||
new Effect.MoveBy(effect.element, 0, -40,
|
||||
{ duration: 0.1, afterFinishInternal: function(effect) {
|
||||
new Effect.MoveBy(effect.element, 0, 40,
|
||||
{ duration: 0.1, afterFinishInternal: function(effect) {
|
||||
new Effect.MoveBy(effect.element, 0, -40,
|
||||
{ duration: 0.1, afterFinishInternal: function(effect) {
|
||||
new Effect.MoveBy(effect.element, 0, 40,
|
||||
{ duration: 0.1, afterFinishInternal: function(effect) {
|
||||
new Effect.MoveBy(effect.element, 0, -20,
|
||||
{ duration: 0.05, afterFinishInternal: function(effect) { with(Element) {
|
||||
undoPositioned(effect.element);
|
||||
setStyle(effect.element, oldStyle);
|
||||
}}}) }}) }}) }}) }}) }});
|
||||
}
|
||||
|
||||
Effect.SlideDown = function(element) {
|
||||
element = $(element);
|
||||
Element.cleanWhitespace(element);
|
||||
// SlideDown need to have the content of the element wrapped in a container element with fixed height!
|
||||
var oldInnerBottom = Element.getStyle(element.firstChild, 'bottom');
|
||||
var elementDimensions = Element.getDimensions(element);
|
||||
return new Effect.Scale(element, 100, Object.extend({
|
||||
scaleContent: false,
|
||||
scaleX: false,
|
||||
scaleFrom: 0,
|
||||
scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
|
||||
restoreAfterFinish: true,
|
||||
afterSetup: function(effect) { with(Element) {
|
||||
makePositioned(effect.element);
|
||||
makePositioned(effect.element.firstChild);
|
||||
if(window.opera) setStyle(effect.element, {top: ''});
|
||||
makeClipping(effect.element);
|
||||
setStyle(effect.element, {height: '0px'});
|
||||
show(element); }},
|
||||
afterUpdateInternal: function(effect) { with(Element) {
|
||||
setStyle(effect.element.firstChild, {bottom:
|
||||
(effect.dims[0] - effect.element.clientHeight) + 'px' }); }},
|
||||
afterFinishInternal: function(effect) { with(Element) {
|
||||
undoClipping(effect.element);
|
||||
undoPositioned(effect.element.firstChild);
|
||||
undoPositioned(effect.element);
|
||||
setStyle(effect.element.firstChild, {bottom: oldInnerBottom}); }}
|
||||
}, arguments[1] || {})
|
||||
);
|
||||
}
|
||||
|
||||
Effect.SlideUp = function(element) {
|
||||
element = $(element);
|
||||
Element.cleanWhitespace(element);
|
||||
var oldInnerBottom = Element.getStyle(element.firstChild, 'bottom');
|
||||
return new Effect.Scale(element, 0,
|
||||
Object.extend({ scaleContent: false,
|
||||
scaleX: false,
|
||||
scaleMode: 'box',
|
||||
scaleFrom: 100,
|
||||
restoreAfterFinish: true,
|
||||
beforeStartInternal: function(effect) { with(Element) {
|
||||
makePositioned(effect.element);
|
||||
makePositioned(effect.element.firstChild);
|
||||
if(window.opera) setStyle(effect.element, {top: ''});
|
||||
makeClipping(effect.element);
|
||||
show(element); }},
|
||||
afterUpdateInternal: function(effect) { with(Element) {
|
||||
setStyle(effect.element.firstChild, {bottom:
|
||||
(effect.dims[0] - effect.element.clientHeight) + 'px' }); }},
|
||||
afterFinishInternal: function(effect) { with(Element) {
|
||||
[hide, undoClipping].call(effect.element);
|
||||
undoPositioned(effect.element.firstChild);
|
||||
undoPositioned(effect.element);
|
||||
setStyle(effect.element.firstChild, {bottom: oldInnerBottom}); }}
|
||||
}, arguments[1] || {})
|
||||
);
|
||||
}
|
||||
|
||||
// Bug in opera makes the TD containing this element expand for a instance after finish
|
||||
Effect.Squish = function(element) {
|
||||
return new Effect.Scale(element, window.opera ? 1 : 0,
|
||||
{ restoreAfterFinish: true,
|
||||
beforeSetup: function(effect) { with(Element) {
|
||||
makeClipping(effect.element); }},
|
||||
afterFinishInternal: function(effect) { with(Element) {
|
||||
hide(effect.element);
|
||||
undoClipping(effect.element); }}
|
||||
});
|
||||
}
|
||||
|
||||
Effect.Grow = function(element) {
|
||||
element = $(element);
|
||||
var options = Object.extend({
|
||||
direction: 'center',
|
||||
moveTransistion: Effect.Transitions.sinoidal,
|
||||
scaleTransition: Effect.Transitions.sinoidal,
|
||||
opacityTransition: Effect.Transitions.full
|
||||
}, arguments[1] || {});
|
||||
var oldStyle = {
|
||||
top: element.style.top,
|
||||
left: element.style.left,
|
||||
height: element.style.height,
|
||||
width: element.style.width,
|
||||
opacity: Element.getInlineOpacity(element) };
|
||||
|
||||
var dims = Element.getDimensions(element);
|
||||
var initialMoveX, initialMoveY;
|
||||
var moveX, moveY;
|
||||
|
||||
switch (options.direction) {
|
||||
case 'top-left':
|
||||
initialMoveX = initialMoveY = moveX = moveY = 0;
|
||||
break;
|
||||
case 'top-right':
|
||||
initialMoveX = dims.width;
|
||||
initialMoveY = moveY = 0;
|
||||
moveX = -dims.width;
|
||||
break;
|
||||
case 'bottom-left':
|
||||
initialMoveX = moveX = 0;
|
||||
initialMoveY = dims.height;
|
||||
moveY = -dims.height;
|
||||
break;
|
||||
case 'bottom-right':
|
||||
initialMoveX = dims.width;
|
||||
initialMoveY = dims.height;
|
||||
moveX = -dims.width;
|
||||
moveY = -dims.height;
|
||||
break;
|
||||
case 'center':
|
||||
initialMoveX = dims.width / 2;
|
||||
initialMoveY = dims.height / 2;
|
||||
moveX = -dims.width / 2;
|
||||
moveY = -dims.height / 2;
|
||||
break;
|
||||
}
|
||||
|
||||
return new Effect.MoveBy(element, initialMoveY, initialMoveX, {
|
||||
duration: 0.01,
|
||||
beforeSetup: function(effect) { with(Element) {
|
||||
hide(effect.element);
|
||||
makeClipping(effect.element);
|
||||
makePositioned(effect.element);
|
||||
}},
|
||||
afterFinishInternal: function(effect) {
|
||||
new Effect.Parallel(
|
||||
[ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }),
|
||||
new Effect.MoveBy(effect.element, moveY, moveX, { sync: true, transition: options.moveTransition }),
|
||||
new Effect.Scale(effect.element, 100, {
|
||||
scaleMode: { originalHeight: dims.height, originalWidth: dims.width },
|
||||
sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true})
|
||||
], Object.extend({
|
||||
beforeSetup: function(effect) { with(Element) {
|
||||
setStyle(effect.effects[0].element, {height: '0px'});
|
||||
show(effect.effects[0].element); }},
|
||||
afterFinishInternal: function(effect) { with(Element) {
|
||||
[undoClipping, undoPositioned].call(effect.effects[0].element);
|
||||
setStyle(effect.effects[0].element, oldStyle); }}
|
||||
}, options)
|
||||
)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Effect.Shrink = function(element) {
|
||||
element = $(element);
|
||||
var options = Object.extend({
|
||||
direction: 'center',
|
||||
moveTransistion: Effect.Transitions.sinoidal,
|
||||
scaleTransition: Effect.Transitions.sinoidal,
|
||||
opacityTransition: Effect.Transitions.none
|
||||
}, arguments[1] || {});
|
||||
var oldStyle = {
|
||||
top: element.style.top,
|
||||
left: element.style.left,
|
||||
height: element.style.height,
|
||||
width: element.style.width,
|
||||
opacity: Element.getInlineOpacity(element) };
|
||||
|
||||
var dims = Element.getDimensions(element);
|
||||
var moveX, moveY;
|
||||
|
||||
switch (options.direction) {
|
||||
case 'top-left':
|
||||
moveX = moveY = 0;
|
||||
break;
|
||||
case 'top-right':
|
||||
moveX = dims.width;
|
||||
moveY = 0;
|
||||
break;
|
||||
case 'bottom-left':
|
||||
moveX = 0;
|
||||
moveY = dims.height;
|
||||
break;
|
||||
case 'bottom-right':
|
||||
moveX = dims.width;
|
||||
moveY = dims.height;
|
||||
break;
|
||||
case 'center':
|
||||
moveX = dims.width / 2;
|
||||
moveY = dims.height / 2;
|
||||
break;
|
||||
}
|
||||
|
||||
return new Effect.Parallel(
|
||||
[ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }),
|
||||
new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}),
|
||||
new Effect.MoveBy(element, moveY, moveX, { sync: true, transition: options.moveTransition })
|
||||
], Object.extend({
|
||||
beforeStartInternal: function(effect) { with(Element) {
|
||||
[makePositioned, makeClipping].call(effect.effects[0].element) }},
|
||||
afterFinishInternal: function(effect) { with(Element) {
|
||||
[hide, undoClipping, undoPositioned].call(effect.effects[0].element);
|
||||
setStyle(effect.effects[0].element, oldStyle); }}
|
||||
}, options)
|
||||
);
|
||||
}
|
||||
|
||||
Effect.Pulsate = function(element) {
|
||||
element = $(element);
|
||||
var options = arguments[1] || {};
|
||||
var oldOpacity = Element.getInlineOpacity(element);
|
||||
var transition = options.transition || Effect.Transitions.sinoidal;
|
||||
var reverser = function(pos){ return transition(1-Effect.Transitions.pulse(pos)) };
|
||||
reverser.bind(transition);
|
||||
return new Effect.Opacity(element,
|
||||
Object.extend(Object.extend({ duration: 3.0, from: 0,
|
||||
afterFinishInternal: function(effect) { Element.setStyle(effect.element, {opacity: oldOpacity}); }
|
||||
}, options), {transition: reverser}));
|
||||
}
|
||||
|
||||
Effect.Fold = function(element) {
|
||||
element = $(element);
|
||||
var oldStyle = {
|
||||
top: element.style.top,
|
||||
left: element.style.left,
|
||||
width: element.style.width,
|
||||
height: element.style.height };
|
||||
Element.makeClipping(element);
|
||||
return new Effect.Scale(element, 5, Object.extend({
|
||||
scaleContent: false,
|
||||
scaleX: false,
|
||||
afterFinishInternal: function(effect) {
|
||||
new Effect.Scale(element, 1, {
|
||||
scaleContent: false,
|
||||
scaleY: false,
|
||||
afterFinishInternal: function(effect) { with(Element) {
|
||||
[hide, undoClipping].call(effect.element);
|
||||
setStyle(effect.element, oldStyle);
|
||||
}} });
|
||||
}}, arguments[1] || {}));
|
||||
}
|
||||
1785
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/public/javascripts/prototype.js
vendored
Normal file
1785
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/public/javascripts/prototype.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/public/robots.txt
vendored
Normal file
1
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/public/robots.txt
vendored
Normal file
@@ -0,0 +1 @@
|
||||
# See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file
|
||||
3
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/script/about
vendored
Normal file
3
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/script/about
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
#!/usr/bin/env ruby
|
||||
require File.dirname(__FILE__) + '/../config/boot'
|
||||
require 'commands/about'
|
||||
3
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/script/breakpointer
vendored
Normal file
3
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/script/breakpointer
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
#!/usr/bin/env ruby
|
||||
require File.dirname(__FILE__) + '/../config/boot'
|
||||
require 'commands/breakpointer'
|
||||
3
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/script/console
vendored
Normal file
3
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/script/console
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
#!/usr/bin/env ruby
|
||||
require File.dirname(__FILE__) + '/../config/boot'
|
||||
require 'commands/console'
|
||||
3
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/script/destroy
vendored
Normal file
3
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/script/destroy
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
#!/usr/bin/env ruby
|
||||
require File.dirname(__FILE__) + '/../config/boot'
|
||||
require 'commands/destroy'
|
||||
3
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/script/generate
vendored
Normal file
3
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/script/generate
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
#!/usr/bin/env ruby
|
||||
require File.dirname(__FILE__) + '/../config/boot'
|
||||
require 'commands/generate'
|
||||
3
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/script/performance/benchmarker
vendored
Normal file
3
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/script/performance/benchmarker
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
#!/usr/bin/env ruby
|
||||
require File.dirname(__FILE__) + '/../../config/boot'
|
||||
require 'commands/performance/benchmarker'
|
||||
3
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/script/performance/profiler
vendored
Normal file
3
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/script/performance/profiler
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
#!/usr/bin/env ruby
|
||||
require File.dirname(__FILE__) + '/../../config/boot'
|
||||
require 'commands/performance/profiler'
|
||||
3
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/script/plugin
vendored
Normal file
3
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/script/plugin
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
#!/usr/bin/env ruby
|
||||
require File.dirname(__FILE__) + '/../config/boot'
|
||||
require 'commands/plugin'
|
||||
3
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/script/process/reaper
vendored
Normal file
3
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/script/process/reaper
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
#!/usr/bin/env ruby
|
||||
require File.dirname(__FILE__) + '/../../config/boot'
|
||||
require 'commands/process/reaper'
|
||||
3
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/script/process/spawner
vendored
Normal file
3
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/script/process/spawner
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
#!/usr/bin/env ruby
|
||||
require File.dirname(__FILE__) + '/../../config/boot'
|
||||
require 'commands/process/spawner'
|
||||
3
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/script/process/spinner
vendored
Normal file
3
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/script/process/spinner
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
#!/usr/bin/env ruby
|
||||
require File.dirname(__FILE__) + '/../../config/boot'
|
||||
require 'commands/process/spinner'
|
||||
3
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/script/runner
vendored
Normal file
3
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/script/runner
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
#!/usr/bin/env ruby
|
||||
require File.dirname(__FILE__) + '/../config/boot'
|
||||
require 'commands/runner'
|
||||
3
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/script/server
vendored
Normal file
3
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/script/server
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
#!/usr/bin/env ruby
|
||||
require File.dirname(__FILE__) + '/../config/boot'
|
||||
require 'commands/server'
|
||||
18
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/test/functional/login_controller_test.rb
vendored
Normal file
18
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/test/functional/login_controller_test.rb
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
require File.dirname(__FILE__) + '/../test_helper'
|
||||
require 'login_controller'
|
||||
|
||||
# Re-raise errors caught by the controller.
|
||||
class LoginController; def rescue_action(e) raise e end; end
|
||||
|
||||
class LoginControllerTest < Test::Unit::TestCase
|
||||
def setup
|
||||
@controller = LoginController.new
|
||||
@request = ActionController::TestRequest.new
|
||||
@response = ActionController::TestResponse.new
|
||||
end
|
||||
|
||||
# Replace this with your real tests.
|
||||
def test_truth
|
||||
assert true
|
||||
end
|
||||
end
|
||||
18
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/test/functional/server_controller_test.rb
vendored
Normal file
18
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/test/functional/server_controller_test.rb
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
require File.dirname(__FILE__) + '/../test_helper'
|
||||
require 'server_controller'
|
||||
|
||||
# Re-raise errors caught by the controller.
|
||||
class ServerController; def rescue_action(e) raise e end; end
|
||||
|
||||
class ServerControllerTest < Test::Unit::TestCase
|
||||
def setup
|
||||
@controller = ServerController.new
|
||||
@request = ActionController::TestRequest.new
|
||||
@response = ActionController::TestResponse.new
|
||||
end
|
||||
|
||||
# Replace this with your real tests.
|
||||
def test_truth
|
||||
assert true
|
||||
end
|
||||
end
|
||||
28
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/test/test_helper.rb
vendored
Normal file
28
vendor/gems/ruby-openid-2.1.4/examples/rails_openid/test/test_helper.rb
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
ENV["RAILS_ENV"] = "test"
|
||||
require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
|
||||
require 'test_help'
|
||||
|
||||
class Test::Unit::TestCase
|
||||
# Transactional fixtures accelerate your tests by wrapping each test method
|
||||
# in a transaction that's rolled back on completion. This ensures that the
|
||||
# test database remains unchanged so your fixtures don't have to be reloaded
|
||||
# between every test method. Fewer database queries means faster tests.
|
||||
#
|
||||
# Read Mike Clark's excellent walkthrough at
|
||||
# http://clarkware.com/cgi/blosxom/2005/10/24#Rails10FastTesting
|
||||
#
|
||||
# Every Active Record database supports transactions except MyISAM tables
|
||||
# in MySQL. Turn off transactional fixtures in this case; however, if you
|
||||
# don't care one way or the other, switching from MyISAM to InnoDB tables
|
||||
# is recommended.
|
||||
self.use_transactional_fixtures = true
|
||||
|
||||
# Instantiated fixtures are slow, but give you @david where otherwise you
|
||||
# would need people(:david). If you don't want to migrate your existing
|
||||
# test cases which use the @david style and don't mind the speed hit (each
|
||||
# instantiated fixtures translates to a database query per test method),
|
||||
# then set this back to true.
|
||||
self.use_instantiated_fixtures = false
|
||||
|
||||
# Add more helper methods to be used by all tests here...
|
||||
end
|
||||
Reference in New Issue
Block a user