Changeset 39
- Timestamp:
- 03/20/06 02:09:26 (7 years ago)
- Location:
- trunk
- Files:
-
- 516 added
- 13 removed
- 24 modified
-
README (modified) (9 diffs)
-
Rakefile (modified) (1 diff)
-
app/controllers/navigation_controller.rb (modified) (5 diffs)
-
app/helpers/hyperde/breadcrumb.rb (modified) (4 diffs)
-
app/helpers/hyperde/context.rb (modified) (1 diff)
-
app/helpers/hyperde/node.rb (modified) (1 diff)
-
app/helpers/hyperde_helper.rb (modified) (1 diff)
-
app/helpers/navigation_helper.rb (modified) (7 diffs)
-
app/models/node.rb (modified) (1 diff)
-
config/boot.rb (added)
-
config/environment.rb (modified) (1 diff)
-
config/environments/development.rb (modified) (1 diff)
-
config/environments/production.rb (modified) (1 diff)
-
config/environments/test.rb (modified) (1 diff)
-
config/routes.rb (modified) (1 diff)
-
lib/model_loader.rb (modified) (2 diffs)
-
lib/rjb.so (modified) (previous)
-
lib/tasks (added)
-
log (added)
-
log/development.log (added)
-
log/production.log (added)
-
log/server.log (added)
-
log/test.log (added)
-
public/.htaccess (modified) (1 diff)
-
public/favicon.ico (modified) (previous)
-
public/images/rails.png (added)
-
public/javascripts/controls.js (modified) (18 diffs)
-
public/javascripts/dragdrop.js (modified) (9 diffs)
-
public/javascripts/effects.js (modified) (15 diffs)
-
public/javascripts/prototype.js (modified) (55 diffs)
-
public/robots.txt (added)
-
r.cmd (added)
-
script/about (added)
-
script/benchmarker.rb (deleted)
-
script/breakpointer (added)
-
script/breakpointer.rb (deleted)
-
script/console (added)
-
script/console.rb (deleted)
-
script/destroy (added)
-
script/destroy.rb (deleted)
-
script/export (added)
-
script/export.rb (deleted)
-
script/generate (added)
-
script/generate.rb (deleted)
-
script/import (added)
-
script/import.rb (deleted)
-
script/performance (added)
-
script/performance/benchmarker (added)
-
script/performance/profiler (added)
-
script/plugin (added)
-
script/process (added)
-
script/process/reaper (added)
-
script/process/spawner (added)
-
script/process/spinner (added)
-
script/profiler.rb (deleted)
-
script/runner (added)
-
script/runner.rb (deleted)
-
script/server (added)
-
script/server.rb (deleted)
-
test/test_helper.rb (modified) (1 diff)
-
vendor/actionpack (deleted)
-
vendor/activesupport (deleted)
-
vendor/rails (added)
-
vendor/rails/actionmailer (added)
-
vendor/rails/actionmailer/lib (added)
-
vendor/rails/actionmailer/lib/action_mailer (added)
-
vendor/rails/actionmailer/lib/action_mailer.rb (added)
-
vendor/rails/actionmailer/lib/action_mailer/adv_attr_accessor.rb (added)
-
vendor/rails/actionmailer/lib/action_mailer/base.rb (added)
-
vendor/rails/actionmailer/lib/action_mailer/helpers.rb (added)
-
vendor/rails/actionmailer/lib/action_mailer/mail_helper.rb (added)
-
vendor/rails/actionmailer/lib/action_mailer/part.rb (added)
-
vendor/rails/actionmailer/lib/action_mailer/part_container.rb (added)
-
vendor/rails/actionmailer/lib/action_mailer/quoting.rb (added)
-
vendor/rails/actionmailer/lib/action_mailer/utils.rb (added)
-
vendor/rails/actionmailer/lib/action_mailer/vendor (added)
-
vendor/rails/actionmailer/lib/action_mailer/vendor/text (added)
-
vendor/rails/actionmailer/lib/action_mailer/vendor/text/format.rb (added)
-
vendor/rails/actionmailer/lib/action_mailer/vendor/tmail (added)
-
vendor/rails/actionmailer/lib/action_mailer/vendor/tmail.rb (added)
-
vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/address.rb (added)
-
vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/attachments.rb (added)
-
vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/base64.rb (added)
-
vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/config.rb (added)
-
vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/encode.rb (added)
-
vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/facade.rb (added)
-
vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/header.rb (added)
-
vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/info.rb (added)
-
vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/loader.rb (added)
-
vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/mail.rb (added)
-
vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/mailbox.rb (added)
-
vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/mbox.rb (added)
-
vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/net.rb (added)
-
vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/obsolete.rb (added)
-
vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/parser.rb (added)
-
vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/port.rb (added)
-
vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/quoting.rb (added)
-
vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/scanner.rb (added)
-
vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/scanner_r.rb (added)
-
vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/stringio.rb (added)
-
vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/tmail.rb (added)
-
vendor/rails/actionmailer/lib/action_mailer/vendor/tmail/utils.rb (added)
-
vendor/rails/actionmailer/lib/action_mailer/version.rb (added)
-
vendor/rails/actionpack (added)
-
vendor/rails/actionpack/lib (added)
-
vendor/rails/actionpack/lib/action_controller (added)
-
vendor/rails/actionpack/lib/action_controller.rb (added)
-
vendor/rails/actionpack/lib/action_controller/assertions.rb (added)
-
vendor/rails/actionpack/lib/action_controller/base.rb (added)
-
vendor/rails/actionpack/lib/action_controller/benchmarking.rb (added)
-
vendor/rails/actionpack/lib/action_controller/caching.rb (added)
-
vendor/rails/actionpack/lib/action_controller/cgi_ext (added)
-
vendor/rails/actionpack/lib/action_controller/cgi_ext/cgi_ext.rb (added)
-
vendor/rails/actionpack/lib/action_controller/cgi_ext/cgi_methods.rb (added)
-
vendor/rails/actionpack/lib/action_controller/cgi_ext/cookie_performance_fix.rb (added)
-
vendor/rails/actionpack/lib/action_controller/cgi_ext/raw_post_data_fix.rb (added)
-
vendor/rails/actionpack/lib/action_controller/cgi_process.rb (added)
-
vendor/rails/actionpack/lib/action_controller/code_generation.rb (added)
-
vendor/rails/actionpack/lib/action_controller/components.rb (added)
-
vendor/rails/actionpack/lib/action_controller/cookies.rb (added)
-
vendor/rails/actionpack/lib/action_controller/dependencies.rb (added)
-
vendor/rails/actionpack/lib/action_controller/deprecated_assertions.rb (added)
-
vendor/rails/actionpack/lib/action_controller/deprecated_redirects.rb (added)
-
vendor/rails/actionpack/lib/action_controller/deprecated_request_methods.rb (added)
-
vendor/rails/actionpack/lib/action_controller/filters.rb (added)
-
vendor/rails/actionpack/lib/action_controller/flash.rb (added)
-
vendor/rails/actionpack/lib/action_controller/helpers.rb (added)
-
vendor/rails/actionpack/lib/action_controller/integration.rb (added)
-
vendor/rails/actionpack/lib/action_controller/layout.rb (added)
-
vendor/rails/actionpack/lib/action_controller/macros (added)
-
vendor/rails/actionpack/lib/action_controller/macros/auto_complete.rb (added)
-
vendor/rails/actionpack/lib/action_controller/macros/in_place_editing.rb (added)
-
vendor/rails/actionpack/lib/action_controller/mime_responds.rb (added)
-
vendor/rails/actionpack/lib/action_controller/mime_type.rb (added)
-
vendor/rails/actionpack/lib/action_controller/pagination.rb (added)
-
vendor/rails/actionpack/lib/action_controller/request.rb (added)
-
vendor/rails/actionpack/lib/action_controller/rescue.rb (added)
-
vendor/rails/actionpack/lib/action_controller/response.rb (added)
-
vendor/rails/actionpack/lib/action_controller/routing.rb (added)
-
vendor/rails/actionpack/lib/action_controller/scaffolding.rb (added)
-
vendor/rails/actionpack/lib/action_controller/session (added)
-
vendor/rails/actionpack/lib/action_controller/session/active_record_store.rb (added)
-
vendor/rails/actionpack/lib/action_controller/session/drb_server.rb (added)
-
vendor/rails/actionpack/lib/action_controller/session/drb_store.rb (added)
-
vendor/rails/actionpack/lib/action_controller/session/mem_cache_store.rb (added)
-
vendor/rails/actionpack/lib/action_controller/session_management.rb (added)
-
vendor/rails/actionpack/lib/action_controller/streaming.rb (added)
-
vendor/rails/actionpack/lib/action_controller/templates (added)
-
vendor/rails/actionpack/lib/action_controller/templates/rescues (added)
-
vendor/rails/actionpack/lib/action_controller/templates/rescues/_request_and_response.rhtml (added)
-
vendor/rails/actionpack/lib/action_controller/templates/rescues/_trace.rhtml (added)
-
vendor/rails/actionpack/lib/action_controller/templates/rescues/diagnostics.rhtml (added)
-
vendor/rails/actionpack/lib/action_controller/templates/rescues/layout.rhtml (added)
-
vendor/rails/actionpack/lib/action_controller/templates/rescues/missing_template.rhtml (added)
-
vendor/rails/actionpack/lib/action_controller/templates/rescues/routing_error.rhtml (added)
-
vendor/rails/actionpack/lib/action_controller/templates/rescues/template_error.rhtml (added)
-
vendor/rails/actionpack/lib/action_controller/templates/rescues/unknown_action.rhtml (added)
-
vendor/rails/actionpack/lib/action_controller/templates/scaffolds (added)
-
vendor/rails/actionpack/lib/action_controller/templates/scaffolds/edit.rhtml (added)
-
vendor/rails/actionpack/lib/action_controller/templates/scaffolds/layout.rhtml (added)
-
vendor/rails/actionpack/lib/action_controller/templates/scaffolds/list.rhtml (added)
-
vendor/rails/actionpack/lib/action_controller/templates/scaffolds/new.rhtml (added)
-
vendor/rails/actionpack/lib/action_controller/templates/scaffolds/show.rhtml (added)
-
vendor/rails/actionpack/lib/action_controller/test_process.rb (added)
-
vendor/rails/actionpack/lib/action_controller/url_rewriter.rb (added)
-
vendor/rails/actionpack/lib/action_controller/vendor (added)
-
vendor/rails/actionpack/lib/action_controller/vendor/html-scanner (added)
-
vendor/rails/actionpack/lib/action_controller/vendor/html-scanner/html (added)
-
vendor/rails/actionpack/lib/action_controller/vendor/html-scanner/html/document.rb (added)
-
vendor/rails/actionpack/lib/action_controller/vendor/html-scanner/html/node.rb (added)
-
vendor/rails/actionpack/lib/action_controller/vendor/html-scanner/html/tokenizer.rb (added)
-
vendor/rails/actionpack/lib/action_controller/vendor/html-scanner/html/version.rb (added)
-
vendor/rails/actionpack/lib/action_controller/vendor/xml_node.rb (added)
-
vendor/rails/actionpack/lib/action_controller/vendor/xml_simple.rb (added)
-
vendor/rails/actionpack/lib/action_controller/verification.rb (added)
-
vendor/rails/actionpack/lib/action_pack (added)
-
vendor/rails/actionpack/lib/action_pack.rb (added)
-
vendor/rails/actionpack/lib/action_pack/version.rb (added)
-
vendor/rails/actionpack/lib/action_view (added)
-
vendor/rails/actionpack/lib/action_view.rb (added)
-
vendor/rails/actionpack/lib/action_view/base.rb (added)
-
vendor/rails/actionpack/lib/action_view/compiled_templates.rb (added)
-
vendor/rails/actionpack/lib/action_view/helpers (added)
-
vendor/rails/actionpack/lib/action_view/helpers/active_record_helper.rb (added)
-
vendor/rails/actionpack/lib/action_view/helpers/asset_tag_helper.rb (added)
-
vendor/rails/actionpack/lib/action_view/helpers/benchmark_helper.rb (added)
-
vendor/rails/actionpack/lib/action_view/helpers/cache_helper.rb (added)
-
vendor/rails/actionpack/lib/action_view/helpers/capture_helper.rb (added)
-
vendor/rails/actionpack/lib/action_view/helpers/date_helper.rb (added)
-
vendor/rails/actionpack/lib/action_view/helpers/debug_helper.rb (added)
-
vendor/rails/actionpack/lib/action_view/helpers/form_helper.rb (added)
-
vendor/rails/actionpack/lib/action_view/helpers/form_options_helper.rb (added)
-
vendor/rails/actionpack/lib/action_view/helpers/form_tag_helper.rb (added)
-
vendor/rails/actionpack/lib/action_view/helpers/java_script_macros_helper.rb (added)
-
vendor/rails/actionpack/lib/action_view/helpers/javascript_helper.rb (added)
-
vendor/rails/actionpack/lib/action_view/helpers/javascripts (added)
-
vendor/rails/actionpack/lib/action_view/helpers/javascripts/controls.js (added)
-
vendor/rails/actionpack/lib/action_view/helpers/javascripts/dragdrop.js (added)
-
vendor/rails/actionpack/lib/action_view/helpers/javascripts/effects.js (added)
-
vendor/rails/actionpack/lib/action_view/helpers/javascripts/prototype.js (added)
-
vendor/rails/actionpack/lib/action_view/helpers/number_helper.rb (added)
-
vendor/rails/actionpack/lib/action_view/helpers/pagination_helper.rb (added)
-
vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb (added)
-
vendor/rails/actionpack/lib/action_view/helpers/scriptaculous_helper.rb (added)
-
vendor/rails/actionpack/lib/action_view/helpers/tag_helper.rb (added)
-
vendor/rails/actionpack/lib/action_view/helpers/text_helper.rb (added)
-
vendor/rails/actionpack/lib/action_view/helpers/url_helper.rb (added)
-
vendor/rails/actionpack/lib/action_view/partials.rb (added)
-
vendor/rails/actionpack/lib/action_view/template_error.rb (added)
-
vendor/rails/actionwebservice (added)
-
vendor/rails/actionwebservice/lib (added)
-
vendor/rails/actionwebservice/lib/action_web_service (added)
-
vendor/rails/actionwebservice/lib/action_web_service.rb (added)
-
vendor/rails/actionwebservice/lib/action_web_service/api.rb (added)
-
vendor/rails/actionwebservice/lib/action_web_service/base.rb (added)
-
vendor/rails/actionwebservice/lib/action_web_service/casting.rb (added)
-
vendor/rails/actionwebservice/lib/action_web_service/client (added)
-
vendor/rails/actionwebservice/lib/action_web_service/client.rb (added)
-
vendor/rails/actionwebservice/lib/action_web_service/client/base.rb (added)
-
vendor/rails/actionwebservice/lib/action_web_service/client/soap_client.rb (added)
-
vendor/rails/actionwebservice/lib/action_web_service/client/xmlrpc_client.rb (added)
-
vendor/rails/actionwebservice/lib/action_web_service/container (added)
-
vendor/rails/actionwebservice/lib/action_web_service/container.rb (added)
-
vendor/rails/actionwebservice/lib/action_web_service/container/action_controller_container.rb (added)
-
vendor/rails/actionwebservice/lib/action_web_service/container/delegated_container.rb (added)
-
vendor/rails/actionwebservice/lib/action_web_service/container/direct_container.rb (added)
-
vendor/rails/actionwebservice/lib/action_web_service/dispatcher (added)
-
vendor/rails/actionwebservice/lib/action_web_service/dispatcher.rb (added)
-
vendor/rails/actionwebservice/lib/action_web_service/dispatcher/abstract.rb (added)
-
vendor/rails/actionwebservice/lib/action_web_service/dispatcher/action_controller_dispatcher.rb (added)
-
vendor/rails/actionwebservice/lib/action_web_service/invocation.rb (added)
-
vendor/rails/actionwebservice/lib/action_web_service/protocol (added)
-
vendor/rails/actionwebservice/lib/action_web_service/protocol.rb (added)
-
vendor/rails/actionwebservice/lib/action_web_service/protocol/abstract.rb (added)
-
vendor/rails/actionwebservice/lib/action_web_service/protocol/discovery.rb (added)
-
vendor/rails/actionwebservice/lib/action_web_service/protocol/soap_protocol (added)
-
vendor/rails/actionwebservice/lib/action_web_service/protocol/soap_protocol.rb (added)
-
vendor/rails/actionwebservice/lib/action_web_service/protocol/soap_protocol/marshaler.rb (added)
-
vendor/rails/actionwebservice/lib/action_web_service/protocol/xmlrpc_protocol.rb (added)
-
vendor/rails/actionwebservice/lib/action_web_service/scaffolding.rb (added)
-
vendor/rails/actionwebservice/lib/action_web_service/struct.rb (added)
-
vendor/rails/actionwebservice/lib/action_web_service/support (added)
-
vendor/rails/actionwebservice/lib/action_web_service/support/class_inheritable_options.rb (added)
-
vendor/rails/actionwebservice/lib/action_web_service/support/signature_types.rb (added)
-
vendor/rails/actionwebservice/lib/action_web_service/templates (added)
-
vendor/rails/actionwebservice/lib/action_web_service/templates/scaffolds (added)
-
vendor/rails/actionwebservice/lib/action_web_service/templates/scaffolds/layout.rhtml (added)
-
vendor/rails/actionwebservice/lib/action_web_service/templates/scaffolds/methods.rhtml (added)
-
vendor/rails/actionwebservice/lib/action_web_service/templates/scaffolds/parameters.rhtml (added)
-
vendor/rails/actionwebservice/lib/action_web_service/templates/scaffolds/result.rhtml (added)
-
vendor/rails/actionwebservice/lib/action_web_service/test_invoke.rb (added)
-
vendor/rails/actionwebservice/lib/action_web_service/version.rb (added)
-
vendor/rails/activerecord (added)
-
vendor/rails/activerecord/lib (added)
-
vendor/rails/activerecord/lib/active_record (added)
-
vendor/rails/activerecord/lib/active_record.rb (added)
-
vendor/rails/activerecord/lib/active_record/acts (added)
-
vendor/rails/activerecord/lib/active_record/acts/list.rb (added)
-
vendor/rails/activerecord/lib/active_record/acts/nested_set.rb (added)
-
vendor/rails/activerecord/lib/active_record/acts/tree.rb (added)
-
vendor/rails/activerecord/lib/active_record/aggregations.rb (added)
-
vendor/rails/activerecord/lib/active_record/associations (added)
-
vendor/rails/activerecord/lib/active_record/associations.rb (added)
-
vendor/rails/activerecord/lib/active_record/associations/association_collection.rb (added)
-
vendor/rails/activerecord/lib/active_record/associations/association_proxy.rb (added)
-
vendor/rails/activerecord/lib/active_record/associations/belongs_to_association.rb (added)
-
vendor/rails/activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb (added)
-
vendor/rails/activerecord/lib/active_record/associations/has_and_belongs_to_many_association.rb (added)
-
vendor/rails/activerecord/lib/active_record/associations/has_many_association.rb (added)
-
vendor/rails/activerecord/lib/active_record/associations/has_many_through_association.rb (added)
-
vendor/rails/activerecord/lib/active_record/associations/has_one_association.rb (added)
-
vendor/rails/activerecord/lib/active_record/base.rb (added)
-
vendor/rails/activerecord/lib/active_record/calculations.rb (added)
-
vendor/rails/activerecord/lib/active_record/callbacks.rb (added)
-
vendor/rails/activerecord/lib/active_record/connection_adapters (added)
-
vendor/rails/activerecord/lib/active_record/connection_adapters/abstract (added)
-
vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb (added)
-
vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb (added)
-
vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb (added)
-
vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb (added)
-
vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb (added)
-
vendor/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb (added)
-
vendor/rails/activerecord/lib/active_record/connection_adapters/db2_adapter.rb (added)
-
vendor/rails/activerecord/lib/active_record/connection_adapters/firebird_adapter.rb (added)
-
vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb (added)
-
vendor/rails/activerecord/lib/active_record/connection_adapters/openbase_adapter.rb (added)
-
vendor/rails/activerecord/lib/active_record/connection_adapters/oracle_adapter.rb (added)
-
vendor/rails/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb (added)
-
vendor/rails/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb (added)
-
vendor/rails/activerecord/lib/active_record/connection_adapters/sqlserver_adapter.rb (added)
-
vendor/rails/activerecord/lib/active_record/connection_adapters/sybase_adapter.rb (added)
-
vendor/rails/activerecord/lib/active_record/deprecated_associations.rb (added)
-
vendor/rails/activerecord/lib/active_record/deprecated_finders.rb (added)
-
vendor/rails/activerecord/lib/active_record/fixtures.rb (added)
-
vendor/rails/activerecord/lib/active_record/locking.rb (added)
-
vendor/rails/activerecord/lib/active_record/migration.rb (added)
-
vendor/rails/activerecord/lib/active_record/observer.rb (added)
-
vendor/rails/activerecord/lib/active_record/query_cache.rb (added)
-
vendor/rails/activerecord/lib/active_record/reflection.rb (added)
-
vendor/rails/activerecord/lib/active_record/schema.rb (added)
-
vendor/rails/activerecord/lib/active_record/schema_dumper.rb (added)
-
vendor/rails/activerecord/lib/active_record/timestamp.rb (added)
-
vendor/rails/activerecord/lib/active_record/transactions.rb (added)
-
vendor/rails/activerecord/lib/active_record/validations.rb (added)
-
vendor/rails/activerecord/lib/active_record/vendor (added)
-
vendor/rails/activerecord/lib/active_record/vendor/db2.rb (added)
-
vendor/rails/activerecord/lib/active_record/vendor/mysql.rb (added)
-
vendor/rails/activerecord/lib/active_record/vendor/simple.rb (added)
-
vendor/rails/activerecord/lib/active_record/version.rb (added)
-
vendor/rails/activerecord/lib/active_record/wrappers (added)
-
vendor/rails/activerecord/lib/active_record/wrappers/yaml_wrapper.rb (added)
-
vendor/rails/activerecord/lib/active_record/wrappings.rb (added)
-
vendor/rails/activesupport (added)
-
vendor/rails/activesupport/lib (added)
-
vendor/rails/activesupport/lib/active_support (added)
-
vendor/rails/activesupport/lib/active_support.rb (added)
-
vendor/rails/activesupport/lib/active_support/binding_of_caller.rb (added)
-
vendor/rails/activesupport/lib/active_support/breakpoint.rb (added)
-
vendor/rails/activesupport/lib/active_support/clean_logger.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext (added)
-
vendor/rails/activesupport/lib/active_support/core_ext.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/array (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/array.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/array/conversions.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/blank.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/cgi (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/cgi.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/class (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/class.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/class/attribute_accessors.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/class/removal.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/date (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/date.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/date/conversions.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/enumerable.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/exception.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/hash (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/hash.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/hash/conversions.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/hash/diff.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/hash/indifferent_access.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/hash/keys.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/hash/reverse_merge.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/integer (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/integer.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/integer/even_odd.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/integer/inflections.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/kernel (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/kernel.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/kernel/agnostics.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/kernel/daemonizing.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/kernel/reporting.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/kernel/requires.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/load_error.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/logger.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/module (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/module.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/module/attribute_accessors.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/module/delegation.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/module/inclusion.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/numeric (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/numeric.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/numeric/bytes.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/numeric/time.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/object (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/object.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/object/extending.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/object/misc.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/proc.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/range (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/range.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/range/conversions.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/string (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/string.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/string/access.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/string/conversions.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/string/inflections.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/string/iterators.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/string/starts_ends_with.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/symbol.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/time (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/time.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/time/calculations.rb (added)
-
vendor/rails/activesupport/lib/active_support/core_ext/time/conversions.rb (added)
-
vendor/rails/activesupport/lib/active_support/dependencies.rb (added)
-
vendor/rails/activesupport/lib/active_support/inflections.rb (added)
-
vendor/rails/activesupport/lib/active_support/inflector.rb (added)
-
vendor/rails/activesupport/lib/active_support/json (added)
-
vendor/rails/activesupport/lib/active_support/json.rb (added)
-
vendor/rails/activesupport/lib/active_support/json/encoders (added)
-
vendor/rails/activesupport/lib/active_support/json/encoders.rb (added)
-
vendor/rails/activesupport/lib/active_support/json/encoders/core.rb (added)
-
vendor/rails/activesupport/lib/active_support/option_merger.rb (added)
-
vendor/rails/activesupport/lib/active_support/ordered_options.rb (added)
-
vendor/rails/activesupport/lib/active_support/reloadable.rb (added)
-
vendor/rails/activesupport/lib/active_support/values (added)
-
vendor/rails/activesupport/lib/active_support/values/time_zone.rb (added)
-
vendor/rails/activesupport/lib/active_support/vendor (added)
-
vendor/rails/activesupport/lib/active_support/vendor/builder (added)
-
vendor/rails/activesupport/lib/active_support/vendor/builder.rb (added)
-
vendor/rails/activesupport/lib/active_support/vendor/builder/blankslate.rb (added)
-
vendor/rails/activesupport/lib/active_support/vendor/builder/xmlbase.rb (added)
-
vendor/rails/activesupport/lib/active_support/vendor/builder/xmlevents.rb (added)
-
vendor/rails/activesupport/lib/active_support/vendor/builder/xmlmarkup.rb (added)
-
vendor/rails/activesupport/lib/active_support/version.rb (added)
-
vendor/rails/activesupport/lib/active_support/whiny_nil.rb (added)
-
vendor/rails/railties (added)
-
vendor/rails/railties/lib (added)
-
vendor/rails/railties/lib/binding_of_caller.rb (added)
-
vendor/rails/railties/lib/breakpoint.rb (added)
-
vendor/rails/railties/lib/breakpoint_client.rb (added)
-
vendor/rails/railties/lib/code_statistics.rb (added)
-
vendor/rails/railties/lib/commands (added)
-
vendor/rails/railties/lib/commands.rb (added)
-
vendor/rails/railties/lib/commands/about.rb (added)
-
vendor/rails/railties/lib/commands/breakpointer.rb (added)
-
vendor/rails/railties/lib/commands/console.rb (added)
-
vendor/rails/railties/lib/commands/destroy.rb (added)
-
vendor/rails/railties/lib/commands/generate.rb (added)
-
vendor/rails/railties/lib/commands/ncgi (added)
-
vendor/rails/railties/lib/commands/ncgi/listener (added)
-
vendor/rails/railties/lib/commands/ncgi/tracker (added)
-
vendor/rails/railties/lib/commands/performance (added)
-
vendor/rails/railties/lib/commands/performance/benchmarker.rb (added)
-
vendor/rails/railties/lib/commands/performance/profiler.rb (added)
-
vendor/rails/railties/lib/commands/plugin.rb (added)
-
vendor/rails/railties/lib/commands/process (added)
-
vendor/rails/railties/lib/commands/process/reaper.rb (added)
-
vendor/rails/railties/lib/commands/process/spawner.rb (added)
-
vendor/rails/railties/lib/commands/process/spinner.rb (added)
-
vendor/rails/railties/lib/commands/runner.rb (added)
-
vendor/rails/railties/lib/commands/server.rb (added)
-
vendor/rails/railties/lib/commands/servers (added)
-
vendor/rails/railties/lib/commands/servers/lighttpd.rb (added)
-
vendor/rails/railties/lib/commands/servers/webrick.rb (added)
-
vendor/rails/railties/lib/commands/update.rb (added)
-
vendor/rails/railties/lib/console_app.rb (added)
-
vendor/rails/railties/lib/console_sandbox.rb (added)
-
vendor/rails/railties/lib/dispatcher.rb (added)
-
vendor/rails/railties/lib/fcgi_handler.rb (added)
-
vendor/rails/railties/lib/initializer.rb (added)
-
vendor/rails/railties/lib/rails_generator (added)
-
vendor/rails/railties/lib/rails_generator.rb (added)
-
vendor/rails/railties/lib/rails_generator/base.rb (added)
-
vendor/rails/railties/lib/rails_generator/commands.rb (added)
-
vendor/rails/railties/lib/rails_generator/generators (added)
-
vendor/rails/railties/lib/rails_generator/generators/applications (added)
-
vendor/rails/railties/lib/rails_generator/generators/applications/app (added)
-
vendor/rails/railties/lib/rails_generator/generators/applications/app/USAGE (added)
-
vendor/rails/railties/lib/rails_generator/generators/applications/app/app_generator.rb (added)
-
vendor/rails/railties/lib/rails_generator/generators/components (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/controller (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/controller/USAGE (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/controller/controller_generator.rb (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/controller/templates (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/controller/templates/controller.rb (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/controller/templates/functional_test.rb (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/controller/templates/helper.rb (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/controller/templates/view.rhtml (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/mailer (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/mailer/USAGE (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/mailer/mailer_generator.rb (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/mailer/templates (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/mailer/templates/fixture.rhtml (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/mailer/templates/mailer.rb (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/mailer/templates/unit_test.rb (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/mailer/templates/view.rhtml (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/migration (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/migration/USAGE (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/migration/migration_generator.rb (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/migration/templates (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/migration/templates/migration.rb (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/model (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/model/USAGE (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/model/model_generator.rb (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/model/templates (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/model/templates/fixtures.yml (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/model/templates/migration.rb (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/model/templates/model.rb (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/model/templates/unit_test.rb (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/plugin (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/plugin/USAGE (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/plugin/plugin_generator.rb (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/plugin/templates (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/plugin/templates/README (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/plugin/templates/Rakefile (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/plugin/templates/USAGE (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/plugin/templates/generator.rb (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/plugin/templates/init.rb (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/plugin/templates/install.rb (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/plugin/templates/plugin.rb (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/plugin/templates/tasks.rake (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/plugin/templates/unit_test.rb (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/scaffold (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/scaffold/USAGE (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/controller.rb (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/form.rhtml (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/form_scaffolding.rhtml (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/functional_test.rb (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/helper.rb (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/layout.rhtml (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/style.css (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/view_edit.rhtml (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/view_list.rhtml (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/view_new.rhtml (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/scaffold/templates/view_show.rhtml (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/session_migration (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/session_migration/USAGE (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/session_migration/session_migration_generator.rb (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/session_migration/templates (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/session_migration/templates/migration.rb (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/web_service (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/web_service/USAGE (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/web_service/templates (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/web_service/templates/api_definition.rb (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/web_service/templates/controller.rb (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/web_service/templates/functional_test.rb (added)
-
vendor/rails/railties/lib/rails_generator/generators/components/web_service/web_service_generator.rb (added)
-
vendor/rails/railties/lib/rails_generator/lookup.rb (added)
-
vendor/rails/railties/lib/rails_generator/manifest.rb (added)
-
vendor/rails/railties/lib/rails_generator/options.rb (added)
-
vendor/rails/railties/lib/rails_generator/scripts (added)
-
vendor/rails/railties/lib/rails_generator/scripts.rb (added)
-
vendor/rails/railties/lib/rails_generator/scripts/destroy.rb (added)
-
vendor/rails/railties/lib/rails_generator/scripts/generate.rb (added)
-
vendor/rails/railties/lib/rails_generator/scripts/update.rb (added)
-
vendor/rails/railties/lib/rails_generator/simple_logger.rb (added)
-
vendor/rails/railties/lib/rails_generator/spec.rb (added)
-
vendor/rails/railties/lib/rails_info.rb (added)
-
vendor/rails/railties/lib/rails_version.rb (added)
-
vendor/rails/railties/lib/railties_path.rb (added)
-
vendor/rails/railties/lib/rubyprof_ext.rb (added)
-
vendor/rails/railties/lib/tasks (added)
-
vendor/rails/railties/lib/tasks/databases.rake (added)
-
vendor/rails/railties/lib/tasks/documentation.rake (added)
-
vendor/rails/railties/lib/tasks/framework.rake (added)
-
vendor/rails/railties/lib/tasks/log.rake (added)
-
vendor/rails/railties/lib/tasks/misc.rake (added)
-
vendor/rails/railties/lib/tasks/pre_namespace_aliases.rake (added)
-
vendor/rails/railties/lib/tasks/rails.rb (added)
-
vendor/rails/railties/lib/tasks/statistics.rake (added)
-
vendor/rails/railties/lib/tasks/testing.rake (added)
-
vendor/rails/railties/lib/tasks/tmp.rake (added)
-
vendor/rails/railties/lib/test_help.rb (added)
-
vendor/rails/railties/lib/webrick_server.rb (added)
-
vendor/railties (deleted)
-
vendor/semanticrecord/lib/semantic_record.rb (modified) (1 diff)
-
vendor/semanticrecord/lib/semantic_record/core_ext (added)
-
vendor/semanticrecord/lib/semantic_record/core_ext/string.rb (added)
Legend:
- Unmodified
- Added
- Removed
-
trunk/README
r5 r39 1 1 == Welcome to Rails 2 2 3 Rails is a web-application and persist ance framework that includes everything3 Rails is a web-application and persistence framework that includes everything 4 4 needed to create database-backed web-applications according to the 5 5 Model-View-Control pattern of separation. This pattern splits the view (also 6 6 called the presentation) into "dumb" templates that are primarily responsible 7 for inserting pre-buil ddata in between HTML tags. The model contains the7 for inserting pre-built data in between HTML tags. The model contains the 8 8 "smart" domain objects (such as Account, Product, Person, Post) that holds all 9 9 the business logic and knows how to persist themselves to a database. The … … 11 11 Product, Show Post) by manipulating the model and directing data to the view. 12 12 13 In Rails, the model is handled by what's called a object-relational mapping13 In Rails, the model is handled by what's called an object-relational mapping 14 14 layer entitled Active Record. This layer allows you to present the data from 15 15 database rows as objects and embellish these data objects with business logic … … 17 17 link:files/vendor/rails/activerecord/README.html. 18 18 19 The controller and view ishandled by the Action Pack, which handles both19 The controller and view are handled by the Action Pack, which handles both 20 20 layers by its two parts: Action View and Action Controller. These two layers 21 21 are bundled in a single package due to their heavy interdependence. This is … … 26 26 27 27 28 == Requirements29 30 * Database and driver (MySQL, PostgreSQL, or SQLite)31 * Rake[http://rake.rubyforge.org] for running tests and the generating documentation32 33 == Optionals34 35 * Apache 1.3.x or 2.x or lighttpd 1.3.11+ (or any FastCGI-capable webserver with a36 mod_rewrite-like module)37 * FastCGI (or mod_ruby) for better performance on Apache38 39 28 == Getting started 40 29 41 1. Run the WEBrick servlet: <tt>ruby script/server</tt> 42 (run with --help for options)30 1. Run the WEBrick servlet: <tt>ruby script/server</tt> (run with --help for options) 31 ...or if you have lighttpd installed: <tt>ruby script/lighttpd</tt> (it's faster) 43 32 2. Go to http://localhost:3000/ and get "Congratulations, you've put Ruby on Rails!" 44 33 3. Follow the guidelines on the "Congratulations, you've put Ruby on Rails!" screen … … 61 50 62 51 NOTE: Be sure that CGIs can be executed in that directory as well. So ExecCGI 63 should be on and ".cgi" should respond. All requests from 127.0.0.1 go es52 should be on and ".cgi" should respond. All requests from 127.0.0.1 go 64 53 through CGI, so no Apache restart is necessary for changes. All other requests 65 go es through FCGI (or mod_ruby) that requiresrestart to show changes.54 go through FCGI (or mod_ruby), which requires a restart to show changes. 66 55 67 68 == Example for lighttpd conf (with FastCGI)69 70 server.port = 808071 server.bind = "127.0.0.1"72 # server.event-handler = "freebsd-kqueue" # needed on OS X73 74 server.modules = ( "mod_rewrite", "mod_fastcgi" )75 76 url.rewrite = ( "^/$" => "index.html", "^([^.]+)$" => "$1.html" )77 server.error-handler-404 = "/dispatch.fcgi"78 79 server.document-root = "/path/application/public"80 server.errorlog = "/path/application/log/server.log"81 82 fastcgi.server = ( ".fcgi" =>83 ( "localhost" =>84 (85 "min-procs" => 1,86 "max-procs" => 5,87 "socket" => "/tmp/application.fcgi.socket",88 "bin-path" => "/path/application/public/dispatch.fcgi",89 "bin-environment" => ( "RAILS_ENV" => "development" )90 )91 )92 )93 94 56 95 57 == Debugging Rails … … 140 102 Here you'll have all parts of the application configured, just like it is when the 141 103 application is running. You can inspect domain models, change values, and save to the 142 database. Start the script without arguments will launch it in the development environment.104 database. Starting the script without arguments will launch it in the development environment. 143 105 Passing an argument will specify a different environment, like <tt>console production</tt>. 144 106 … … 156 118 app/models 157 119 Holds models that should be named like post.rb. 158 Most models will descen tfrom ActiveRecord::Base.120 Most models will descend from ActiveRecord::Base. 159 121 160 122 app/views 161 123 Holds the template files for the view that should be named like 162 weblog/index.rhtml for the WeblogController#index action. All views use seRuby124 weblog/index.rhtml for the WeblogController#index action. All views use eRuby 163 125 syntax. This directory can also be used to keep stylesheets, images, and so on 164 126 that can be symlinked to public. … … 171 133 172 134 components 173 Self-contained mini-applications that can bundle controllers, models, and views together.135 Self-contained mini-applications that can bundle together controllers, models, and views. 174 136 175 137 lib 176 138 Application specific libraries. Basically, any kind of custom code that doesn't 177 belong controllers, models, or helpers. This directory is in the load path.139 belong under controllers, models, or helpers. This directory is in the load path. 178 140 179 141 public 180 The directory available for the web server. Contains sub -directories for images, stylesheets,142 The directory available for the web server. Contains subdirectories for images, stylesheets, 181 143 and javascripts. Also contains the dispatchers and the default HTML files. 182 144 … … 188 150 189 151 vendor 190 External libraries that the application depend on. This directory is in the load path. 152 External libraries that the application depends on. Also includes the plugins subdirectory. 153 This directory is in the load path. -
trunk/Rakefile
r5 r39 1 # Add your own tasks in files placed in lib/tasks ending in .rake, 2 # for example lib/tasks/switchtower.rake, and they will automatically be available to Rake. 3 4 require(File.join(File.dirname(__FILE__), 'config', 'boot')) 5 1 6 require 'rake' 2 7 require 'rake/testtask' 3 8 require 'rake/rdoctask' 4 9 5 $VERBOSE = nil 6 TEST_CHANGES_SINCE = Time.now - 600 7 8 desc "Run all the tests on a fresh test database" 9 task :default => [ :test_units, :test_functional ] 10 11 12 desc 'Require application environment.' 13 task :environment do 14 unless defined? RAILS_ROOT 15 require File.dirname(__FILE__) + '/config/environment' 16 end 17 end 18 19 desc "Generate API documentation, show coding stats" 20 task :doc => [ :appdoc, :stats ] 21 22 23 # Look up tests for recently modified sources. 24 def recent_tests(source_pattern, test_path, touched_since = 10.minutes.ago) 25 FileList[source_pattern].map do |path| 26 if File.mtime(path) > touched_since 27 test = "#{test_path}/#{File.basename(path, '.rb')}_test.rb" 28 test if File.exists?(test) 29 end 30 end.compact 31 end 32 33 desc 'Test recent changes.' 34 Rake::TestTask.new(:recent => [ :clone_structure_to_test ]) do |t| 35 since = TEST_CHANGES_SINCE 36 touched = FileList['test/**/*_test.rb'].select { |path| File.mtime(path) > since } + 37 recent_tests('app/models/*.rb', 'test/unit', since) + 38 recent_tests('app/controllers/*.rb', 'test/functional', since) 39 40 t.libs << 'test' 41 t.verbose = true 42 t.test_files = touched.uniq 43 end 44 task :test_recent => [ :clone_structure_to_test ] 45 46 desc "Run the unit tests in test/unit" 47 Rake::TestTask.new("test_units") { |t| 48 t.libs << "test" 49 t.pattern = 'test/unit/**/*_test.rb' 50 t.verbose = true 51 } 52 task :test_units => [ :clone_structure_to_test ] 53 54 desc "Run the functional tests in test/functional" 55 Rake::TestTask.new("test_functional") { |t| 56 t.libs << "test" 57 t.pattern = 'test/functional/**/*_test.rb' 58 t.verbose = true 59 } 60 task :test_functional => [ :clone_structure_to_test ] 61 62 desc "Generate documentation for the application" 63 Rake::RDocTask.new("appdoc") { |rdoc| 64 rdoc.rdoc_dir = 'doc/app' 65 rdoc.title = "Rails Application Documentation" 66 rdoc.options << '--line-numbers --inline-source' 67 rdoc.rdoc_files.include('doc/README_FOR_APP') 68 rdoc.rdoc_files.include('app/**/*.rb') 69 } 70 71 desc "Generate documentation for the Rails framework" 72 Rake::RDocTask.new("apidoc") { |rdoc| 73 rdoc.rdoc_dir = 'doc/api' 74 rdoc.template = "#{ENV['template']}.rb" if ENV['template'] 75 rdoc.title = "Rails Framework Documentation" 76 rdoc.options << '--line-numbers --inline-source' 77 rdoc.rdoc_files.include('README') 78 rdoc.rdoc_files.include('CHANGELOG') 79 rdoc.rdoc_files.include('vendor/rails/railties/CHANGELOG') 80 rdoc.rdoc_files.include('vendor/rails/railties/MIT-LICENSE') 81 rdoc.rdoc_files.include('vendor/rails/activerecord/README') 82 rdoc.rdoc_files.include('vendor/rails/activerecord/CHANGELOG') 83 rdoc.rdoc_files.include('vendor/rails/activerecord/lib/active_record/**/*.rb') 84 rdoc.rdoc_files.exclude('vendor/rails/activerecord/lib/active_record/vendor/*') 85 rdoc.rdoc_files.include('vendor/rails/actionpack/README') 86 rdoc.rdoc_files.include('vendor/rails/actionpack/CHANGELOG') 87 rdoc.rdoc_files.include('vendor/rails/actionpack/lib/action_controller/**/*.rb') 88 rdoc.rdoc_files.include('vendor/rails/actionpack/lib/action_view/**/*.rb') 89 rdoc.rdoc_files.include('vendor/rails/actionmailer/README') 90 rdoc.rdoc_files.include('vendor/rails/actionmailer/CHANGELOG') 91 rdoc.rdoc_files.include('vendor/rails/actionmailer/lib/action_mailer/base.rb') 92 rdoc.rdoc_files.include('vendor/rails/actionwebservice/README') 93 rdoc.rdoc_files.include('vendor/rails/actionwebservice/CHANGELOG') 94 rdoc.rdoc_files.include('vendor/rails/actionwebservice/lib/action_web_service.rb') 95 rdoc.rdoc_files.include('vendor/rails/actionwebservice/lib/action_web_service/*.rb') 96 rdoc.rdoc_files.include('vendor/rails/actionwebservice/lib/action_web_service/api/*.rb') 97 rdoc.rdoc_files.include('vendor/rails/actionwebservice/lib/action_web_service/client/*.rb') 98 rdoc.rdoc_files.include('vendor/rails/actionwebservice/lib/action_web_service/container/*.rb') 99 rdoc.rdoc_files.include('vendor/rails/actionwebservice/lib/action_web_service/dispatcher/*.rb') 100 rdoc.rdoc_files.include('vendor/rails/actionwebservice/lib/action_web_service/protocol/*.rb') 101 rdoc.rdoc_files.include('vendor/rails/actionwebservice/lib/action_web_service/support/*.rb') 102 rdoc.rdoc_files.include('vendor/rails/activesupport/README') 103 rdoc.rdoc_files.include('vendor/rails/activesupport/CHANGELOG') 104 rdoc.rdoc_files.include('vendor/rails/activesupport/lib/active_support/**/*.rb') 105 } 106 107 desc "Report code statistics (KLOCs, etc) from the application" 108 task :stats => [ :environment ] do 109 require 'code_statistics' 110 CodeStatistics.new( 111 ["Helpers", "app/helpers"], 112 ["Controllers", "app/controllers"], 113 ["APIs", "app/apis"], 114 ["Components", "components"], 115 ["Functionals", "test/functional"], 116 ["Models", "app/models"], 117 ["Units", "test/unit"] 118 ).to_s 119 end 120 121 desc "Recreate the test databases from the development structure" 122 task :clone_structure_to_test => [ :db_structure_dump, :purge_test_database ] do 123 abcs = ActiveRecord::Base.configurations 124 case abcs["test"]["adapter"] 125 when "mysql" 126 ActiveRecord::Base.establish_connection(:test) 127 ActiveRecord::Base.connection.execute('SET foreign_key_checks = 0') 128 IO.readlines("db/#{RAILS_ENV}_structure.sql").join.split("\n\n").each do |table| 129 ActiveRecord::Base.connection.execute(table) 130 end 131 when "postgresql" 132 ENV['PGHOST'] = abcs["test"]["host"] if abcs["test"]["host"] 133 ENV['PGPORT'] = abcs["test"]["port"].to_s if abcs["test"]["port"] 134 ENV['PGPASSWORD'] = abcs["test"]["password"].to_s if abcs["test"]["password"] 135 `psql -U "#{abcs["test"]["username"]}" -f db/#{RAILS_ENV}_structure.sql #{abcs["test"]["database"]}` 136 when "sqlite", "sqlite3" 137 `#{abcs[RAILS_ENV]["adapter"]} #{abcs["test"]["dbfile"]} < db/#{RAILS_ENV}_structure.sql` 138 when "sqlserver" 139 `osql -E -S #{abcs["test"]["host"]} -d #{abcs["test"]["database"]} -i db\\#{RAILS_ENV}_structure.sql` 140 else 141 raise "Unknown database adapter '#{abcs["test"]["adapter"]}'" 142 end 143 end 144 145 desc "Dump the database structure to a SQL file" 146 task :db_structure_dump => :environment do 147 abcs = ActiveRecord::Base.configurations 148 case abcs[RAILS_ENV]["adapter"] 149 when "mysql" 150 ActiveRecord::Base.establish_connection(abcs[RAILS_ENV]) 151 File.open("db/#{RAILS_ENV}_structure.sql", "w+") { |f| f << ActiveRecord::Base.connection.structure_dump } 152 when "postgresql" 153 ENV['PGHOST'] = abcs[RAILS_ENV]["host"] if abcs[RAILS_ENV]["host"] 154 ENV['PGPORT'] = abcs[RAILS_ENV]["port"].to_s if abcs[RAILS_ENV]["port"] 155 ENV['PGPASSWORD'] = abcs[RAILS_ENV]["password"].to_s if abcs[RAILS_ENV]["password"] 156 `pg_dump -U "#{abcs[RAILS_ENV]["username"]}" -s -x -O -f db/#{RAILS_ENV}_structure.sql #{abcs[RAILS_ENV]["database"]}` 157 when "sqlite", "sqlite3" 158 `#{abcs[RAILS_ENV]["adapter"]} #{abcs[RAILS_ENV]["dbfile"]} .schema > db/#{RAILS_ENV}_structure.sql` 159 when "sqlserver" 160 `scptxfr /s #{abcs[RAILS_ENV]["host"]} /d #{abcs[RAILS_ENV]["database"]} /I /f db\\#{RAILS_ENV}_structure.sql /q /A /r` 161 `scptxfr /s #{abcs[RAILS_ENV]["host"]} /d #{abcs[RAILS_ENV]["database"]} /I /F db\ /q /A /r` 162 else 163 raise "Unknown database adapter '#{abcs["test"]["adapter"]}'" 164 end 165 end 166 167 desc "Empty the test database" 168 task :purge_test_database => :environment do 169 abcs = ActiveRecord::Base.configurations 170 case abcs["test"]["adapter"] 171 when "mysql" 172 ActiveRecord::Base.establish_connection(:test) 173 ActiveRecord::Base.connection.recreate_database(abcs["test"]["database"]) 174 when "postgresql" 175 ENV['PGHOST'] = abcs["test"]["host"] if abcs["test"]["host"] 176 ENV['PGPORT'] = abcs["test"]["port"].to_s if abcs["test"]["port"] 177 ENV['PGPASSWORD'] = abcs["test"]["password"].to_s if abcs["test"]["password"] 178 `dropdb -U "#{abcs["test"]["username"]}" #{abcs["test"]["database"]}` 179 `createdb -T template0 -U "#{abcs["test"]["username"]}" #{abcs["test"]["database"]}` 180 when "sqlite","sqlite3" 181 File.delete(abcs["test"]["dbfile"]) if File.exist?(abcs["test"]["dbfile"]) 182 when "sqlserver" 183 dropfkscript = "#{abcs["test"]["host"]}.#{abcs["test"]["database"]}.DP1".gsub(/\\/,'-') 184 `osql -E -S #{abcs["test"]["host"]} -d #{abcs["test"]["database"]} -i db\\#{dropfkscript}` 185 `osql -E -S #{abcs["test"]["host"]} -d #{abcs["test"]["database"]} -i db\\#{RAILS_ENV}_structure.sql` 186 else 187 raise "Unknown database adapter '#{abcs["test"]["adapter"]}'" 188 end 189 end 190 191 desc "Clears all *.log files in log/" 192 task :clear_logs => :environment do 193 FileList["log/*.log"].each do |log_file| 194 f = File.open(log_file, "w") 195 f.close 196 end 197 end 198 199 desc "Migrate the database according to the migrate scripts in db/migrate (only supported on PG/MySQL). A specific version can be targetted with VERSION=x" 200 task :migrate => :environment do 201 ActiveRecord::Migrator.migrate(File.dirname(__FILE__) + '/db/migrate/', ENV["VERSION"] ? ENV["VERSION"].to_i : nil) 202 end 10 require 'tasks/rails' -
trunk/app/controllers/navigation_controller.rb
r16 r39 22 22 redirect_to :action => action_for_landmark(lm), 23 23 :id => lm.target_id, 24 :params => { "params"=> lm.params_values }24 :params => { :p => lm.params_values } 25 25 else 26 26 redirect_to :controller => "nav_class" … … 31 31 id = @params["id"] 32 32 id ? @index = Index.find(id) : @index = Index.find_first 33 params = @params[ "params"]33 params = @params[:p] 34 34 @index.entries(params ? params.split(",") : nil) 35 35 @page_title = "#{@index.name}" … … 42 42 id ? @context = Context.find(id) : @context = Context.find_first 43 43 @context.position = position.to_i 44 params = @params[ "params"]44 params = @params[:p] 45 45 @context.nodes(params ? params.split(",") : nil) 46 46 … … 131 131 132 132 def set_return_to_current 133 self.return_to = url_for :params => { "params" => @params["params"]}133 self.return_to = url_for :params => { :p => @params[:p]} 134 134 end 135 135 … … 149 149 bc_cookie = @cookies["breadcrumb"] 150 150 @breadcrumb = Breadcrumb.new(bc_cookie) 151 @breadcrumb.add(action_name, @params["id"], @params[ "params"], @page_title)151 @breadcrumb.add(action_name, @params["id"], @params[:p], @page_title) 152 152 end 153 153 -
trunk/app/helpers/hyperde/breadcrumb.rb
r1 r39 18 18 @label = view.truncate(bc["title"]) 19 19 @url = view.url_for(:action => bc["action"], :id => bc["id"], 20 :params => params_for_anchor(bc[ "params"]))20 :params => params_for_anchor(bc[:p])) 21 21 @ahref = view.link_to(@label, :action => bc["action"], :id => bc["id"], 22 :params => params_for_anchor(bc[ "params"]))22 :params => params_for_anchor(bc[:p])) 23 23 end 24 24 end … … 37 37 def add(action, id, params, title) 38 38 last = @entries.last 39 new = { "action" => action, "id" => id, "params"=> params, "title" => title }39 new = { "action" => action, "id" => id, :p => params, "title" => title } 40 40 if (strip(new) == strip(last)) 41 41 @entries.pop … … 58 58 def serialize 59 59 values = [] 60 @entries.each { |e| values << [e["action"], e["id"], e[ "params"], e["title"]].join('&') }60 @entries.each { |e| values << [e["action"], e["id"], e[:p], e["title"]].join('&') } 61 61 values 62 62 end … … 66 66 serialized_bc.each do |c| 67 67 data = c.split("&") 68 hash = { "action" => data[0], "id" => data[1], "params"=> data[2] && data[2].length > 0 ? data[2] : nil, "title" => data[3] }68 hash = { "action" => data[0], "id" => data[1], :p => data[2] && data[2].length > 0 ? data[2] : nil, "title" => data[3] } 69 69 @entries << hash 70 70 end -
trunk/app/helpers/hyperde/context.rb
r1 r39 121 121 @url = view.url_for(:controller => "navigation", :action => "context", 122 122 :id => "#{Context.full_id(context, @position)}", 123 :params => params_for_anchor(view.params[ "params"]))123 :params => params_for_anchor(view.params[:p])) 124 124 125 125 @ahref = view.link_to(@label, :controller => "navigation", :action => "context", 126 126 :id => "#{Context.full_id(context, @position)}", 127 :params => params_for_anchor(view.params[ "params"]))127 :params => params_for_anchor(view.params[:p])) 128 128 end 129 129 -
trunk/app/helpers/hyperde/node.rb
r19 r39 85 85 options[:url] ||= { :action => "context", :op => op_name, 86 86 :view => options[:view], 87 :params => params_for_anchor(view.params[ "params"]) }87 :params => params_for_anchor(view.params[:p]) } 88 88 options[:with] ||= "Form.serialize(document.forms[0])" 89 89 options[:complete] ||= "window.location.reload()" unless options[:update] -
trunk/app/helpers/hyperde_helper.rb
r1 r39 151 151 ret = [] 152 152 params.each { |p| ret << p if p } if params 153 { "params"=> ret.length == 0 ? nil : ret.join(',') }153 { :p => ret.length == 0 ? nil : ret.join(',') } 154 154 end 155 155 -
trunk/app/helpers/navigation_helper.rb
r1 r39 5 5 for op_name, op in node.nav_operations 6 6 buffer << "<span class=operation> [" 7 buffer << link_to(op_name, :id => @params["id"], :params => { "params" => @params["params"], "operation" => op_name })7 buffer << link_to(op_name, :id => @params["id"], :params => { :p => @params[:p], "operation" => op_name }) 8 8 buffer << "] </span>" 9 9 end … … 93 93 ret = [] 94 94 params.each { |p| ret << p if p } if params 95 { "params"=> ret.length == 0 ? nil : ret.join(',') }95 { :p => ret.length == 0 ? nil : ret.join(',') } 96 96 end 97 97 … … 162 162 def render_context_index(context) 163 163 buffer = "" 164 buffer << render_index(context.index, @params[ "params"], context.position, 9, 20)164 buffer << render_index(context.index, @params[:p], context.position, 9, 20) 165 165 buffer 166 166 end … … 188 188 :controller => "navigation", :action => "context", 189 189 :id => "#{Context.full_id(context,context.position-1)}", 190 :params => params_for_anchor(@params[ "params"]) )190 :params => params_for_anchor(@params[:p]) ) 191 191 else 192 192 buffer << " " … … 199 199 buffer = "<span id=next_link>" 200 200 if !context.on_last? 201 buffer << link_to("#{truncate(context.next.label)} >>", :controller => "navigation", :action => "context", :id => "#{Context.full_id(context,context.position+1)}", :params => params_for_anchor(@params[ "params"]) )201 buffer << link_to("#{truncate(context.next.label)} >>", :controller => "navigation", :action => "context", :id => "#{Context.full_id(context,context.position+1)}", :params => params_for_anchor(@params[:p]) ) 202 202 else 203 203 buffer << " " … … 228 228 buffer << separator if separator 229 229 buffer << "<span class=breadcrumb_item>" 230 buffer << link_to(truncate(bc["title"]), :action => bc["action"], :id => bc["id"], :params => params_for_anchor(bc[ "params"]))230 buffer << link_to(truncate(bc["title"]), :action => bc["action"], :id => bc["id"], :params => params_for_anchor(bc[:p])) 231 231 buffer << "</span>" 232 232 end … … 259 259 :action => @controller.action_name, \ 260 260 :id => @params["id"], \ 261 :params => { "params" => @params["params"] } ) } )261 :params => { :p => @params[:p] } ) } ) 262 262 buffer << "]</span>" 263 263 end -
trunk/app/models/node.rb
r28 r39 156 156 end 157 157 158 alias read_std_attribute read_attribute159 160 158 def read_attribute(attr_name) 161 val = read_std_attribute(attr_name)159 val = super(attr_name) 162 160 if val.nil? 163 161 attr_def = nav_attributes[attr_name] -
trunk/config/environment.rb
r28 r39 1 # Be sure to restart your web server when you modify this file. 2 3 # Uncomment below to force Rails into production mode when 4 # you don't control web/app server and can't set it the proper way 5 # ENV['RAILS_ENV'] ||= 'production' 6 7 # Bootstrap the Rails environment, frameworks, and default configuration 8 require File.join(File.dirname(__FILE__), 'boot') 9 10 Rails::Initializer.run do |config| 11 # Settings in config/environments/* take precedence those specified here 12 13 # Skip frameworks you're not going to use 14 config.frameworks -= [ :action_web_service, :action_mailer, :active_record ] 15 16 # Add additional load paths for your own custom dirs 17 config.load_paths += %W( #{RAILS_ROOT}/vendor/semanticrecord/lib ) 18 19 # Force all environments to use the same logger level 20 # (by default production uses :info, the others :debug) 21 # config.log_level = :debug 22 23 # Use the database for sessions instead of the file system 24 # (create the session table with 'rake create_sessions_table') 25 # config.action_controller.session_store = :active_record_store 26 27 # Enable page/fragment caching by setting a file-based store 28 # (remember to create the caching directory and make it readable to the application) 29 # config.action_controller.fragment_cache_store = :file_store, "#{RAILS_ROOT}/cache" 30 31 # Activate observers that should always be running 32 # config.active_record.observers = :cacher, :garbage_collector 33 34 # Make Active Record use UTC-base instead of local time 35 # config.active_record.default_timezone = :utc 36 37 # Use Active Record's schema dumper instead of SQL when creating the test database 38 # (enables use of different database adapters for development and test environments) 39 # config.active_record.schema_format = :ruby 40 41 # See Rails::Configuration for more options 42 end 43 44 # Add new inflection rules using the following format 45 # (all these examples are active by default): 46 # Inflector.inflections do |inflect| 47 # inflect.plural /^(ox)$/i, '\1en' 48 # inflect.singular /^(ox)en/i, '\1' 49 # inflect.irregular 'person', 'people' 50 # inflect.uncountable %w( fish sheep ) 51 # end 52 53 # Include your application configuration below 1 54 $KCODE = 'u' 2 55 require 'jcode' 3 4 # Load the Rails framework and configure your application.5 # You can include your own configuration at the end of this file.6 #7 # Be sure to restart your webserver when you modify this file.8 9 # The path to the root directory of your application.10 RAILS_ROOT = File.join(File.dirname(__FILE__), '..')11 12 # The environment your application is currently running. Don't set13 # this here; put it in your webserver's configuration as the RAILS_ENV14 # environment variable instead.15 #16 # See config/environments/*.rb for environment-specific configuration.17 RAILS_ENV = ENV['RAILS_ENV'] || 'development'18 19 20 # Load the Rails framework. Mock classes for testing come first.21 ADDITIONAL_LOAD_PATHS = ["#{RAILS_ROOT}/test/mocks/#{RAILS_ENV}"]22 23 # Then model subdirectories.24 ADDITIONAL_LOAD_PATHS.concat(Dir["#{RAILS_ROOT}/app/models/[_a-z]*"])25 ADDITIONAL_LOAD_PATHS.concat(Dir["#{RAILS_ROOT}/components/[_a-z]*"])26 27 # Followed by the standard includes.28 ADDITIONAL_LOAD_PATHS.concat %w(29 app30 app/models31 app/controllers32 app/helpers33 app/apis34 components35 config36 lib37 vendor38 vendor/railties39 vendor/railties/lib40 vendor/actionpack/lib41 vendor/activesupport/lib42 vendor/semanticrecord/lib43 ).map { |dir| "#{RAILS_ROOT}/#{dir}" }.select { |dir| File.directory?(dir) }44 45 # Prepend to $LOAD_PATH46 ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) }47 48 require 'active_support'49 56 require 'semantic_record' 50 require 'action_controller'51 52 # Environment-specific configuration.53 require_dependency "environments/#{RAILS_ENV}"54 SemanticRecord::Base.configurations = File.open("#{RAILS_ROOT}/config/database.yml") { |f| YAML::load(f) }55 56 # Configure defaults if the included environment did not.57 begin58 RAILS_DEFAULT_LOGGER = Logger.new("#{RAILS_ROOT}/log/#{RAILS_ENV}.log")59 RAILS_DEFAULT_LOGGER.level = (RAILS_ENV == 'production' ? Logger::INFO : Logger::DEBUG)60 rescue StandardError61 RAILS_DEFAULT_LOGGER = Logger.new(STDERR)62 RAILS_DEFAULT_LOGGER.level = Logger::WARN63 RAILS_DEFAULT_LOGGER.warn(64 "Rails Error: Unable to access log file. Please ensure that log/#{RAILS_ENV}.log exists and is chmod 0666. " +65 "The log level has been raised to WARN and the output directed to STDERR until the problem is fixed."66 )67 end68 69 [SemanticRecord, ActionController].each { |mod| mod::Base.logger ||= RAILS_DEFAULT_LOGGER }70 [ActionController].each { |mod| mod::Base.template_root ||= "#{RAILS_ROOT}/app/views/" }71 72 # Set up routes.73 ActionController::Routing::Routes.reload74 75 Controllers = Dependencies::LoadingModule.root(76 File.join(RAILS_ROOT, 'app', 'controllers'),77 File.join(RAILS_ROOT, 'components')78 )79 80 # Include your app's configuration here:81 57 require 'query_builder' 82 58 Dir["#{RAILS_ROOT}/app/models/**.rb"].each { |model| require File.basename(model, ".rb") } 59 SemanticRecord::Base.logger = RAILS_DEFAULT_LOGGER 60 SemanticRecord::Base.configurations = File.open("#{RAILS_ROOT}/config/database.yml") { |f| YAML::load(f) } 83 61 SemanticRecord::Base.save_schema 84 62 NavModelGenerator.new.generate -
trunk/config/environments/development.rb
r5 r39 1 # Settings specified here will take precedence over those in config/environment.rb 2 1 3 # In the development environment your application's code is reloaded on 2 4 # every request. This slows down response time but is perfect for development 3 5 # since you don't have to restart the webserver when you make code changes. 6 config.cache_classes = false 4 7 5 8 # Log error messages when you accidentally call methods on nil. 6 require 'active_support/whiny_nil' 9 config.whiny_nils = true 7 10 8 # Reload code; show full error reports; disable caching. 9 Dependencies.mechanism = :require 10 ActionController::Base.consider_all_requests_local = true 11 ActionController::Base.perform_caching = false 11 # Enable the breakpoint server that script/breakpointer connects to 12 config.breakpoint_server = true 12 13 13 # The breakpoint server port that script/breakpointer connects to. 14 BREAKPOINT_SERVER_PORT = 42531 14 # Show full error reports and disable caching 15 config.action_controller.consider_all_requests_local = true 16 config.action_controller.perform_caching = false 17 18 # Don't care if the mailer can't send 19 config.action_mailer.raise_delivery_errors = false -
trunk/config/environments/production.rb
r5 r39 1 # Settings specified here will take precedence over those in config/environment.rb 2 1 3 # The production environment is meant for finished, "live" apps. 2 # Code is not reloaded between requests , full error reports are disabled,3 # and caching is turned on. 4 # Code is not reloaded between requests 5 config.cache_classes = true 4 6 5 # Don't reload code; don't show full error reports; enable caching. 6 Dependencies.mechanism = :require 7 ActionController::Base.consider_all_requests_local = false 8 ActionController::Base.perform_caching = true 7 # Use a different logger for distributed setups 8 # config.logger = SyslogLogger.new 9 10 11 # Full error reports are disabled and caching is turned on 12 config.action_controller.consider_all_requests_local = false 13 config.action_controller.perform_caching = true 14 15 # Enable serving of images, stylesheets, and javascripts from an asset server 16 # config.action_controller.asset_host = "http://assets.example.com" 17 18 # Disable delivery errors if you bad email addresses should just be ignored 19 # config.action_mailer.raise_delivery_errors = false -
trunk/config/environments/test.rb
r5 r39 1 # Settings specified here will take precedence over those in config/environment.rb 2 1 3 # The test environment is used exclusively to run your application's 2 4 # test suite. You never need to work with it otherwise. Remember that 3 5 # your test database is "scratch space" for the test suite and is wiped 4 6 # and recreated between test runs. Don't rely on the data there! 7 config.cache_classes = true 5 8 6 9 # Log error messages when you accidentally call methods on nil. 7 require 'active_support/whiny_nil' 10 config.whiny_nils = true 8 11 9 # Don't reload code; show full error reports; disable caching. 10 Dependencies.mechanism = :require 11 ActionController::Base.consider_all_requests_local = true 12 ActionController::Base.perform_caching = false 12 # Show full error reports and disable caching 13 config.action_controller.consider_all_requests_local = true 14 config.action_controller.perform_caching = false 13 15 14 16 # Tell ActionMailer not to deliver emails to the real world. 15 17 # The :test delivery method accumulates sent emails in the 16 18 # ActionMailer::Base.deliveries array. 17 ActionMailer::Base.delivery_method= :test19 config.action_mailer.delivery_method = :test -
trunk/config/routes.rb
r5 r39 11 11 map.connect '', :controller => "navigation" 12 12 13 # Allow downloading Web Service WSDL as a file with an extension 14 # instead of a file named 'wsdl' 15 map.connect ':controller/service.wsdl', :action => 'wsdl' 13 16 14 17 # Install the default route as the lowest priority. -
trunk/lib/model_loader.rb
r9 r39 100 100 ctx["params"] ||= [] 101 101 define_parameters(ctx["params"]) do |p_name, p_class| 102 @stdout.puts "Context Parameter: #{p_name}" 102 103 context.parameters.create("name" => p_name, "nav_class" => p_class) 103 104 end … … 121 122 idx["params"] ||= [] 122 123 define_parameters(idx["params"]) do |p_name, p_class| 124 @stdout.puts "Index Parameter: #{p_name}" 123 125 index.parameters.create("name" => p_name, "nav_class" => p_class) 124 126 end -
trunk/public/.htaccess
r5 r39 19 19 # RewriteRule ^(.*)$ dispatch.fcgi [QSA,L] 20 20 RewriteEngine On 21 22 # If your Rails application is accessed via an Alias directive, 23 # then you MUST also set the RewriteBase in this htaccess file. 24 # 25 # Example: 26 # Alias /myrailsapp /path/to/myrailsapp/public 27 # RewriteBase /myrailsapp 28 21 29 RewriteRule ^$ index.html [QSA] 22 30 RewriteRule ^([^.]+)$ $1.html [QSA] -
trunk/public/javascripts/controls.js
r5 r39 1 1 // Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) 2 2 // (c) 2005 Ivan Krstic (http://blogs.law.harvard.edu/ivan) 3 // (c) 2005 Jon Tirsen (http://www.tirsen.com) 4 // Contributors: 5 // Richard Livsey 6 // Rahul Bhargava 7 // Rob Wills 3 8 // 4 // Permission is hereby granted, free of charge, to any person obtaining 5 // a copy of this software and associated documentation files (the 6 // "Software"), to deal in the Software without restriction, including 7 // without limitation the rights to use, copy, modify, merge, publish, 8 // distribute, sublicense, and/or sell copies of the Software, and to 9 // permit persons to whom the Software is furnished to do so, subject to 10 // the following conditions: 11 // 12 // The above copyright notice and this permission notice shall be 13 // included in all copies or substantial portions of the Software. 14 // 15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 23 Element.collectTextNodesIgnoreClass = function(element, ignoreclass) { 24 var children = $(element).childNodes; 25 var text = ""; 26 var classtest = new RegExp("^([^ ]+ )*" + ignoreclass+ "( [^ ]+)*$","i"); 27 28 for (var i = 0; i < children.length; i++) { 29 if(children[i].nodeType==3) { 30 text+=children[i].nodeValue; 31 } else { 32 if((!children[i].className.match(classtest)) && children[i].hasChildNodes()) 33 text += Element.collectTextNodesIgnoreClass(children[i], ignoreclass); 34 } 35 } 36 37 return text; 38 } 9 // See scriptaculous.js for full license. 39 10 40 11 // Autocompleter.Base handles all the autocompletion functionality … … 47 18 // the text inside the monitored textbox changes. This method 48 19 // should get the text for which to provide autocompletion by 49 // invoking this.get Entry(), NOT by directly accessing20 // invoking this.getToken(), NOT by directly accessing 50 21 // this.element.value. This is to allow incremental tokenized 51 22 // autocompletion. Specific auto-completion logic (AJAX, etc) … … 58 29 // will incrementally autocomplete with a comma as the token. 59 30 // Additionally, ',' in the above example can be replaced with 60 // a token array, e.g. { tokens: new Array (',', '\n')} which31 // a token array, e.g. { tokens: [',', '\n'] } which 61 32 // enables autocompletion on multiple tokens. This is most 62 33 // useful when one of the tokens is \n (a newline), as it … … 66 37 Autocompleter.Base = function() {}; 67 38 Autocompleter.Base.prototype = { 68 base _initialize: function(element, update, options) {39 baseInitialize: function(element, update, options) { 69 40 this.element = $(element); 70 41 this.update = $(update); 71 this.has _focus= false;42 this.hasFocus = false; 72 43 this.changed = false; 73 44 this.active = false; 74 45 this.index = 0; 75 this.entry _count= 0;46 this.entryCount = 0; 76 47 77 48 if (this.setOptions) 78 49 this.setOptions(options); 79 50 else 80 this.options = {} 81 82 this.options.tokens = this.options.tokens || new Array(); 51 this.options = options || {}; 52 53 this.options.paramName = this.options.paramName || this.element.name; 54 this.options.tokens = this.options.tokens || []; 83 55 this.options.frequency = this.options.frequency || 0.4; 84 this.options.min _chars = this.options.min_chars || 1;56 this.options.minChars = this.options.minChars || 1; 85 57 this.options.onShow = this.options.onShow || 86 58 function(element, update){ 87 59 if(!update.style.position || update.style.position=='absolute') { 88 60 update.style.position = 'absolute'; 89 var offsets = Position.cumulativeOffset(element); 90 update.style.left = offsets[0] + 'px'; 91 update.style.top = (offsets[1] + element.offsetHeight) + 'px'; 92 update.style.width = element.offsetWidth + 'px'; 61 Position.clone(element, update, {setHeight: false, offsetTop: element.offsetHeight}); 93 62 } 94 newEffect.Appear(update,{duration:0.15});63 Effect.Appear(update,{duration:0.15}); 95 64 }; 96 65 this.options.onHide = this.options.onHide || 97 66 function(element, update){ new Effect.Fade(update,{duration:0.15}) }; 98 99 if(this.options.indicator)100 this.indicator = $(this.options.indicator);101 67 102 68 if (typeof(this.options.tokens) == 'string') 103 69 this.options.tokens = new Array(this.options.tokens); 104 70 105 71 this.observer = null; 106 72 73 this.element.setAttribute('autocomplete','off'); 74 107 75 Element.hide(this.update); 108 76 109 77 Event.observe(this.element, "blur", this.onBlur.bindAsEventListener(this)); 110 78 Event.observe(this.element, "keypress", this.onKeyPress.bindAsEventListener(this)); … … 112 80 113 81 show: function() { 114 if(this.update.style.display=='none') this.options.onShow(this.element, this.update); 115 if(!this.iefix && (navigator.appVersion.indexOf('MSIE')>0) && this.update.style.position=='absolute') { 82 if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update); 83 if(!this.iefix && 84 (navigator.appVersion.indexOf('MSIE')>0) && 85 (navigator.userAgent.indexOf('Opera')<0) && 86 (Element.getStyle(this.update, 'position')=='absolute')) { 116 87 new Insertion.After(this.update, 117 88 '<iframe id="' + this.update.id + '_iefix" '+ 118 'style="display:none; filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' +89 'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' + 119 90 'src="javascript:false;" frameborder="0" scrolling="no"></iframe>'); 120 91 this.iefix = $(this.update.id+'_iefix'); 121 92 } 122 if(this.iefix) { 123 Position.clone(this.update, this.iefix); 124 this.iefix.style.zIndex = 1; 125 this.update.style.zIndex = 2; 126 Element.show(this.iefix); 127 } 128 }, 129 93 if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50); 94 }, 95 96 fixIEOverlapping: function() { 97 Position.clone(this.update, this.iefix); 98 this.iefix.style.zIndex = 1; 99 this.update.style.zIndex = 2; 100 Element.show(this.iefix); 101 }, 102 130 103 hide: function() { 131 if(this.update.style.display=='') this.options.onHide(this.element, this.update); 104 this.stopIndicator(); 105 if(Element.getStyle(this.update, 'display')!='none') this.options.onHide(this.element, this.update); 132 106 if(this.iefix) Element.hide(this.iefix); 133 107 }, 134 108 135 109 startIndicator: function() { 136 if(this. indicator) Element.show(this.indicator);137 }, 138 110 if(this.options.indicator) Element.show(this.options.indicator); 111 }, 112 139 113 stopIndicator: function() { 140 if(this. indicator) Element.hide(this.indicator);114 if(this.options.indicator) Element.hide(this.options.indicator); 141 115 }, 142 116 … … 146 120 case Event.KEY_TAB: 147 121 case Event.KEY_RETURN: 148 this.select _entry();122 this.selectEntry(); 149 123 Event.stop(event); 150 124 case Event.KEY_ESC: 151 125 this.hide(); 152 126 this.active = false; 127 Event.stop(event); 153 128 return; 154 129 case Event.KEY_LEFT: … … 156 131 return; 157 132 case Event.KEY_UP: 158 this.mark _previous();133 this.markPrevious(); 159 134 this.render(); 160 135 if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event); 161 136 return; 162 137 case Event.KEY_DOWN: 163 this.mark _next();138 this.markNext(); 164 139 this.render(); 165 140 if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event); … … 169 144 if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN) 170 145 return; 171 146 172 147 this.changed = true; 173 this.has _focus = true;174 148 this.hasFocus = true; 149 175 150 if(this.observer) clearTimeout(this.observer); 176 151 this.observer = 177 152 setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000); 178 153 }, 179 154 180 155 onHover: function(event) { 181 156 var element = Event.findElement(event, 'LI'); … … 191 166 var element = Event.findElement(event, 'LI'); 192 167 this.index = element.autocompleteIndex; 193 this.select _entry();194 Event.stop(event);168 this.selectEntry(); 169 this.hide(); 195 170 }, 196 171 … … 198 173 // needed to make click events working 199 174 setTimeout(this.hide.bind(this), 250); 200 this.has _focus = false;175 this.hasFocus = false; 201 176 this.active = false; 202 177 }, 203 178 204 179 render: function() { 205 if(this.entry _count > 0) {206 for (var i = 0; i < this.entry _count; i++)180 if(this.entryCount > 0) { 181 for (var i = 0; i < this.entryCount; i++) 207 182 this.index==i ? 208 Element.addClassName(this.get _entry(i),"selected") :209 Element.removeClassName(this.get _entry(i),"selected");183 Element.addClassName(this.getEntry(i),"selected") : 184 Element.removeClassName(this.getEntry(i),"selected"); 210 185 211 if(this.has_focus) { 212 if(this.get_current_entry().scrollIntoView) 213 this.get_current_entry().scrollIntoView(false); 214 186 if(this.hasFocus) { 215 187 this.show(); 216 188 this.active = true; 217 189 } 218 } else this.hide(); 219 }, 220 221 mark_previous: function() { 190 } else { 191 this.active = false; 192 this.hide(); 193 } 194 }, 195 196 markPrevious: function() { 222 197 if(this.index > 0) this.index-- 223 else this.index = this.entry _count-1;224 }, 225 226 mark _next: function() {227 if(this.index < this.entry _count-1) this.index++198 else this.index = this.entryCount-1; 199 }, 200 201 markNext: function() { 202 if(this.index < this.entryCount-1) this.index++ 228 203 else this.index = 0; 229 204 }, 230 205 231 get _entry: function(index) {206 getEntry: function(index) { 232 207 return this.update.firstChild.childNodes[index]; 233 208 }, 234 209 235 get _current_entry: function() {236 return this.get _entry(this.index);237 }, 238 239 select _entry: function() {210 getCurrentEntry: function() { 211 return this.getEntry(this.index); 212 }, 213 214 selectEntry: function() { 240 215 this.active = false; 241 value = Element.collectTextNodesIgnoreClass(this.get_current_entry(), 'informal').unescapeHTML(); 242 this.updateElement(value); 243 this.element.focus(); 244 }, 245 246 updateElement: function(value) { 247 var last_token_pos = this.findLastToken(); 248 if (last_token_pos != -1) { 249 var new_value = this.element.value.substr(0, last_token_pos + 1); 250 var whitespace = this.element.value.substr(last_token_pos + 1).match(/^\s+/); 216 this.updateElement(this.getCurrentEntry()); 217 }, 218 219 updateElement: function(selectedElement) { 220 if (this.options.updateElement) { 221 this.options.updateElement(selectedElement); 222 return; 223 } 224 225 var value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal'); 226 var lastTokenPos = this.findLastToken(); 227 if (lastTokenPos != -1) { 228 var newValue = this.element.value.substr(0, lastTokenPos + 1); 229 var whitespace = this.element.value.substr(lastTokenPos + 1).match(/^\s+/); 251 230 if (whitespace) 252 new _value += whitespace[0];253 this.element.value = new _value + value;231 newValue += whitespace[0]; 232 this.element.value = newValue + value; 254 233 } else { 255 234 this.element.value = value; 256 } 257 }, 258 235 } 236 this.element.focus(); 237 238 if (this.options.afterUpdateElement) 239 this.options.afterUpdateElement(this.element, selectedElement); 240 }, 241 259 242 updateChoices: function(choices) { 260 if(!this.changed && this.has _focus) {243 if(!this.changed && this.hasFocus) { 261 244 this.update.innerHTML = choices; 262 245 Element.cleanWhitespace(this.update); … … 264 247 265 248 if(this.update.firstChild && this.update.firstChild.childNodes) { 266 this.entry _count =249 this.entryCount = 267 250 this.update.firstChild.childNodes.length; 268 for (var i = 0; i < this.entry _count; i++) {269 entry = this.get_entry(i);251 for (var i = 0; i < this.entryCount; i++) { 252 var entry = this.getEntry(i); 270 253 entry.autocompleteIndex = i; 271 254 this.addObservers(entry); 272 255 } 273 256 } else { 274 this.entry _count = 0;257 this.entryCount = 0; 275 258 } 276 259 277 260 this.stopIndicator(); 278 261 279 262 this.index = 0; 280 263 this.render(); … … 289 272 onObserverEvent: function() { 290 273 this.changed = false; 291 if(this.get Entry().length>=this.options.min_chars) {274 if(this.getToken().length>=this.options.minChars) { 292 275 this.startIndicator(); 293 276 this.getUpdatedChoices(); … … 298 281 }, 299 282 300 get Entry: function() {301 var token _pos = this.findLastToken();302 if (token _pos != -1)303 var ret = this.element.value.substr(token _pos + 1).replace(/^\s+/,'').replace(/\s+$/,'');283 getToken: function() { 284 var tokenPos = this.findLastToken(); 285 if (tokenPos != -1) 286 var ret = this.element.value.substr(tokenPos + 1).replace(/^\s+/,'').replace(/\s+$/,''); 304 287 else 305 288 var ret = this.element.value; 306 289 307 290 return /\n/.test(ret) ? '' : ret; 308 291 }, 309 292 310 293 findLastToken: function() { 311 var last _token_pos = -1;294 var lastTokenPos = -1; 312 295 313 296 for (var i=0; i<this.options.tokens.length; i++) { 314 var this _token_pos = this.element.value.lastIndexOf(this.options.tokens[i]);315 if (this _token_pos > last_token_pos)316 last _token_pos = this_token_pos;317 } 318 return last _token_pos;297 var thisTokenPos = this.element.value.lastIndexOf(this.options.tokens[i]); 298 if (thisTokenPos > lastTokenPos) 299 lastTokenPos = thisTokenPos; 300 } 301 return lastTokenPos; 319 302 } 320 303 } 321 304 322 305 Ajax.Autocompleter = Class.create(); 323 Ajax.Autocompleter.prototype = Object.extend(new Autocompleter.Base(), 324 Object.extend(new Ajax.Base(), { 306 Object.extend(Object.extend(Ajax.Autocompleter.prototype, Autocompleter.Base.prototype), { 325 307 initialize: function(element, update, url, options) { 326 this.base _initialize(element, update, options);308 this.baseInitialize(element, update, options); 327 309 this.options.asynchronous = true; 328 this.options.onComplete = this.onComplete.bind(this) 329 this.options.method = 'post'; 310 this.options.onComplete = this.onComplete.bind(this); 330 311 this.options.defaultParams = this.options.parameters || null; 331 312 this.url = url; 332 313 }, 333 314 334 315 getUpdatedChoices: function() { 335 entry = encodeURIComponent(this. element.name) + '=' +336 encodeURIComponent(this.get Entry());337 316 entry = encodeURIComponent(this.options.paramName) + '=' + 317 encodeURIComponent(this.getToken()); 318 338 319 this.options.parameters = this.options.callback ? 339 320 this.options.callback(this.element, entry) : entry; 340 321 341 322 if(this.options.defaultParams) 342 323 this.options.parameters += '&' + this.options.defaultParams; 343 324 344 325 new Ajax.Request(this.url, this.options); 345 326 }, 346 327 347 328 onComplete: function(request) { 348 329 this.updateChoices(request.responseText); 349 330 } 350 331 351 }) );332 }); 352 333 353 334 // The local array autocompleter. Used when you'd prefer to … … 363 344 // - choices - How many autocompletion choices to offer 364 345 // 365 // - partial _search - If false, the autocompleter will match entered346 // - partialSearch - If false, the autocompleter will match entered 366 347 // text only at the beginning of strings in the 367 348 // autocomplete array. Defaults to true, which will … … 369 350 // strings in the autocomplete array. If you want to 370 351 // search anywhere in the string, additionally set 371 // the option full _search to true (default: off).372 // 373 // - full _search - Search anywhere in autocomplete array strings.374 // 375 // - partial _chars - How many characters to enter before triggering376 // a partial match (unlike min _chars, which defines352 // the option fullSearch to true (default: off). 353 // 354 // - fullSsearch - Search anywhere in autocomplete array strings. 355 // 356 // - partialChars - How many characters to enter before triggering 357 // a partial match (unlike minChars, which defines 377 358 // how many characters are required to do any match 378 359 // at all). Defaults to 2. 379 360 // 380 // - ignore _case - Whether to ignore case when autocompleting.361 // - ignoreCase - Whether to ignore case when autocompleting. 381 362 // Defaults to true. 382 363 // … … 389 370 Autocompleter.Local.prototype = Object.extend(new Autocompleter.Base(), { 390 371 initialize: function(element, update, array, options) { 391 this.base _initialize(element, update, options);372 this.baseInitialize(element, update, options); 392 373 this.options.array = array; 393 374 }, … … 400 381 this.options = Object.extend({ 401 382 choices: 10, 402 partial _search: true,403 partial _chars: 2,404 ignore _case: true,405 full _search: false,383 partialSearch: true, 384 partialChars: 2, 385 ignoreCase: true, 386 fullSearch: false, 406 387 selector: function(instance) { 407 var ret = new Array(); // Beginning matches408 var partial = new Array(); // Inside matches409 var entry = instance.get Entry();388 var ret = []; // Beginning matches 389 var partial = []; // Inside matches 390 var entry = instance.getToken(); 410 391 var count = 0; 411 392 412 393 for (var i = 0; i < instance.options.array.length && 413 ret.length < instance.options.choices ; i++) { 394 ret.length < instance.options.choices ; i++) { 395 414 396 var elem = instance.options.array[i]; 415 var found _pos = instance.options.ignore_case ?397 var foundPos = instance.options.ignoreCase ? 416 398 elem.toLowerCase().indexOf(entry.toLowerCase()) : 417 399 elem.indexOf(entry); 418 400 419 while (found _pos != -1) {420 if (found _pos == 0 && elem.length != entry.length) {401 while (foundPos != -1) { 402 if (foundPos == 0 && elem.length != entry.length) { 421 403 ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" + 422 404 elem.substr(entry.length) + "</li>"); 423 405 break; 424 } else if (entry.length >= instance.options.partial _chars &&425 instance.options.partial _search && found_pos != -1) {426 if (instance.options.full _search || /\s/.test(elem.substr(found_pos-1,1))) {427 partial.push("<li>" + elem.substr(0, found _pos) + "<strong>" +428 elem.substr(found _pos, entry.length) + "</strong>" + elem.substr(429 found _pos + entry.length) + "</li>");406 } else if (entry.length >= instance.options.partialChars && 407 instance.options.partialSearch && foundPos != -1) { 408 if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) { 409 partial.push("<li>" + elem.substr(0, foundPos) + "<strong>" + 410 elem.substr(foundPos, entry.length) + "</strong>" + elem.substr( 411 foundPos + entry.length) + "</li>"); 430 412 break; 431 413 } 432 414 } 433 415 434 found _pos = instance.options.ignore_case ?435 elem.toLowerCase().indexOf(entry.toLowerCase(), found _pos + 1) :436 elem.indexOf(entry, found _pos + 1);416 foundPos = instance.options.ignoreCase ? 417 elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) : 418 elem.indexOf(entry, foundPos + 1); 437 419 438 420 } … … 445 427 } 446 428 }); 429 430 // AJAX in-place editor 431 // 432 // see documentation on http://wiki.script.aculo.us/scriptaculous/show/Ajax.InPlaceEditor 433 434 // Use this if you notice weird scrolling problems on some browsers, 435 // the DOM might be a bit confused when this gets called so do this 436 // waits 1 ms (with setTimeout) until it does the activation 437 Field.scrollFreeActivate = function(field) { 438 setTimeout(function() { 439 Field.activate(field); 440 }, 1); 441 } 442 443 Ajax.InPlaceEditor = Class.create(); 444 Ajax.InPlaceEditor.defaultHighlightColor = "#FFFF99"; 445 Ajax.InPlaceEditor.prototype = { 446 initialize: function(element, url, options) { 447 this.url = url; 448 this.element = $(element); 449 450 this.options = Object.extend({ 451 okText: "ok", 452 cancelText: "cancel", 453 savingText: "Saving...", 454 clickToEditText: "Click to edit", 455 okText: "ok", 456 rows: 1, 457 onComplete: function(transport, element) { 458 new Effect.Highlight(element, {startcolor: this.options.highlightcolor}); 459 }, 460 onFailure: function(transport) { 461 alert("Error communicating with the server: " + transport.responseText.stripTags()); 462 }, 463 callback: function(form) { 464 return Form.serialize(form); 465 }, 466 handleLineBreaks: true, 467 loadingText: 'Loading...', 468 savingClassName: 'inplaceeditor-saving', 469 loadingClassName: 'inplaceeditor-loading', 470 formClassName: 'inplaceeditor-form', 471 highlightcolor: Ajax.InPlaceEditor.defaultHighlightColor, 472 highlightendcolor: "#FFFFFF", 473 externalControl: null, 474 ajaxOptions: {} 475 }, options || {}); 476 477 if(!this.options.formId && this.element.id) { 478 this.options.formId = this.element.id + "-inplaceeditor"; 479 if ($(this.options.formId)) { 480 // there's already a form with that name, don't specify an id 481 this.options.formId = null; 482 } 483 } 484 485 if (this.options.externalControl) { 486 this.options.externalControl = $(this.options.externalControl); 487 } 488 489 this.originalBackground = Element.getStyle(this.element, 'background-color'); 490 if (!this.originalBackground) { 491 this.originalBackground = "transparent"; 492 } 493 494 this.element.title = this.options.clickToEditText; 495 496 this.onclickListener = this.enterEditMode.bindAsEventListener(this); 497 this.mouseoverListener = this.enterHover.bindAsEventListener(this); 498 this.mouseoutListener = this.leaveHover.bindAsEventListener(this); 499 Event.observe(this.element, 'click', this.onclickListener); 500 Event.observe(this.element, 'mouseover', this.mouseoverListener); 501 Event.observe(this.element, 'mouseout', this.mouseoutListener); 502 if (this.options.externalControl) { 503 Event.observe(this.options.externalControl, 'click', this.onclickListener); 504 Event.observe(this.options.externalControl, 'mouseover', this.mouseoverListener); 505 Event.observe(this.options.externalControl, 'mouseout', this.mouseoutListener); 506 } 507 }, 508 enterEditMode: function(evt) { 509 if (this.saving) return; 510 if (this.editing) return; 511 this.editing = true; 512 this.onEnterEditMode(); 513 if (this.options.externalControl) { 514 Element.hide(this.options.externalControl); 515 } 516 Element.hide(this.element); 517 this.createForm(); 518 this.element.parentNode.insertBefore(this.form, this.element); 519 Field.scrollFreeActivate(this.editField); 520 // stop the event to avoid a page refresh in Safari 521 if (evt) { 522 Event.stop(evt); 523 } 524 return false; 525 }, 526 createForm: function() { 527 this.form = document.createElement("form"); 528 this.form.id = this.options.formId; 529 Element.addClassName(this.form, this.options.formClassName) 530 this.form.onsubmit = this.onSubmit.bind(this); 531 532 this.createEditField(); 533 534 if (this.options.textarea) { 535 var br = document.createElement("br"); 536 this.form.appendChild(br); 537 } 538 539 okButton = document.createElement("input"); 540 okButton.type = "submit"; 541 okButton.value = this.options.okText; 542 this.form.appendChild(okButton); 543 544 cancelLink = document.createElement("a"); 545 cancelLink.href = "#"; 546 cancelLink.appendChild(document.createTextNode(this.options.cancelText)); 547 cancelLink.onclick = this.onclickCancel.bind(this); 548 this.form.appendChild(cancelLink); 549 }, 550 hasHTMLLineBreaks: function(string) { 551 if (!this.options.handleLineBreaks) return false; 552 return string.match(/<br/i) || string.match(/<p>/i); 553 }, 554 convertHTMLLineBreaks: function(string) { 555 return string.replace(/<br>/gi, "\n").replace(/<br\/>/gi, "\n").replace(/<\/p>/gi, "\n").replace(/<p>/gi, ""); 556 }, 557 createEditField: function() { 558 var text; 559 if(this.options.loadTextURL) { 560 text = this.options.loadingText; 561 } else { 562 text = this.getText(); 563 } 564 565 if (this.options.rows == 1 && !this.hasHTMLLineBreaks(text)) { 566 this.options.textarea = false; 567 var textField = document.createElement("input"); 568 textField.type = "text"; 569 textField.name = "value"; 570 textField.value = text; 571 textField.style.backgroundColor = this.options.highlightcolor; 572 var size = this.options.size || this.options.cols || 0; 573 if (size != 0) textField.size = size; 574 this.editField = textField; 575 } else { 576 this.options.textarea = true; 577 var textArea = document.createElement("textarea"); 578 textArea.name = "value"; 579 textArea.value = this.convertHTMLLineBreaks(text); 580 textArea.rows = this.options.rows; 581 textArea.cols = this.options.cols || 40; 582 this.editField = textArea; 583 } 584 585 if(this.options.loadTextURL) { 586 this.loadExternalText(); 587 } 588 this.form.appendChild(this.editField); 589 }, 590 getText: function() { 591 return this.element.innerHTML; 592 }, 593 loadExternalText: function() { 594 Element.addClassName(this.form, this.options.loadingClassName); 595 this.editField.disabled = true; 596 new Ajax.Request( 597 this.options.loadTextURL, 598 Object.extend({ 599 asynchronous: true, 600 onComplete: this.onLoadedExternalText.bind(this) 601 }, this.options.ajaxOptions) 602 ); 603 }, 604 onLoadedExternalText: function(transport) { 605 Element.removeClassName(this.form, this.options.loadingClassName); 606 this.editField.disabled = false; 607 this.editField.value = transport.responseText.stripTags(); 608 }, 609 onclickCancel: function() { 610 this.onComplete(); 611 this.leaveEditMode(); 612 return false; 613 }, 614 onFailure: function(transport) { 615 this.options.onFailure(transport); 616 if (this.oldInnerHTML) { 617 this.element.innerHTML = this.oldInnerHTML; 618 this.oldInnerHTML = null; 619 } 620 return false; 621 }, 622 onSubmit: function() { 623 // onLoading resets these so we need to save them away for the Ajax call 624 var form = this.form; 625 var value = this.editField.value; 626 627 // do this first, sometimes the ajax call returns before we get a chance to switch on Saving... 628 // which means this will actually switch on Saving... *after* we've left edit mode causing Saving... 629 // to be displayed indefinitely 630 this.onLoading(); 631 632 new Ajax.Updater( 633 { 634 success: this.element, 635 // don't update on failure (this could be an option) 636 failure: null 637 }, 638 this.url, 639 Object.extend({ 640 parameters: this.options.callback(form, value), 641 onComplete: this.onComplete.bind(this), 642 onFailure: this.onFailure.bind(this) 643 }, this.options.ajaxOptions) 644 ); 645 // stop the event to avoid a page refresh in Safari 646 if (arguments.length > 1) { 647 Event.stop(arguments[0]); 648 } 649 return false; 650 }, 651 onLoading: function() { 652 this.saving = true; 653 this.removeForm(); 654 this.leaveHover(); 655 this.showSaving(); 656 }, 657 showSaving: function() { 658 this.oldInnerHTML = this.element.innerHTML; 659 this.element.innerHTML = this.options.savingText; 660 Element.addClassName(this.element, this.options.savingClassName); 661 this.element.style.backgroundColor = this.originalBackground; 662 Element.show(this.element); 663 }, 664 removeForm: function() { 665 if(this.form) { 666 if (this.form.parentNode) Element.remove(this.form); 667 this.form = null; 668 } 669 }, 670 enterHover: function() { 671 if (this.saving) return; 672 this.element.style.backgroundColor = this.options.highlightcolor; 673 if (this.effect) { 674 this.effect.cancel(); 675 } 676 Element.addClassName(this.element, this.options.hoverClassName) 677 }, 678 leaveHover: function() { 679 if (this.options.backgroundColor) { 680 this.element.style.backgroundColor = this.oldBackground; 681 } 682 Element.removeClassName(this.element, this.options.hoverClassName) 683 if (this.saving) return; 684 this.effect = new Effect.Highlight(this.element, { 685 startcolor: this.options.highlightcolor, 686 endcolor: this.options.highlightendcolor, 687 restorecolor: this.originalBackground 688 }); 689 }, 690 leaveEditMode: function() { 691 Element.removeClassName(this.element, this.options.savingClassName); 692 this.removeForm(); 693 this.leaveHover(); 694 this.element.style.backgroundColor = this.originalBackground; 695 Element.show(this.element); 696 if (this.options.externalControl) { 697 Element.show(this.options.externalControl); 698 } 699 this.editing = false; 700 this.saving = false; 701 this.oldInnerHTML = null; 702 this.onLeaveEditMode(); 703 }, 704 onComplete: function(transport) { 705 this.leaveEditMode(); 706 this.options.onComplete.bind(this)(transport, this.element); 707 }, 708 onEnterEditMode: function() {}, 709 onLeaveEditMode: function() {}, 710 dispose: function() { 711 if (this.oldInnerHTML) { 712 this.element.innerHTML = this.oldInnerHTML; 713 } 714 this.leaveEditMode(); 715 Event.stopObserving(this.element, 'click', this.onclickListener); 716 Event.stopObserving(this.element, 'mouseover', this.mouseoverListener); 717 Event.stopObserving(this.element, 'mouseout', this.mouseoutListener); 718 if (this.options.externalControl) { 719 Event.stopObserving(this.options.externalControl, 'click', this.onclickListener); 720 Event.stopObserving(this.options.externalControl, 'mouseover', this.mouseoverListener); 721 Event.stopObserving(this.options.externalControl, 'mouseout', this.mouseoutListener); 722 } 723 } 724 }; 725 726 // Delayed observer, like Form.Element.Observer, 727 // but waits for delay after last key input 728 // Ideal for live-search fields 729 730 Form.Element.DelayedObserver = Class.create(); 731 Form.Element.DelayedObserver.prototype = { 732 initialize: function(element, delay, callback) { 733 this.delay = delay || 0.5; 734 this.element = $(element); 735 this.callback = callback; 736 this.timer = null; 737 this.lastValue = $F(this.element); 738 Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this)); 739 }, 740 delayedListener: function(event) { 741 if(this.lastValue == $F(this.element)) return; 742 if(this.timer) clearTimeout(this.timer); 743 this.timer = setTimeout(this.onTimerEvent.bind(this), this.delay * 1000); 744 this.lastValue = $F(this.element); 745 }, 746 onTimerEvent: function() { 747 this.timer = null; 748 this.callback(this.element, $F(this.element)); 749 } 750 }; -
trunk/public/javascripts/dragdrop.js
r5 r39 1 1 // Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) 2 2 // 3 // Element.Class part Copyright (c) 2005 by Rick Olson 4 // 5 // Permission is hereby granted, free of charge, to any person obtaining 6 // a copy of this software and associated documentation files (the 7 // "Software"), to deal in the Software without restriction, including 8 // without limitation the rights to use, copy, modify, merge, publish, 9 // distribute, sublicense, and/or sell copies of the Software, and to 10 // permit persons to whom the Software is furnished to do so, subject to 11 // the following conditions: 12 // 13 // The above copyright notice and this permission notice shall be 14 // included in all copies or substantial portions of the Software. 15 // 16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 24 Element.Class = { 25 // Element.toggleClass(element, className) toggles the class being on/off 26 // Element.toggleClass(element, className1, className2) toggles between both classes, 27 // defaulting to className1 if neither exist 28 toggle: function(element, className) { 29 if(Element.Class.has(element, className)) { 30 Element.Class.remove(element, className); 31 if(arguments.length == 3) Element.Class.add(element, arguments[2]); 32 } else { 33 Element.Class.add(element, className); 34 if(arguments.length == 3) Element.Class.remove(element, arguments[2]); 35 } 36 }, 37 38 // gets space-delimited classnames of an element as an array 39 get: function(element) { 40 element = $(element); 41 return element.className.split(' '); 42 }, 43 44 // functions adapted from original functions by Gavin Kistner 45 remove: function(element) { 46 element = $(element); 47 var regEx; 48 for(var i = 1; i < arguments.length; i++) { 49 regEx = new RegExp("^" + arguments[i] + "\\b\\s*|\\s*\\b" + arguments[i] + "\\b", 'g'); 50 element.className = element.className.replace(regEx, '') 51 } 52 }, 53 54 add: function(element) { 55 element = $(element); 56 for(var i = 1; i < arguments.length; i++) { 57 Element.Class.remove(element, arguments[i]); 58 element.className += (element.className.length > 0 ? ' ' : '') + arguments[i]; 59 } 60 }, 61 62 // returns true if all given classes exist in said element 63 has: function(element) { 64 element = $(element); 65 if(!element || !element.className) return false; 66 var regEx; 67 for(var i = 1; i < arguments.length; i++) { 68 regEx = new RegExp("\\b" + arguments[i] + "\\b"); 69 if(!regEx.test(element.className)) return false; 70 } 71 return true; 72 }, 73 74 // expects arrays of strings and/or strings as optional paramters 75 // Element.Class.has_any(element, ['classA','classB','classC'], 'classD') 76 has_any: function(element) { 77 element = $(element); 78 if(!element || !element.className) return false; 79 var regEx; 80 for(var i = 1; i < arguments.length; i++) { 81 if((typeof arguments[i] == 'object') && 82 (arguments[i].constructor == Array)) { 83 for(var j = 0; j < arguments[i].length; j++) { 84 regEx = new RegExp("\\b" + arguments[i][j] + "\\b"); 85 if(regEx.test(element.className)) return true; 86 } 87 } else { 88 regEx = new RegExp("\\b" + arguments[i] + "\\b"); 89 if(regEx.test(element.className)) return true; 90 } 91 } 92 return false; 93 }, 94 95 childrenWith: function(element, className) { 96 var children = $(element).getElementsByTagName('*'); 97 var elements = new Array(); 98 99 for (var i = 0; i < children.length; i++) { 100 if (Element.Class.has(children[i], className)) { 101 elements.push(children[i]); 102 break; 103 } 104 } 105 106 return elements; 107 } 108 } 3 // See scriptaculous.js for full license. 109 4 110 5 /*--------------------------------------------------------------------------*/ 111 6 112 7 var Droppables = { 113 drops: false,114 8 drops: [], 9 115 10 remove: function(element) { 116 for(var i = 0; i < this.drops.length; i++) 117 if(this.drops[i].element == element) 118 this.drops.splice(i,1); 119 }, 120 11 this.drops = this.drops.reject(function(d) { return d.element==$(element) }); 12 }, 13 121 14 add: function(element) { 122 varelement = $(element);15 element = $(element); 123 16 var options = Object.extend({ 124 17 greedy: true, 125 18 hoverclass: null 126 19 }, arguments[1] || {}); 127 20 128 21 // cache containers 129 22 if(options.containment) { 130 options._containers = new Array();23 options._containers = []; 131 24 var containment = options.containment; 132 25 if((typeof containment == 'object') && 133 26 (containment.constructor == Array)) { 134 for(var i=0; i<containment.length; i++) 135 options._containers.push($(containment[i])); 27 containment.each( function(c) { options._containers.push($(c)) }); 136 28 } else { 137 29 options._containers.push($(containment)); 138 30 } 139 options._containers_length =140 options._containers.length-1;141 }142 31 } 32 33 if(options.accept) options.accept = [options.accept].flatten(); 34 143 35 Element.makePositioned(element); // fix IE 144 145 36 options.element = element; 146 147 // activate the droppable 148 if(!this.drops) this.drops = []; 37 149 38 this.drops.push(options); 150 39 }, 151 152 is_contained: function(element, drop) { 153 var containers = drop._containers; 40 41 isContained: function(element, drop) { 154 42 var parentNode = element.parentNode; 155 var i = drop._containers_length; 156 do { if(parentNode==containers[i]) return true; } while (i--); 157 return false; 158 }, 159 160 is_affected: function(pX, pY, element, drop) { 43 return drop._containers.detect(function(c) { return parentNode == c }); 44 }, 45 46 isAffected: function(point, element, drop) { 161 47 return ( 162 48 (drop.element!=element) && 163 49 ((!drop._containers) || 164 this.is _contained(element, drop)) &&50 this.isContained(element, drop)) && 165 51 ((!drop.accept) || 166 (Element.Class.has_any(element, drop.accept))) && 167 Position.within(drop.element, pX, pY) ); 168 }, 169 52 (Element.classNames(element).detect( 53 function(v) { return drop.accept.include(v) } ) )) && 54 Position.within(drop.element, point[0], point[1]) ); 55 }, 56 170 57 deactivate: function(drop) { 171 Element.Class.remove(drop.element, drop.hoverclass); 58 if(drop.hoverclass) 59 Element.removeClassName(drop.element, drop.hoverclass); 172 60 this.last_active = null; 173 61 }, 174 62 175 63 activate: function(drop) { 64 if(drop.hoverclass) 65 Element.addClassName(drop.element, drop.hoverclass); 66 this.last_active = drop; 67 }, 68 69 show: function(point, element) { 70 if(!this.drops.length) return; 71 176 72 if(this.last_active) this.deactivate(this.last_active); 177 if(drop.hoverclass) { 178 Element.Class.add(drop.element, drop.hoverclass); 179 this.last_active = drop; 180 } 181 }, 182 183 show: function(event, element) { 184 if(!this.drops) return; 185 var pX = Event.pointerX(event); 186 var pY = Event.pointerY(event); 187 Position.prepare(); 188 189 var i = this.drops.length-1; do { 190 var drop = this.drops[i]; 191 if(this.is_affected(pX, pY, element, drop)) { 73 this.drops.each( function(drop) { 74 if(Droppables.isAffected(point, element, drop)) { 192 75 if(drop.onHover) 193 76 drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element)); 194 77 if(drop.greedy) { 195 this.activate(drop);196 return;78 Droppables.activate(drop); 79 throw $break; 197 80 } 198 81 } 199 } while (i--);200 }, 201 82 }); 83 }, 84 202 85 fire: function(event, element) { 203 86 if(!this.last_active) return; 204 87 Position.prepare(); 205 206 if (this.is _affected(Event.pointerX(event), Event.pointerY(event), element, this.last_active))88 89 if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active)) 207 90 if (this.last_active.onDrop) 208 this.last_active.onDrop(element, this.last_active); 209 210 }, 211 91 this.last_active.onDrop(element, this.last_active.element, event); 92 }, 93 212 94 reset: function() { 213 95 if(this.last_active) … … 216 98 } 217 99 218 Draggables = { 219 observers: new Array(), 100 var Draggables = { 101 drags: [], 102 observers: [], 103 104 register: function(draggable) { 105 if(this.drags.length == 0) { 106 this.eventMouseUp = this.endDrag.bindAsEventListener(this); 107 this.eventMouseMove = this.updateDrag.bindAsEventListener(this); 108 this.eventKeypress = this.keyPress.bindAsEventListener(this); 109 110 Event.observe(document, "mouseup", this.eventMouseUp); 111 Event.observe(document, "mousemove", this.eventMouseMove); 112 Event.observe(document, "keypress", this.eventKeypress); 113 } 114 this.drags.push(draggable); 115 }, 116 117 unregister: function(draggable) { 118 this.drags = this.drags.reject(function(d) { return d==draggable }); 119 if(this.drags.length == 0) { 120 Event.stopObserving(document, "mouseup", this.eventMouseUp); 121 Event.stopObserving(document, "mousemove", this.eventMouseMove); 122 Event.stopObserving(document, "keypress", this.eventKeypress); 123 } 124 }, 125 126 activate: function(draggable) { 127 window.focus(); // allows keypress events if window isn't currently focused, fails for Safari 128 this.activeDraggable = draggable; 129 }, 130 131 deactivate: function(draggbale) { 132 this.activeDraggable = null; 133 }, 134 135 updateDrag: function(event) { 136 if(!this.activeDraggable) return; 137 var pointer = [Event.pointerX(event), Event.pointerY(event)]; 138 // Mozilla-based browsers fire successive mousemove events with 139 // the same coordinates, prevent needless redrawing (moz bug?) 140 if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return; 141 this._lastPointer = pointer; 142 this.activeDraggable.updateDrag(event, pointer); 143 }, 144 145 endDrag: function(event) { 146 if(!this.activeDraggable) return; 147 this._lastPointer = null; 148 this.activeDraggable.endDrag(event); 149 }, 150 151 keyPress: function(event) { 152 if(this.activeDraggable) 153 this.activeDraggable.keyPress(event); 154 }, 155 220 156 addObserver: function(observer) { 221 this.observers.push(observer); 222 }, 223 removeObserver: function(element) { // element instead of obsever fixes mem leaks 224 for(var i = 0; i < this.observers.length; i++) 225 if(this.observers[i].element && (this.observers[i].element == element)) 226 this.observers.splice(i,1); 227 }, 228 notify: function(eventName, draggable) { // 'onStart', 'onEnd' 229 for(var i = 0; i < this.observers.length; i++) 230 this.observers[i][eventName](draggable); 157 this.observers.push(observer); 158 this._cacheObserverCallbacks(); 159 }, 160 161 removeObserver: function(element) { // element instead of observer fixes mem leaks 162 this.observers = this.observers.reject( function(o) { return o.element==element }); 163 this._cacheObserverCallbacks(); 164 }, 165 166 notify: function(eventName, draggable, event) { // 'onStart', 'onEnd', 'onDrag' 167 if(this[eventName+'Count'] > 0) 168 this.observers.each( function(o) { 169 if(o[eventName]) o[eventName](eventName, draggable, event); 170 }); 171 }, 172 173 _cacheObserverCallbacks: function() { 174 ['onStart','onEnd','onDrag'].each( function(eventName) { 175 Draggables[eventName+'Count'] = Draggables.observers.select( 176 function(o) { return o[eventName]; } 177 ).length; 178 }); 231 179 } 232 180 } … … 234 182 /*--------------------------------------------------------------------------*/ 235 183 236 Draggable = Class.create();184 var Draggable = Class.create(); 237 185 Draggable.prototype = { 238 186 initialize: function(element) { … … 243 191 }, 244 192 reverteffect: function(element, top_offset, left_offset) { 245 new Effect.MoveBy(element, -top_offset, -left_offset, {duration:0.4}); 193 var dur = Math.sqrt(Math.abs(top_offset^2)+Math.abs(left_offset^2))*0.02; 194 element._revert = new Effect.MoveBy(element, -top_offset, -left_offset, {duration:dur}); 246 195 }, 247 196 endeffect: function(element) { 248 new Effect.Opacity(element, {duration:0.2, from:0.7, to:1.0});197 new Effect.Opacity(element, {duration:0.2, from:0.7, to:1.0}); 249 198 }, 250 199 zindex: 1000, 251 revert: false 200 revert: false, 201 snap: false // false, or xy or [x,y] or function(x,y){ return [x,y] } 252 202 }, arguments[1] || {}); 253 254 this.element = $(element); 255 this.handle = options.handle ? $(options.handle) : this.element; 256 257 Element.makePositioned(this.element); // fix IE 258 259 this.offsetX = 0; 260 this.offsetY = 0; 261 this.originalLeft = this.currentLeft(); 262 this.originalTop = this.currentTop(); 263 this.originalX = this.element.offsetLeft; 264 this.originalY = this.element.offsetTop; 265 this.originalZ = parseInt(this.element.style.zIndex || "0"); 266 267 this.options = options; 268 269 this.active = false; 270 this.dragging = false; 271 272 this.eventMouseDown = this.startDrag.bindAsEventListener(this); 273 this.eventMouseUp = this.endDrag.bindAsEventListener(this); 274 this.eventMouseMove = this.update.bindAsEventListener(this); 275 this.eventKeypress = this.keyPress.bindAsEventListener(this); 276 203 204 this.element = $(element); 205 206 if(options.handle && (typeof options.handle == 'string')) 207 this.handle = Element.childrenWithClassName(this.element, options.handle)[0]; 208 if(!this.handle) this.handle = $(options.handle); 209 if(!this.handle) this.handle = this.element; 210 211 Element.makePositioned(this.element); // fix IE 212 213 this.delta = this.currentDelta(); 214 this.options = options; 215 this.dragging = false; 216 217 this.eventMouseDown = this.initDrag.bindAsEventListener(this); 277 218 Event.observe(this.handle, "mousedown", this.eventMouseDown); 278 Event.observe(document, "mouseup", this.eventMouseUp);279 Event.observe(document, "mousemove", this.eventMouseMove);280 Event.observe(document, "keypress", this.eventKeypress);281 },219 220 Draggables.register(this); 221 }, 222 282 223 destroy: function() { 283 224 Event.stopObserving(this.handle, "mousedown", this.eventMouseDown); 284 Event.stopObserving(document, "mouseup", this.eventMouseUp); 285 Event.stopObserving(document, "mousemove", this.eventMouseMove); 286 Event.stopObserving(document, "keypress", this.eventKeypress); 287 }, 288 currentLeft: function() { 289 return parseInt(this.element.style.left || '0'); 290 }, 291 currentTop: function() { 292 return parseInt(this.element.style.top || '0') 293 }, 225 Draggables.unregister(this); 226 }, 227 228 currentDelta: function() { 229 return([ 230 parseInt(this.element.style.left || '0'), 231 parseInt(this.element.style.top || '0')]); 232 }, 233 234 initDrag: function(event) { 235 if(Event.isLeftClick(event)) { 236 // abort on form elements, fixes a Firefox issue 237 var src = Event.element(event); 238 if(src.tagName && ( 239 src.tagName=='INPUT' || 240 src.tagName=='SELECT' || 241 src.tagName=='BUTTON' || 242 src.tagName=='TEXTAREA')) return; 243 244 if(this.element._revert) { 245 this.element._revert.cancel(); 246 this.element._revert = null; 247 } 248 249 var pointer = [Event.pointerX(event), Event.pointerY(event)]; 250 var pos = Position.cumulativeOffset(this.element); 251 this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) }); 252 253 Draggables.activate(this); 254 Event.stop(event); 255 } 256 }, 257 294 258 startDrag: function(event) { 295 if(Event.isLeftClick(event)) { 296 this.active = true; 297 298 var style = this.element.style; 299 this.originalY = this.element.offsetTop - this.currentTop() - this.originalTop; 300 this.originalX = this.element.offsetLeft - this.currentLeft() - this.originalLeft; 301 this.offsetY = event.clientY - this.originalY - this.originalTop; 302 this.offsetX = event.clientX - this.originalX - this.originalLeft; 303 304 Event.stop(event); 305 } 306 }, 259 this.dragging = true; 260 261 if(this.options.zindex) { 262 this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0); 263 this.element.style.zIndex = this.options.zindex; 264 } 265 266 if(this.options.ghosting) { 267 this._clone = this.element.cloneNode(true); 268 Position.absolutize(this.element); 269 this.element.parentNode.insertBefore(this._clone, this.element); 270 } 271 272 Draggables.notify('onStart', this, event); 273 if(this.options.starteffect) this.options.starteffect(this.element); 274 }, 275 276 updateDrag: function(event, pointer) { 277 if(!this.dragging) this.startDrag(event); 278 Position.prepare(); 279 Droppables.show(pointer, this.element); 280 Draggables.notify('onDrag', this, event); 281 this.draw(pointer); 282 if(this.options.change) this.options.change(this); 283 284 // fix AppleWebKit rendering 285 if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0); 286 Event.stop(event); 287 }, 288 307 289 finishDrag: function(event, success) { 308 this.active = false;309 290 this.dragging = false; 310 291 292 if(this.options.ghosting) { 293 Position.relativize(this.element); 294 Element.remove(this._clone); 295 this._clone = null; 296 } 297 311 298 if(success) Droppables.fire(event, this.element); 312 Draggables.notify('onEnd', this );313 299 Draggables.notify('onEnd', this, event); 300 314 301 var revert = this.options.revert; 315 302 if(revert && typeof revert == 'function') revert = revert(this.element); 316 303 304 var d = this.currentDelta(); 317 305 if(revert && this.options.reverteffect) { 318 306 this.options.reverteffect(this.element, 319 this.currentTop()-this.originalTop, 320 this.currentLeft()-this.originalLeft); 307 d[1]-this.delta[1], d[0]-this.delta[0]); 321 308 } else { 322 this. originalLeft = this.currentLeft();323 this.originalTop = this.currentTop();324 } 325 326 this.element.style.zIndex = this.originalZ;327 309 this.delta = d; 310 } 311 312 if(this.options.zindex) 313 this.element.style.zIndex = this.originalZ; 314 328 315 if(this.options.endeffect) 329 316 this.options.endeffect(this.element); 330 317 318 Draggables.deactivate(this); 331 319 Droppables.reset(); 332 320 }, 321 333 322 keyPress: function(event) { 334 if(this.active) { 335 if(event.keyCode==Event.KEY_ESC) { 336 this.finishDrag(event, false); 337 Event.stop(event); 338 } 339 } 340 }, 323 if(!event.keyCode==Event.KEY_ESC) return; 324 this.finishDrag(event, false); 325 Event.stop(event); 326 }, 327 341 328 endDrag: function(event) { 342 if(this.active && this.dragging) { 343 this.finishDrag(event, true); 344 Event.stop(event); 345 } 346 this.active = false; 347 this.dragging = false; 348 }, 349 draw: function(event) { 329 if(!this.dragging) return; 330 this.finishDrag(event, true); 331 Event.stop(event); 332 }, 333 334 draw: function(point) { 335 var pos = Position.cumulativeOffset(this.element); 336 var d = this.currentDelta(); 337 pos[0] -= d[0]; pos[1] -= d[1]; 338 339 var p = [0,1].map(function(i){ return (point[i]-pos[i]-this.offset[i]) }.bind(this)); 340 341 if(this.options.snap) { 342 if(typeof this.options.snap == 'function') { 343 p = this.options.snap(p[0],p[1]); 344 } else { 345 if(this.options.snap instanceof Array) { 346 p = p.map( function(v, i) { 347 return Math.round(v/this.options.snap[i])*this.options.snap[i] }.bind(this)) 348 } else { 349 p = p.map( function(v) { 350 return Math.round(v/this.options.snap)*this.options.snap }.bind(this)) 351 } 352 }} 353 350 354 var style = this.element.style; 351 this.originalX = this.element.offsetLeft - this.currentLeft() - this.originalLeft;352 this.originalY = this.element.offsetTop - this.currentTop() - this.originalTop;353 355 if((!this.options.constraint) || (this.options.constraint=='horizontal')) 354 style.left = ((event.clientX - this.originalX) - this.offsetX)+ "px";356 style.left = p[0] + "px"; 355 357 if((!this.options.constraint) || (this.options.constraint=='vertical')) 356 style.top = ((event.clientY - this.originalY) - this.offsetY)+ "px";358 style.top = p[1] + "px"; 357 359 if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering 358 },359 update: function(event) {360 if(this.active) {361 if(!this.dragging) {362 var style = this.element.style;363 this.dragging = true;364 if(style.position=="") style.position = "relative";365 style.zIndex = this.options.zindex;366 Draggables.notify('onStart', this);367 if(this.options.starteffect) this.options.starteffect(this.element);368 }369 370 Droppables.show(event, this.element);371 this.draw(event);372 if(this.options.change) this.options.change(this);373 374 // fix AppleWebKit rendering375 if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);376 377 Event.stop(event);378 }379 360 } 380 361 } … … 382 363 /*--------------------------------------------------------------------------*/ 383 364 384 SortableObserver = Class.create();365 var SortableObserver = Class.create(); 385 366 SortableObserver.prototype = { 386 367 initialize: function(element, observer) { … … 389 370 this.lastValue = Sortable.serialize(this.element); 390 371 }, 372 391 373 onStart: function() { 392 374 this.lastValue = Sortable.serialize(this.element); 393 375 }, 394 onEnd: function() { 376 377 onEnd: function() { 378 Sortable.unmark(); 395 379 if(this.lastValue != Sortable.serialize(this.element)) 396 380 this.observer(this.element) … … 398 382 } 399 383 400 Sortable = {384 var Sortable = { 401 385 sortables: new Array(), 386 402 387 options: function(element){ 403 var element = $(element); 404 for(var i=0;i<this.sortables.length;i++) 405 if(this.sortables[i].element == element) 406 return this.sortables[i]; 407 return null; 408 }, 388 element = $(element); 389 return this.sortables.detect(function(s) { return s.element == element }); 390 }, 391 409 392 destroy: function(element){ 410 var element = $(element); 411 for(var i=0;i<this.sortables.length;i++) { 412 if(this.sortables[i].element == element) { 413 var s = this.sortables[i]; 414 Draggables.removeObserver(s.element); 415 for(var j=0;j<s.droppables.length;j++) 416 Droppables.remove(s.droppables[j]); 417 for(var j=0;j<s.draggables.length;j++) 418 s.draggables[j].destroy(); 419 this.sortables.splice(i,1); 420 } 421 } 422 }, 393 element = $(element); 394 this.sortables.findAll(function(s) { return s.element == element }).each(function(s){ 395 Draggables.removeObserver(s.element); 396 s.droppables.each(function(d){ Droppables.remove(d) }); 397 s.draggables.invoke('destroy'); 398 }); 399 this.sortables = this.sortables.reject(function(s) { return s.element == element }); 400 }, 401 423 402 create: function(element) { 424 varelement = $(element);403 element = $(element); 425 404 var options = Object.extend({ 426 405 element: element, 427 406 tag: 'li', // assumes li children, override with tag: 'tagname' 407 dropOnEmpty: false, 408 tree: false, // fixme: unimplemented 428 409 overlap: 'vertical', // one of 'vertical', 'horizontal' 429 410 constraint: 'vertical', // one of 'vertical', 'horizontal', false … … 432 413 only: false, 433 414 hoverclass: null, 434 onChange: function() {}, 435 onUpdate: function() {} 415 ghosting: false, 416 format: null, 417 onChange: Prototype.emptyFunction, 418 onUpdate: Prototype.emptyFunction 436 419 }, arguments[1] || {}); 437 420 438 421 // clear any old sortable with same element 439 422 this.destroy(element); 440 423 441 424 // build options for the draggables 442 425 var options_for_draggable = { 443 426 revert: true, 427 ghosting: options.ghosting, 444 428 constraint: options.constraint, 445 handle: handle }; 429 handle: options.handle }; 430 446 431 if(options.starteffect) 447 432 options_for_draggable.starteffect = options.starteffect; 433 448 434 if(options.reverteffect) 449 435 options_for_draggable.reverteffect = options.reverteffect; 436 else 437 if(options.ghosting) options_for_draggable.reverteffect = function(element) { 438 element.style.top = 0; 439 element.style.left = 0; 440 }; 441 450 442 if(options.endeffect) 451 443 options_for_draggable.endeffect = options.endeffect; 444 452 445 if(options.zindex) 453 446 options_for_draggable.zindex = options.zindex; 454 447 455 448 // build options for the droppables 456 449 var options_for_droppable = { … … 458 451 containment: options.containment, 459 452 hoverclass: options.hoverclass, 460 onHover: function(element, dropon, overlap) { 461 if(overlap>0.5) { 462 if(dropon.previousSibling != element) { 463 var oldParentNode = element.parentNode; 464 element.style.visibility = "hidden"; // fix gecko rendering 465 dropon.parentNode.insertBefore(element, dropon); 466 if(dropon.parentNode!=oldParentNode && oldParentNode.sortable) 467 oldParentNode.sortable.onChange(element); 468 if(dropon.parentNode.sortable) 469 dropon.parentNode.sortable.onChange(element); 470 } 471 } else { 472 var nextElement = dropon.nextSibling || null; 473 if(nextElement != element) { 474 var oldParentNode = element.parentNode; 475 element.style.visibility = "hidden"; // fix gecko rendering 476 dropon.parentNode.insertBefore(element, nextElement); 477 if(dropon.parentNode!=oldParentNode && oldParentNode.sortable) 478 oldParentNode.sortable.onChange(element); 479 if(dropon.parentNode.sortable) 480 dropon.parentNode.sortable.onChange(element); 481 } 482 } 483 } 453 onHover: Sortable.onHover, 454 greedy: !options.dropOnEmpty 484 455 } 485 456 486 457 // fix for gecko engine 487 458 Element.cleanWhitespace(element); 488 459 489 460 options.draggables = []; 490 461 options.droppables = []; 491 492 // make it so 493 var elements = element.childNodes; 494 for (var i = 0; i < elements.length; i++) 495 if(elements[i].tagName && elements[i].tagName==options.tag.toUpperCase() && 496 (!options.only || (Element.Class.has(elements[i], options.only)))) { 497 498 // handles are per-draggable 499 var handle = options.handle ? 500 Element.Class.childrenWith(elements[i], options.handle)[0] : elements[i]; 501 502 options.draggables.push(new Draggable(elements[i], Object.extend(options_for_draggable, { handle: handle }))); 503 504 Droppables.add(elements[i], options_for_droppable); 505 options.droppables.push(elements[i]); 506 507 } 508 462 463 // make it so 464 465 // drop on empty handling 466 if(options.dropOnEmpty) { 467 Droppables.add(element, 468 {containment: options.containment, onHover: Sortable.onEmptyHover, greedy: false}); 469 options.droppables.push(element); 470 } 471 472 (this.findElements(element, options) || []).each( function(e) { 473 // handles are per-draggable 474 var handle = options.handle ? 475 Element.childrenWithClassName(e, options.handle)[0] : e; 476 options.draggables.push( 477 new Draggable(e, Object.extend(options_for_draggable, { handle: handle }))); 478 Droppables.add(e, options_for_droppable); 479 options.droppables.push(e); 480 }); 481 509 482 // keep reference 510 483 this.sortables.push(options); 511 484 512 485 // for onupdate 513 486 Draggables.addObserver(new SortableObserver(element, options.onUpdate)); 514 487 515 488 }, 489 490 // return all suitable-for-sortable elements in a guaranteed order 491 findElements: function(element, options) { 492 if(!element.hasChildNodes()) return null; 493 var elements = []; 494 $A(element.childNodes).each( function(e) { 495 if(e.tagName && e.tagName.toUpperCase()==options.tag.toUpperCase() && 496 (!options.only || (Element.hasClassName(e, options.only)))) 497 elements.push(e); 498 if(options.tree) { 499 var grandchildren = this.findElements(e, options); 500 if(grandchildren) elements.push(grandchildren); 501 } 502 }); 503 504 return (elements.length>0 ? elements.flatten() : null); 505 }, 506 507 onHover: function(element, dropon, overlap) { 508 if(overlap>0.5) { 509 Sortable.mark(dropon, 'before'); 510 if(dropon.previousSibling != element) { 511 var oldParentNode = element.parentNode; 512 element.style.visibility = "hidden"; // fix gecko rendering 513 dropon.parentNode.insertBefore(element, dropon); 514 if(dropon.parentNode!=oldParentNode) 515 Sortable.options(oldParentNode).onChange(element); 516 Sortable.options(dropon.parentNode).onChange(element); 517 } 518 } else { 519 Sortable.mark(dropon, 'after'); 520 var nextElement = dropon.nextSibling || null; 521 if(nextElement != element) { 522 var oldParentNode = element.parentNode; 523 element.style.visibility = "hidden"; // fix gecko rendering 524 dropon.parentNode.insertBefore(element, nextElement); 525 if(dropon.parentNode!=oldParentNode) 526 Sortable.options(oldParentNode).onChange(element); 527 Sortable.options(dropon.parentNode).onChange(element); 528 } 529 } 530 }, 531 532 onEmptyHover: function(element, dropon) { 533 if(element.parentNode!=dropon) { 534 var oldParentNode = element.parentNode; 535 dropon.appendChild(element); 536 Sortable.options(oldParentNode).onChange(element); 537 Sortable.options(dropon).onChange(element); 538 } 539 }, 540 541 unmark: function() { 542 if(Sortable._marker) Element.hide(Sortable._marker); 543 }, 544 545 mark: function(dropon, position) { 546 // mark on ghosting only 547 var sortable = Sortable.options(dropon.parentNode); 548 if(sortable && !sortable.ghosting) return; 549 550 if(!Sortable._marker) { 551 Sortable._marker = $('dropmarker') || document.createElement('DIV'); 552 Element.hide(Sortable._marker); 553 Element.addClassName(Sortable._marker, 'dropmarker'); 554 Sortable._marker.style.position = 'absolute'; 555 document.getElementsByTagName("body").item(0).appendChild(Sortable._marker); 556 } 557 var offsets = Position.cumulativeOffset(dropon); 558 Sortable._marker.style.left = offsets[0] + 'px'; 559 Sortable._marker.style.top = offsets[1] + 'px'; 560 561 if(position=='after') 562 if(sortable.overlap == 'horizontal') 563 Sortable._marker.style.left = (offsets[0]+dropon.clientWidth) + 'px'; 564 else 565 Sortable._marker.style.top = (offsets[1]+dropon.clientHeight) + 'px'; 566 567 Element.show(Sortable._marker); 568 }, 569 516 570 serialize: function(element) { 517 varelement = $(element);571 element = $(element); 518 572 var sortableOptions = this.options(element); 519 573 var options = Object.extend({ 520 574 tag: sortableOptions.tag, 521 575 only: sortableOptions.only, 522 name: element.id 576 name: element.id, 577 format: sortableOptions.format || /^[^_]*_(.*)$/ 523 578 }, arguments[1] || {}); 524 525 var items = $(element).childNodes; 526 var queryComponents = new Array(); 527 528 for(var i=0; i<items.length; i++) 529 if(items[i].tagName && items[i].tagName==options.tag.toUpperCase() && 530 (!options.only || (Element.Class.has(items[i], options.only)))) 531 queryComponents.push( 532 encodeURIComponent(options.name) + "[]=" + 533 encodeURIComponent(items[i].id.split("_")[1])); 534 535 return queryComponents.join("&"); 579 return $(this.findElements(element, options) || []).map( function(item) { 580 return (encodeURIComponent(options.name) + "[]=" + 581 encodeURIComponent(item.id.match(options.format) ? item.id.match(options.format)[1] : '')); 582 }).join("&"); 536 583 } 537 } 584 } -
trunk/public/javascripts/effects.js
r5 r39 1 1 // Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) 2 // 3 // Parts (c) 2005 Justin Palmer (http://encytemedia.com/) 4 // Parts (c) 2005 Mark Pilgrim (http://diveintomark.org/) 2 // Contributors: 3 // Justin Palmer (http://encytemedia.com/) 4 // Mark Pilgrim (http://diveintomark.org/) 5 // Martin Bialasinki 5 6 // 6 // Permission is hereby granted, free of charge, to any person obtaining 7 // a copy of this software and associated documentation files (the 8 // "Software"), to deal in the Software without restriction, including 9 // without limitation the rights to use, copy, modify, merge, publish, 10 // distribute, sublicense, and/or sell copies of the Software, and to 11 // permit persons to whom the Software is furnished to do so, subject to 12 // the following conditions: 13 // 14 // The above copyright notice and this permission notice shall be 15 // included in all copies or substantial portions of the Software. 16 // 17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 21 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 25 26 Effect = {} 27 Effect2 = Effect; // deprecated 7 // See scriptaculous.js for full license. 8 9 /* ------------- element ext -------------- */ 10 11 // converts rgb() and #xxx to #xxxxxx format, 12 // returns self (or first argument) if not convertable 13 String.prototype.parseColor = function() { 14 var color = '#'; 15 if(this.slice(0,4) == 'rgb(') { 16 var cols = this.slice(4,this.length-1).split(','); 17 var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3); 18 } else { 19 if(this.slice(0,1) == '#') { 20 if(this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase(); 21 if(this.length==7) color = this.toLowerCase(); 22 } 23 } 24 return(color.length==7 ? color : (arguments[0] || this)); 25 } 26 27 Element.collectTextNodesIgnoreClass = function(element, ignoreclass) { 28 var children = $(element).childNodes; 29 var text = ''; 30 var classtest = new RegExp('^([^ ]+ )*' + ignoreclass+ '( [^ ]+)*$','i'); 31 32 for (var i = 0; i < children.length; i++) { 33 if(children[i].nodeType==3) { 34 text+=children[i].nodeValue; 35 } else { 36 if((!children[i].className.match(classtest)) && children[i].hasChildNodes()) 37 text += Element.collectTextNodesIgnoreClass(children[i], ignoreclass); 38 } 39 } 40 41 return text; 42 } 43 44 Element.setStyle = function(element, style) { 45 element = $(element); 46 for(k in style) element.style[k.camelize()] = style[k]; 47 } 48 49 Element.setContentZoom = function(element, percent) { 50 Element.setStyle(element, {fontSize: (percent/100) + 'em'}); 51 if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0); 52 } 53 54 Element.getOpacity = function(element){ 55 var opacity; 56 if (opacity = Element.getStyle(element, 'opacity')) 57 return parseFloat(opacity); 58 if (opacity = (Element.getStyle(element, 'filter') || '').match(/alpha\(opacity=(.*)\)/)) 59 if(opacity[1]) return parseFloat(opacity[1]) / 100; 60 return 1.0; 61 } 62 63 Element.setOpacity = function(element, value){ 64 element= $(element); 65 if (value == 1){ 66 Element.setStyle(element, { opacity: 67 (/Gecko/.test(navigator.userAgent) && !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ? 68 0.999999 : null }); 69 if(/MSIE/.test(navigator.userAgent)) 70 Element.setStyle(element, {filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'')}); 71 } else { 72 if(value < 0.00001) value = 0; 73 Element.setStyle(element, {opacity: value}); 74 if(/MSIE/.test(navigator.userAgent)) 75 Element.setStyle(element, 76 { filter: Element.getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'') + 77 'alpha(opacity='+value*100+')' }); 78 } 79 } 80 81 Element.getInlineOpacity = function(element){ 82 return $(element).style.opacity || ''; 83 } 84 85 Element.childrenWithClassName = function(element, className) { 86 return $A($(element).getElementsByTagName('*')).select( 87 function(c) { return Element.hasClassName(c, className) }); 88 } 89 90 Array.prototype.call = function() { 91 var args = arguments; 92 this.each(function(f){ f.apply(this, args) }); 93 } 94 95 /*--------------------------------------------------------------------------*/ 96 97 var Effect = { 98 tagifyText: function(element) { 99 var tagifyStyle = 'position:relative'; 100 if(/MSIE/.test(navigator.userAgent)) tagifyStyle += ';zoom:1'; 101 element = $(element); 102 $A(element.childNodes).each( function(child) { 103 if(child.nodeType==3) { 104 child.nodeValue.toArray().each( function(character) { 105 element.insertBefore( 106 Builder.node('span',{style: tagifyStyle}, 107 character == ' ' ? String.fromCharCode(160) : character), 108 child); 109 }); 110 Element.remove(child); 111 } 112 }); 113 }, 114 multiple: function(element, effect) { 115 var elements; 116 if(((typeof element == 'object') || 117 (typeof element == 'function')) && 118 (element.length)) 119 elements = element; 120 else 121 elements = $(element).childNodes; 122 123 var options = Object.extend({ 124 speed: 0.1, 125 delay: 0.0 126 }, arguments[2] || {}); 127 var masterDelay = options.delay; 128 129 $A(elements).each( function(element, index) { 130 new effect(element, Object.extend(options, { delay: index * options.speed + masterDelay })); 131 }); 132 } 133 }; 134 135 var Effect2 = Effect; // deprecated 28 136 29 137 /* ------------- transitions ------------- */ … … 41 149 } 42 150 Effect.Transitions.flicker = function(pos) { 43 return ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random( 0.25);151 return ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4; 44 152 } 45 153 Effect.Transitions.wobble = function(pos) { … … 57 165 } 58 166 59 /* ------------- element ext -------------- */60 61 Element.makePositioned = function(element) {62 element = $(element);63 if(element.style.position == "")64 element.style.position = "relative";65 }66 67 Element.makeClipping = function(element) {68 element = $(element);69 element._overflow = element.style.overflow || 'visible';70 if(element._overflow!='hidden') element.style.overflow = 'hidden';71 }72 73 Element.undoClipping = function(element) {74 element = $(element);75 if(element._overflow!='hidden') element.style.overflow = element._overflow;76 }77 78 167 /* ------------- core effects ------------- */ 168 169 Effect.Queue = { 170 effects: [], 171 _each: function(iterator) { 172 this.effects._each(iterator); 173 }, 174 interval: null, 175 add: function(effect) { 176 var timestamp = new Date().getTime(); 177 178 switch(effect.options.queue) { 179 case 'front': 180 // move unstarted effects after this effect 181 this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) { 182 e.startOn += effect.finishOn; 183 e.finishOn += effect.finishOn; 184 }); 185 break; 186 case 'end': 187 // start effect after last queued effect has finished 188 timestamp = this.effects.pluck('finishOn').max() || timestamp; 189 break; 190 } 191 192 effect.startOn += timestamp; 193 effect.finishOn += timestamp; 194 this.effects.push(effect); 195 if(!this.interval) 196 this.interval = setInterval(this.loop.bind(this), 40); 197 }, 198 remove: function(effect) { 199 this.effects = this.effects.reject(function(e) { return e==effect }); 200 if(this.effects.length == 0) { 201 clearInterval(this.interval); 202 this.interval = null; 203 } 204 }, 205 loop: function() { 206 var timePos = new Date().getTime(); 207 this.effects.invoke('loop', timePos); 208 } 209 } 210 Object.extend(Effect.Queue, Enumerable); 79 211 80 212 Effect.Base = function() {}; 81 213 Effect.Base.prototype = { 214 position: null, 82 215 setOptions: function(options) { 83 216 this.options = Object.extend({ 84 217 transition: Effect.Transitions.sinoidal, 85 218 duration: 1.0, // seconds 86 fps: 25.0, // max. 100fps219 fps: 25.0, // max. 25fps due to Effect.Queue implementation 87 220 sync: false, // true for combining 88 221 from: 0.0, 89 to: 1.0 222 to: 1.0, 223 delay: 0.0, 224 queue: 'parallel' 90 225 }, options || {}); 91 226 }, … … 93 228 this.setOptions(options || {}); 94 229 this.currentFrame = 0; 95 this.startOn = new Date().getTime(); 230 this.state = 'idle'; 231 this.startOn = this.options.delay*1000; 96 232 this.finishOn = this.startOn + (this.options.duration*1000); 97 if(this.options.beforeStart) this.options.beforeStart(this); 98 if(!this.options.sync) this.loop(); 99 }, 100 loop: function() { 101 var timePos = new Date().getTime(); 102 if(timePos >= this.finishOn) { 103 this.render(this.options.to); 104 if(this.finish) this.finish(); 105 if(this.options.afterFinish) this.options.afterFinish(this); 106 return; 233 this.event('beforeStart'); 234 if(!this.options.sync) Effect.Queue.add(this); 235 }, 236 loop: function(timePos) { 237 if(timePos >= this.startOn) { 238 if(timePos >= this.finishOn) { 239 this.render(1.0); 240 this.cancel(); 241 this.event('beforeFinish'); 242 if(this.finish) this.finish(); 243 this.event('afterFinish'); 244 return; 245 } 246 var pos = (timePos - this.startOn) / (this.finishOn - this.startOn); 247 var frame = Math.round(pos * this.options.fps * this.options.duration); 248 if(frame > this.currentFrame) { 249 this.render(pos); 250 this.currentFrame = frame; 251 } 107 252 } 108 var pos = (timePos - this.startOn) / (this.finishOn - this.startOn); 109 var frame = Math.round(pos * this.options.fps * this.options.duration); 110 if(frame > this.currentFrame) { 111 this.render(pos); 112 this.currentFrame = frame; 253 }, 254 render: function(pos) { 255 if(this.state == 'idle') { 256 this.state = 'running'; 257 this.event('beforeSetup'); 258 if(this.setup) this.setup(); 259 this.event('afterSetup'); 113 260 } 114 this.timeout = setTimeout(this.loop.bind(this), 10);115 },116 render: function(pos) {117 if(this.options.transition) pos = this.options.transition(pos);118 pos *= (this.options.to-this.options.from);119 pos += this.options.from;120 if(this.options.beforeUpdate) this.options.beforeUpdate(this);121 if(this.update) this.update(pos);122 if(this.options.afterUpdate) this.options.afterUpdate(this);261 if(this.state == 'running') { 262 if(this.options.transition) pos = this.options.transition(pos); 263 pos *= (this.options.to-this.options.from); 264 pos += this.options.from; 265 this.position = pos; 266 this.event('beforeUpdate'); 267 if(this.update) this.update(pos); 268 this.event('afterUpdate'); 269 } 123 270 }, 124 271 cancel: function() { 125 if(this.timeout) clearTimeout(this.timeout); 272 if(!this.options.sync) Effect.Queue.remove(this); 273 this.state = 'finished'; 274 }, 275 event: function(eventName) { 276 if(this.options[eventName + 'Internal']) this.options[eventName + 'Internal'](this); 277 if(this.options[eventName]) this.options[eventName](this); 278 }, 279 inspect: function() { 280 return '#<Effect:' + $H(this).inspect() + ',options:' + $H(this.options).inspect() + '>'; 126 281 } 127 282 } … … 134 289 }, 135 290 update: function(position) { 136 for (var i = 0; i < this.effects.length; i++) 137 this.effects[i].render(position); 291 this.effects.invoke('render', position); 138 292 }, 139 293 finish: function(position) { 140 for (var i = 0; i < this.effects.length; i++) 141 if(this.effects[i].finish) this.effects[i].finish(position); 294 this.effects.each( function(effect) { 295 effect.render(1.0); 296 effect.cancel(); 297 effect.event('beforeFinish'); 298 if(effect.finish) effect.finish(position); 299 effect.event('afterFinish'); 300 }); 142 301 } 143 302 }); 144 303 145 // Internet Explorer caveat: works only on elements the have146 // a 'layout', meaning having a given width or height.147 // There is no way to safely set this automatically.148 304 Effect.Opacity = Class.create(); 149 305 Object.extend(Object.extend(Effect.Opacity.prototype, Effect.Base.prototype), { 150 306 initialize: function(element) { 151 307 this.element = $(element); 152 options = Object.extend({ 153 from: 0.0, 308 // make this work on IE on elements without 'layout' 309 if(/MSIE/.test(navigator.userAgent) && (!this.element.hasLayout)) 310 Element.setStyle(this.element, {zoom: 1}); 311 var options = Object.extend({ 312 from: Element.getOpacity(this.element) || 0.0, 154 313 to: 1.0 155 314 }, arguments[1] || {}); … … 157 316 }, 158 317 update: function(position) { 159 this.setOpacity(position); 160 }, 161 setOpacity: function(opacity) { 162 opacity = (opacity == 1) ? 0.99999 : opacity; 163 this.element.style.opacity = opacity; 164 this.element.style.filter = "alpha(opacity:"+opacity*100+")"; 318 Element.setOpacity(this.element, position); 165 319 } 166 320 }); … … 170 324 initialize: function(element, toTop, toLeft) { 171 325 this.element = $(element); 172 this.originalTop = parseFloat(this.element.style.top || '0');173 this.originalLeft = parseFloat(this.element.style.left || '0');174 326 this.toTop = toTop; 175 327 this.toLeft = toLeft; 328 this.start(arguments[3]); 329 }, 330 setup: function() { 331 // Bug in Opera: Opera returns the "real" position of a static element or 332 // relative element that does not have top/left explicitly set. 333 // ==> Always set top and left for position relative elements in your stylesheets 334 // (to 0 if you do not need them) 176 335 Element.makePositioned(this.element); 177 this.start(arguments[3]); 336 this.originalTop = parseFloat(Element.getStyle(this.element,'top') || '0'); 337 this.originalLeft = parseFloat(Element.getStyle(this.element,'left') || '0'); 178 338 }, 179 339 update: function(position) { 180 topd = this.toTop * position + this.originalTop; 181 leftd = this.toLeft * position + this.originalLeft; 182 this.setPosition(topd, leftd); 183 }, 184 setPosition: function(topd, leftd) { 185 this.element.style.top = topd + "px"; 186 this.element.style.left = leftd + "px"; 340 Element.setStyle(this.element, { 341 top: this.toTop * position + this.originalTop + 'px', 342 left: this.toLeft * position + this.originalLeft + 'px' 343 }); 187 344 } 188 345 }); … … 192 349 initialize: function(element, percent) { 193 350 this.element = $(element) 194 options = Object.extend({351 var options = Object.extend({ 195 352 scaleX: true, 196 353 scaleY: true, … … 198 355 scaleFromCenter: false, 199 356 scaleMode: 'box', // 'box' or 'contents' or {} with provided values 200 scaleFrom: 100.0 357 scaleFrom: 100.0, 358 scaleTo: percent 201 359 }, arguments[2] || {}); 202 this.originalTop = this.element.offsetTop;203 this.originalLeft = this.element.offsetLeft;204 if(this.element.style.fontSize=="") this.sizeEm = 1.0;205 if(this.element.style.fontSize && this.element.style.fontSize.indexOf("em")>0)206 this.sizeEm = parseFloat(this.element.style.fontSize);207 this.factor = (percent/100.0) - (options.scaleFrom/100.0);208 if(options.scaleMode=='box') {209 this.originalHeight = this.element.clientHeight;210 this.originalWidth = this.element.clientWidth;211 } else212 if(options.scaleMode=='contents') {213 this.originalHeight = this.element.scrollHeight;214 this.originalWidth = this.element.scrollWidth;215 } else {216 this.originalHeight = options.scaleMode.originalHeight;217 this.originalWidth = options.scaleMode.originalWidth;218 }219 360 this.start(options); 220 361 }, 221 362 setup: function() { 363 this.restoreAfterFinish = this.options.restoreAfterFinish || false; 364 this.elementPositioning = Element.getStyle(this.element,'position'); 365 366 this.originalStyle = {}; 367 ['top','left','width','height','fontSize'].each( function(k) { 368 this.originalStyle[k] = this.element.style[k]; 369 }.bind(this)); 370 371 this.originalTop = this.element.offsetTop; 372 this.originalLeft = this.element.offsetLeft; 373 374 var fontSize = Element.getStyle(this.element,'font-size') || '100%'; 375 ['em','px','%'].each( function(fontSizeType) { 376 if(fontSize.indexOf(fontSizeType)>0) { 377 this.fontSize = parseFloat(fontSize); 378 this.fontSizeType = fontSizeType; 379 } 380 }.bind(this)); 381 382 this.factor = (this.options.scaleTo - this.options.scaleFrom)/100; 383 384 this.dims = null; 385 if(this.options.scaleMode=='box') 386 this.dims = [this.element.offsetHeight, this.element.offsetWidth]; 387 if(/^content/.test(this.options.scaleMode)) 388 this.dims = [this.element.scrollHeight, this.element.scrollWidth]; 389 if(!this.dims) 390 this.dims = [this.options.scaleMode.originalHeight, 391 this.options.scaleMode.originalWidth]; 392 }, 222 393 update: function(position) { 223 currentScale = (this.options.scaleFrom/100.0) + (this.factor * position); 224 if(this.options.scaleContent && this.sizeEm) 225 this.element.style.fontSize = this.sizeEm*currentScale + "em"; 226 this.setDimensions( 227 this.originalWidth * currentScale, 228 this.originalHeight * currentScale); 229 }, 230 231 setDimensions: function(width, height) { 232 if(this.options.scaleX) this.element.style.width = width + 'px'; 233 if(this.options.scaleY) this.element.style.height = height + 'px'; 394 var currentScale = (this.options.scaleFrom/100.0) + (this.factor * position); 395 if(this.options.scaleContent && this.fontSize) 396 Element.setStyle(this.element, {fontSize: this.fontSize * currentScale + this.fontSizeType }); 397 this.setDimensions(this.dims[0] * currentScale, this.dims[1] * currentScale); 398 }, 399 finish: function(position) { 400 if (this.restoreAfterFinish) Element.setStyle(this.element, this.originalStyle); 401 }, 402 setDimensions: function(height, width) { 403 var d = {}; 404 if(this.options.scaleX) d.width = width + 'px'; 405 if(this.options.scaleY) d.height = height + 'px'; 234 406 if(this.options.scaleFromCenter) { 235 topd = (height - this.originalHeight)/2;236 leftd = (width - this.originalWidth)/2;237 if(this.element .style.position=='absolute') {238 if(this.options.scaleY) this.element.style.top = this.originalTop-topd + "px";239 if(this.options.scaleX) this.element.style.left = this.originalLeft-leftd + "px";407 var topd = (height - this.dims[0])/2; 408 var leftd = (width - this.dims[1])/2; 409 if(this.elementPositioning == 'absolute') { 410 if(this.options.scaleY) d.top = this.originalTop-topd + 'px'; 411 if(this.options.scaleX) d.left = this.originalLeft-leftd + 'px'; 240 412 } else { 241 if(this.options.scaleY) this.element.style.top = -topd + "px";242 if(this.options.scaleX) this.element.style.left = -leftd + "px";413 if(this.options.scaleY) d.top = -topd + 'px'; 414 if(this.options.scaleX) d.left = -leftd + 'px'; 243 415 } 244 416 } 417 Element.setStyle(this.element, d); 245 418 } 246 419 }); … … 250 423 initialize: function(element) { 251 424 this.element = $(element); 252 253 // try to parse current background color as default for endcolor 254 // browser stores this as: "rgb(255, 255, 255)", convert to "#ffffff" format 255 var endcolor = "#ffffff"; 256 var current = this.element.style.backgroundColor; 257 if(current && current.slice(0,4) == "rgb(") { 258 endcolor = "#"; 259 var cols = current.slice(4,current.length-1).split(','); 260 var i=0; do { endcolor += parseInt(cols[i]).toColorPart() } while (++i<3); } 261 262 var options = Object.extend({ 263 startcolor: "#ffff99", 264 endcolor: endcolor, 265 restorecolor: current 266 }, arguments[1] || {}); 267 425 var options = Object.extend({ startcolor: '#ffff99' }, arguments[1] || {}); 426 this.start(options); 427 }, 428 setup: function() { 429 // Prevent executing on elements not in the layout flow 430 if(Element.getStyle(this.element, 'display')=='none') { this.cancel(); return; } 431 // Disable background image during the effect 432 this.oldStyle = { 433 backgroundImage: Element.getStyle(this.element, 'background-image') }; 434 Element.setStyle(this.element, {backgroundImage: 'none'}); 435 if(!this.options.endcolor) 436 this.options.endcolor = Element.getStyle(this.element, 'background-color').parseColor('#ffffff'); 437 if(!this.options.restorecolor) 438 this.options.restorecolor = Element.getStyle(this.element, 'background-color'); 268 439 // init color calculations 269 this.colors_base = [ 270 parseInt(options.startcolor.slice(1,3),16), 271 parseInt(options.startcolor.slice(3,5),16), 272 parseInt(options.startcolor.slice(5),16) ]; 273 this.colors_delta = [ 274 parseInt(options.endcolor.slice(1,3),16)-this.colors_base[0], 275 parseInt(options.endcolor.slice(3,5),16)-this.colors_base[1], 276 parseInt(options.endcolor.slice(5),16)-this.colors_base[2] ]; 277 278 this.start(options); 440 this._base = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this)); 441 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)); 279 442 }, 280 443 update: function(position) { 281 var colors = [ 282 Math.round(this.colors_base[0]+(this.colors_delta[0]*position)), 283 Math.round(this.colors_base[1]+(this.colors_delta[1]*position)), 284 Math.round(this.colors_base[2]+(this.colors_delta[2]*position)) ]; 285 this.element.style.backgroundColor = "#" + 286 colors[0].toColorPart() + colors[1].toColorPart() + colors[2].toColorPart(); 444 Element.setStyle(this.element,{backgroundColor: $R(0,2).inject('#',function(m,v,i){ 445 return m+(Math.round(this._base[i]+(this._delta[i]*position)).toColorPart()); }.bind(this)) }); 287 446 }, 288 447 finish: function() { 289 this.element.style.backgroundColor = this.options.restorecolor; 448 Element.setStyle(this.element, Object.extend(this.oldStyle, { 449 backgroundColor: this.options.restorecolor 450 })); 290 451 } 291 452 }); … … 295 456 initialize: function(element) { 296 457 this.element = $(element); 458 this.start(arguments[1] || {}); 459 }, 460 setup: function() { 297 461 Position.prepare(); 298 462 var offsets = Position.cumulativeOffset(this.element); 463 if(this.options.offset) offsets[1] += this.options.offset; 299 464 var max = window.innerHeight ? 300 465 window.height - window.innerHeight : … … 303 468 document.documentElement.clientHeight : document.body.clientHeight); 304 469 this.scrollStart = Position.deltaY; 305 this.delta = (offsets[1] > max ? max : offsets[1]) - this.scrollStart; 306 this.start(arguments[1] || {}); 470 this.delta = (offsets[1] > max ? max : offsets[1]) - this.scrollStart; 307 471 }, 308 472 update: function(position) { … … 313 477 }); 314 478 315 /* ------------- prepackagedeffects ------------- */479 /* ------------- combination effects ------------- */ 316 480 317 481 Effect.Fade = function(element) { 318 options = Object.extend({ 319 from: 1.0, 482 var oldOpacity = Element.getInlineOpacity(element); 483 var options = Object.extend({ 484 from: Element.getOpacity(element) || 1.0, 320 485 to: 0.0, 321 afterFinish: function(effect) 322 { Element.hide(effect.element); 323 effect.setOpacity(1); } 486 afterFinishInternal: function(effect) { with(Element) { 487 if(effect.options.to!=0) return; 488 hide(effect.element); 489 setStyle(effect.element, {opacity: oldOpacity}); }} 324 490 }, arguments[1] || {}); 325 new Effect.Opacity(element,options);491 return new Effect.Opacity(element,options); 326 492 } 327 493 328 494 Effect.Appear = function(element) { 329 options = Object.extend({330 from: 0.0,495 var options = Object.extend({ 496 from: (Element.getStyle(element, 'display') == 'none' ? 0.0 : Element.getOpacity(element) || 0.0), 331 497 to: 1.0, 332 beforeStart: function(effect) 333 { effect.setOpacity(0); 334 Element.show(effect.element); }, 335 afterUpdate: function(effect) 336 { Element.show(effect.element); } 498 beforeSetup: function(effect) { with(Element) { 499 setOpacity(effect.element, effect.options.from); 500 show(effect.element); }} 337 501 }, arguments[1] || {}); 338 new Effect.Opacity(element,options);502 return new Effect.Opacity(element,options); 339 503 } 340 504 341 505 Effect.Puff = function(element) { 342 new Effect.Parallel( 343 [ new Effect.Scale(element, 200, { sync: true, scaleFromCenter: true }), 344 new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0 } ) ], 345 { duration: 1.0, 346 afterUpdate: function(effect) 347 { effect.effects[0].element.style.position = 'absolute'; }, 348 afterFinish: function(effect) 349 { Element.hide(effect.effects[0].element); } 350 } 506 element = $(element); 507 var oldStyle = { opacity: Element.getInlineOpacity(element), position: Element.getStyle(element, 'position') }; 508 return new Effect.Parallel( 509 [ new Effect.Scale(element, 200, 510 { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }), 511 new Effect.Opacity(element, { sync: true, to: 0.0 } ) ], 512 Object.extend({ duration: 1.0, 513 beforeSetupInternal: function(effect) { with(Element) { 514 setStyle(effect.effects[0].element, {position: 'absolute'}); }}, 515 afterFinishInternal: function(effect) { with(Element) { 516 hide(effect.effects[0].element); 517 setStyle(effect.effects[0].element, oldStyle); }} 518 }, arguments[1] || {}) 351 519 ); 352 520 } 353 521 354 522 Effect.BlindUp = function(element) { 523 element = $(element); 355 524 Element.makeClipping(element); 356 new Effect.Scale(element, 0,525 return new Effect.Scale(element, 0, 357 526 Object.extend({ scaleContent: false, 358 527 scaleX: false, 359 afterFinish: function(effect) 360 { 361 Element.hide(effect.element); 362 Element.undoClipping(effect.element); 363 } 528 restoreAfterFinish: true, 529 afterFinishInternal: function(effect) { with(Element) { 530 [hide, undoClipping].call(effect.element); }} 364 531 }, arguments[1] || {}) 365 532 ); … … 367 534 368 535 Effect.BlindDown = function(element) { 369 $(element).style.height = '0px';370 Element.makeClipping(element);371 Element.show(element);372 new Effect.Scale(element, 100,536 element = $(element); 537 var oldHeight = Element.getStyle(element, 'height'); 538 var elementDimensions = Element.getDimensions(element); 539 return new Effect.Scale(element, 100, 373 540 Object.extend({ scaleContent: false, 374 scaleX: false, 375 scaleMode: 'contents', 541 scaleX: false, 376 542 scaleFrom: 0, 377 afterFinish: function(effect) { 378 Element.undoClipping(effect.element); 379 } 543 scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width}, 544 restoreAfterFinish: true, 545 afterSetup: function(effect) { with(Element) { 546 makeClipping(effect.element); 547 setStyle(effect.element, {height: '0px'}); 548 show(effect.element); 549 }}, 550 afterFinishInternal: function(effect) { with(Element) { 551 undoClipping(effect.element); 552 setStyle(effect.element, {height: oldHeight}); 553 }} 380 554 }, arguments[1] || {}) 381 555 ); … … 383 557 384 558 Effect.SwitchOff = function(element) { 385 new Effect.Appear(element, 386 { duration: 0.4, 387 transition: Effect.Transitions.flicker, 388 afterFinish: function(effect) 389 { effect.element.style.overflow = 'hidden'; 390 new Effect.Scale(effect.element, 1, 391 { duration: 0.3, scaleFromCenter: true, 392 scaleX: false, scaleContent: false, 393 afterUpdate: function(effect) { 394 if(effect.element.style.position=="") 395 effect.element.style.position = 'relative'; }, 396 afterFinish: function(effect) { Element.hide(effect.element); } 397 } ) 398 } 399 } ); 559 element = $(element); 560 var oldOpacity = Element.getInlineOpacity(element); 561 return new Effect.Appear(element, { 562 duration: 0.4, 563 from: 0, 564 transition: Effect.Transitions.flicker, 565 afterFinishInternal: function(effect) { 566 new Effect.Scale(effect.element, 1, { 567 duration: 0.3, scaleFromCenter: true, 568 scaleX: false, scaleContent: false, restoreAfterFinish: true, 569 beforeSetup: function(effect) { with(Element) { 570 [makePositioned,makeClipping].call(effect.element); 571 }}, 572 afterFinishInternal: function(effect) { with(Element) { 573 [hide,undoClipping,undoPositioned].call(effect.element); 574 setStyle(effect.element, {opacity: oldOpacity}); 575 }} 576 }) 577 } 578 }); 400 579 } 401 580 402 581 Effect.DropOut = function(element) { 403 new Effect.Parallel( 582 element = $(element); 583 var oldStyle = { 584 top: Element.getStyle(element, 'top'), 585 left: Element.getStyle(element, 'left'), 586 opacity: Element.getInlineOpacity(element) }; 587 return new Effect.Parallel( 404 588 [ new Effect.MoveBy(element, 100, 0, { sync: true }), 405 new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0 } ) ], 406 { duration: 0.5, 407 afterFinish: function(effect) 408 { Element.hide(effect.effects[0].element); } 409 }); 589 new Effect.Opacity(element, { sync: true, to: 0.0 }) ], 590 Object.extend( 591 { duration: 0.5, 592 beforeSetup: function(effect) { with(Element) { 593 makePositioned(effect.effects[0].element); }}, 594 afterFinishInternal: function(effect) { with(Element) { 595 [hide, undoPositioned].call(effect.effects[0].element); 596 setStyle(effect.effects[0].element, oldStyle); }} 597 }, arguments[1] || {})); 410 598 } 411 599 412 600 Effect.Shake = function(element) { 413 new Effect.MoveBy(element, 0, 20, 414 { duration: 0.05, afterFinish: function(effect) { 601 element = $(element); 602 var oldStyle = { 603 top: Element.getStyle(element, 'top'), 604 left: Element.getStyle(element, 'left') }; 605 return new Effect.MoveBy(element, 0, 20, 606 { duration: 0.05, afterFinishInternal: function(effect) { 415 607 new Effect.MoveBy(effect.element, 0, -40, 416 { duration: 0.1, afterFinish : function(effect) {608 { duration: 0.1, afterFinishInternal: function(effect) { 417 609 new Effect.MoveBy(effect.element, 0, 40, 418 { duration: 0.1, afterFinish : function(effect) {610 { duration: 0.1, afterFinishInternal: function(effect) { 419 611 new Effect.MoveBy(effect.element, 0, -40, 420 { duration: 0.1, afterFinish : function(effect) {612 { duration: 0.1, afterFinishInternal: function(effect) { 421 613 new Effect.MoveBy(effect.element, 0, 40, 422 { duration: 0.1, afterFinish : function(effect) {614 { duration: 0.1, afterFinishInternal: function(effect) { 423 615 new Effect.MoveBy(effect.element, 0, -20, 424 { duration: 0.05, afterFinish: function(effect) { 425 }}) }}) }}) }}) }}) }}); 616 { duration: 0.05, afterFinishInternal: function(effect) { with(Element) { 617 undoPositioned(effect.element); 618 setStyle(effect.element, oldStyle); 619 }}}) }}) }}) }}) }}) }}); 426 620 } 427 621 428 622 Effect.SlideDown = function(element) { 429 623 element = $(element); 430 element.style.height = '0px';431 Element.makeClipping(element);432 624 Element.cleanWhitespace(element); 433 Element.makePositioned(element.firstChild); 434 Element.show(element); 435 new Effect.Scale(element, 100, 625 // SlideDown need to have the content of the element wrapped in a container element with fixed height! 626 var oldInnerBottom = Element.getStyle(element.firstChild, 'bottom'); 627 var elementDimensions = Element.getDimensions(element); 628 return new Effect.Scale(element, 100, Object.extend({ 629 scaleContent: false, 630 scaleX: false, 631 scaleFrom: 0, 632 scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width}, 633 restoreAfterFinish: true, 634 afterSetup: function(effect) { with(Element) { 635 makePositioned(effect.element); 636 makePositioned(effect.element.firstChild); 637 if(window.opera) setStyle(effect.element, {top: ''}); 638 makeClipping(effect.element); 639 setStyle(effect.element, {height: '0px'}); 640 show(element); }}, 641 afterUpdateInternal: function(effect) { with(Element) { 642 setStyle(effect.element.firstChild, {bottom: 643 (effect.dims[0] - effect.element.clientHeight) + 'px' }); }}, 644 afterFinishInternal: function(effect) { with(Element) { 645 undoClipping(effect.element); 646 undoPositioned(effect.element.firstChild); 647 undoPositioned(effect.element); 648 setStyle(effect.element.firstChild, {bottom: oldInnerBottom}); }} 649 }, arguments[1] || {}) 650 ); 651 } 652 653 Effect.SlideUp = function(element) { 654 element = $(element); 655 Element.cleanWhitespace(element); 656 var oldInnerBottom = Element.getStyle(element.firstChild, 'bottom'); 657 return new Effect.Scale(element, 0, 436 658 Object.extend({ scaleContent: false, 437 659 scaleX: false, 438 scaleMode: 'contents', 439 scaleFrom: 0, 440 afterUpdate: function(effect) 441 { effect.element.firstChild.style.bottom = 442 (effect.originalHeight - effect.element.clientHeight) + 'px'; }, 443 afterFinish: function(effect) 444 { Element.undoClipping(effect.element); } 445 }, arguments[1] || {}) 446 ); 447 } 448 449 Effect.SlideUp = function(element) { 450 element = $(element); 451 Element.makeClipping(element); 452 Element.cleanWhitespace(element); 453 Element.makePositioned(element.firstChild); 454 Element.show(element); 455 new Effect.Scale(element, 0, 456 Object.extend({ scaleContent: false, 457 scaleX: false, 458 afterUpdate: function(effect) 459 { effect.element.firstChild.style.bottom = 460 (effect.originalHeight - effect.element.clientHeight) + 'px'; }, 461 afterFinish: function(effect) 462 { 463 Element.hide(effect.element); 464 Element.undoClipping(effect.element); 465 } 660 scaleMode: 'box', 661 scaleFrom: 100, 662 restoreAfterFinish: true, 663 beforeStartInternal: function(effect) { with(Element) { 664 makePositioned(effect.element); 665 makePositioned(effect.element.firstChild); 666 if(window.opera) setStyle(effect.element, {top: ''}); 667 makeClipping(effect.element); 668 show(element); }}, 669 afterUpdateInternal: function(effect) { with(Element) { 670 setStyle(effect.element.firstChild, {bottom: 671 (effect.dims[0] - effect.element.clientHeight) + 'px' }); }}, 672 afterFinishInternal: function(effect) { with(Element) { 673 [hide, undoClipping].call(effect.element); 674 undoPositioned(effect.element.firstChild); 675 undoPositioned(effect.element); 676 setStyle(effect.element.firstChild, {bottom: oldInnerBottom}); }} 466 677 }, arguments[1] || {}) 467 678 ); 468 679 } 469 680 681 // Bug in opera makes the TD containing this element expand for a instance after finish 470 682 Effect.Squish = function(element) { 471 new Effect.Scale(element, 0, 472 { afterFinish: function(effect) { Element.hide(effect.element); } }); 683 return new Effect.Scale(element, window.opera ? 1 : 0, 684 { restoreAfterFinish: true, 685 beforeSetup: function(effect) { with(Element) { 686 makeClipping(effect.element); }}, 687 afterFinishInternal: function(effect) { with(Element) { 688 hide(effect.element); 689 undoClipping(effect.element); }} 690 }); 473 691 } 474 692 475 693 Effect.Grow = function(element) { 476 694 element = $(element); 477 var options = arguments[1] || {}; 478 479 var originalWidth = element.clientWidth; 480 var originalHeight = element.clientHeight; 481 element.style.overflow = 'hidden'; 482 Element.show(element); 483 484 var direction = options.direction || 'center'; 485 var moveTransition = options.moveTransition || Effect.Transitions.sinoidal; 486 var scaleTransition = options.scaleTransition || Effect.Transitions.sinoidal; 487 var opacityTransition = options.opacityTransition || Effect.Transitions.full; 488 695 var options = Object.extend({ 696 direction: 'center', 697 moveTransistion: Effect.Transitions.sinoidal, 698 scaleTransition: Effect.Transitions.sinoidal, 699 opacityTransition: Effect.Transitions.full 700 }, arguments[1] || {}); 701 var oldStyle = { 702 top: element.style.top, 703 left: element.style.left, 704 height: element.style.height, 705 width: element.style.width, 706 opacity: Element.getInlineOpacity(element) }; 707 708 var dims = Element.getDimensions(element); 489 709 var initialMoveX, initialMoveY; 490 710 var moveX, moveY; 491 711 492 switch ( direction) {712 switch (options.direction) { 493 713 case 'top-left': 494 714 initialMoveX = initialMoveY = moveX = moveY = 0; 495 715 break; 496 716 case 'top-right': 497 initialMoveX = originalWidth;717 initialMoveX = dims.width; 498 718 initialMoveY = moveY = 0; 499 moveX = - originalWidth;719 moveX = -dims.width; 500 720 break; 501 721 case 'bottom-left': 502 722 initialMoveX = moveX = 0; 503 initialMoveY = originalHeight;504 moveY = - originalHeight;723 initialMoveY = dims.height; 724 moveY = -dims.height; 505 725 break; 506 726 case 'bottom-right': 507 initialMoveX = originalWidth;508 initialMoveY = originalHeight;509 moveX = - originalWidth;510 moveY = - originalHeight;727 initialMoveX = dims.width; 728 initialMoveY = dims.height; 729 moveX = -dims.width; 730 moveY = -dims.height; 511 731 break; 512 732 case 'center': 513 initialMoveX = originalWidth / 2;514 initialMoveY = originalHeight / 2;515 moveX = - originalWidth / 2;516 moveY = - originalHeight / 2;733 initialMoveX = dims.width / 2; 734 initialMoveY = dims.height / 2; 735 moveX = -dims.width / 2; 736 moveY = -dims.height / 2; 517 737 break; 518 738 } 519 739 520 new Effect.MoveBy(element, initialMoveY, initialMoveX, {740 return new Effect.MoveBy(element, initialMoveY, initialMoveX, { 521 741 duration: 0.01, 522 beforeUpdate: function(effect) { $(element).style.height = '0px'; }, 523 afterFinish: function(effect) { 742 beforeSetup: function(effect) { with(Element) { 743 hide(effect.element); 744 makeClipping(effect.element); 745 makePositioned(effect.element); 746 }}, 747 afterFinishInternal: function(effect) { 524 748 new Effect.Parallel( 525 [ new Effect.Opacity(element, { sync: true, to: 1.0, from: 0.0, transition: opacityTransition }), 526 new Effect.MoveBy(element, moveY, moveX, { sync: true, transition: moveTransition }), 527 new Effect.Scale(element, 100, { 528 scaleMode: { originalHeight: originalHeight, originalWidth: originalWidth }, 529 sync: true, scaleFrom: 0, scaleTo: 100, transition: scaleTransition })], 530 options); } 531 }); 749 [ new Effect.Opacity(effect.element, { sync: true, to: 1.0, from: 0.0, transition: options.opacityTransition }), 750 new Effect.MoveBy(effect.element, moveY, moveX, { sync: true, transition: options.moveTransition }), 751 new Effect.Scale(effect.element, 100, { 752 scaleMode: { originalHeight: dims.height, originalWidth: dims.width }, 753 sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true}) 754 ], Object.extend({ 755 beforeSetup: function(effect) { with(Element) { 756 setStyle(effect.effects[0].element, {height: '0px'}); 757 show(effect.effects[0].element); }}, 758 afterFinishInternal: function(effect) { with(Element) { 759 [undoClipping, undoPositioned].call(effect.effects[0].element); 760 setStyle(effect.effects[0].element, oldStyle); }} 761 }, options) 762 ) 763 } 764 }); 532 765 } 533 766 534 767 Effect.Shrink = function(element) { 535 768 element = $(element); 536 var options = arguments[1] || {}; 537 538 var originalWidth = element.clientWidth; 539 var originalHeight = element.clientHeight; 540 element.style.overflow = 'hidden'; 541 Element.show(element); 542 543 var direction = options.direction || 'center'; 544 var moveTransition = options.moveTransition || Effect.Transitions.sinoidal; 545 var scaleTransition = options.scaleTransition || Effect.Transitions.sinoidal; 546 var opacityTransition = options.opacityTransition || Effect.Transitions.none; 547 769 var options = Object.extend({ 770 direction: 'center', 771 moveTransistion: Effect.Transitions.sinoidal, 772 scaleTransition: Effect.Transitions.sinoidal, 773 opacityTransition: Effect.Transitions.none 774 }, arguments[1] || {}); 775 var oldStyle = { 776 top: element.style.top, 777 left: element.style.left, 778 height: element.style.height, 779 width: element.style.width, 780 opacity: Element.getInlineOpacity(element) }; 781 782 var dims = Element.getDimensions(element); 548 783 var moveX, moveY; 549 784 550 switch ( direction) {785 switch (options.direction) { 551 786 case 'top-left': 552 787 moveX = moveY = 0; 553 788 break; 554 789 case 'top-right': 555 moveX = originalWidth;790 moveX = dims.width; 556 791 moveY = 0; 557 792 break; 558 793 case 'bottom-left': 559 794 moveX = 0; 560 moveY = originalHeight;795 moveY = dims.height; 561 796 break; 562 797 case 'bottom-right': 563 moveX = originalWidth;564 moveY = originalHeight;798 moveX = dims.width; 799 moveY = dims.height; 565 800 break; 566 801 case 'center': 567 moveX = originalWidth / 2;568 moveY = originalHeight / 2;802 moveX = dims.width / 2; 803 moveY = dims.height / 2; 569 804 break; 570 805 } 571 806 572 new Effect.Parallel( 573 [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: opacityTransition }), 574 new Effect.Scale(element, 0, { sync: true, transition: moveTransition }), 575 new Effect.MoveBy(element, moveY, moveX, { sync: true, transition: scaleTransition }) ], 576 options); 807 return new Effect.Parallel( 808 [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }), 809 new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}), 810 new Effect.MoveBy(element, moveY, moveX, { sync: true, transition: options.moveTransition }) 811 ], Object.extend({ 812 beforeStartInternal: function(effect) { with(Element) { 813 [makePositioned, makeClipping].call(effect.effects[0].element) }}, 814 afterFinishInternal: function(effect) { with(Element) { 815 [hide, undoClipping, undoPositioned].call(effect.effects[0].element); 816 setStyle(effect.effects[0].element, oldStyle); }} 817 }, options) 818 ); 577 819 } 578 820 579 821 Effect.Pulsate = function(element) { 822 element = $(element); 580 823 var options = arguments[1] || {}; 824 var oldOpacity = Element.getInlineOpacity(element); 581 825 var transition = options.transition || Effect.Transitions.sinoidal; 582 826 var reverser = function(pos){ return transition(1-Effect.Transitions.pulse(pos)) }; 583 827 reverser.bind(transition); 584 new Effect.Opacity(element,585 Object.extend(Object.extend({ duration: 3.0, 586 afterFinish: function(effect) { Element.show(effect.element); }828 return new Effect.Opacity(element, 829 Object.extend(Object.extend({ duration: 3.0, from: 0, 830 afterFinishInternal: function(effect) { Element.setStyle(effect.element, {opacity: oldOpacity}); } 587 831 }, options), {transition: reverser})); 588 832 } 589 833 590 834 Effect.Fold = function(element) { 591 $(element).style.overflow = 'hidden'; 592 new Effect.Scale(element, 5, Object.extend({ 593 scaleContent: false, 594 scaleTo: 100, 595 scaleX: false, 596 afterFinish: function(effect) { 597 new Effect.Scale(element, 1, { 598 scaleContent: false, 599 scaleTo: 0, 600 scaleY: false, 601 afterFinish: function(effect) { Element.hide(effect.element) } }); 602 }}, arguments[1] || {})); 603 } 604 605 // old: new Effect.ContentZoom(element, percent) 606 // new: Element.setContentZoom(element, percent) 607 608 Element.setContentZoom = function(element, percent) { 609 var element = $(element); 610 element.style.fontSize = (percent/100) + "em"; 611 if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0); 612 } 835 element = $(element); 836 var oldStyle = { 837 top: element.style.top, 838 left: element.style.left, 839 width: element.style.width, 840 height: element.style.height }; 841 Element.makeClipping(element); 842 return new Effect.Scale(element, 5, Object.extend({ 843 scaleContent: false, 844 scaleX: false, 845 afterFinishInternal: function(effect) { 846 new Effect.Scale(element, 1, { 847 scaleContent: false, 848 scaleY: false, 849 afterFinishInternal: function(effect) { with(Element) { 850 [hide, undoClipping].call(effect.element); 851 setStyle(effect.element, oldStyle); 852 }} }); 853 }}, arguments[1] || {})); 854 } -
trunk/public/javascripts/prototype.js
r5 r39 1 /* Prototype JavaScript framework, version 1. 3.11 /* Prototype JavaScript framework, version 1.4.0 2 2 * (c) 2005 Sam Stephenson <sam@conio.net> 3 3 * 4 4 * THIS FILE IS AUTOMATICALLY GENERATED. When sending patches, please diff 5 * against the source tree, available from the Prototype darcs repository. 5 * against the source tree, available from the Prototype darcs repository. 6 6 * 7 7 * Prototype is freely distributable under the terms of an MIT-style license. … … 12 12 13 13 var Prototype = { 14 Version: '1.3.1', 15 emptyFunction: function() {} 14 Version: '1.4.0', 15 ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)', 16 17 emptyFunction: function() {}, 18 K: function(x) {return x} 16 19 } 17 20 18 21 var Class = { 19 22 create: function() { 20 return function() { 23 return function() { 21 24 this.initialize.apply(this, arguments); 22 25 } … … 33 36 } 34 37 35 Object.prototype.extend = function(object) { 36 return Object.extend.apply(this, [this, object]); 37 } 38 39 Function.prototype.bind = function(object) { 40 var __method = this; 38 Object.inspect = function(object) { 39 try { 40 if (object == undefined) return 'undefined'; 41 if (object == null) return 'null'; 42 return object.inspect ? object.inspect() : object.toString(); 43 } catch (e) { 44 if (e instanceof RangeError) return '...'; 45 throw e; 46 } 47 } 48 49 Function.prototype.bind = function() { 50 var __method = this, args = $A(arguments), object = args.shift(); 41 51 return function() { 42 __method.apply(object, arguments);52 return __method.apply(object, args.concat($A(arguments))); 43 53 } 44 54 } … … 47 57 var __method = this; 48 58 return function(event) { 49 __method.call(object, event || window.event); 50 } 51 } 52 53 Number.prototype.toColorPart = function() { 54 var digits = this.toString(16); 55 if (this < 16) return '0' + digits; 56 return digits; 57 } 59 return __method.call(object, event || window.event); 60 } 61 } 62 63 Object.extend(Number.prototype, { 64 toColorPart: function() { 65 var digits = this.toString(16); 66 if (this < 16) return '0' + digits; 67 return digits; 68 }, 69 70 succ: function() { 71 return this + 1; 72 }, 73 74 times: function(iterator) { 75 $R(0, this, true).each(iterator); 76 return this; 77 } 78 }); 58 79 59 80 var Try = { … … 91 112 onTimerEvent: function() { 92 113 if (!this.currentlyExecuting) { 93 try { 114 try { 94 115 this.currentlyExecuting = true; 95 this.callback(); 96 } finally { 116 this.callback(); 117 } finally { 97 118 this.currentlyExecuting = false; 98 119 } … … 111 132 element = document.getElementById(element); 112 133 113 if (arguments.length == 1) 134 if (arguments.length == 1) 114 135 return element; 115 136 … … 119 140 return elements; 120 141 } 121 122 if (!Array.prototype.push) { 123 Array.prototype.push = function() { 124 var startLength = this.length; 125 for (var i = 0; i < arguments.length; i++) 126 this[startLength + i] = arguments[i]; 127 return this.length; 128 } 129 } 130 131 if (!Function.prototype.apply) { 132 // Based on code from http://www.youngpup.net/ 133 Function.prototype.apply = function(object, parameters) { 134 var parameterStrings = new Array(); 135 if (!object) object = window; 136 if (!parameters) parameters = new Array(); 137 138 for (var i = 0; i < parameters.length; i++) 139 parameterStrings[i] = 'parameters[' + i + ']'; 140 141 object.__apply__ = this; 142 var result = eval('object.__apply__(' + 143 parameterStrings[i].join(', ') + ')'); 144 object.__apply__ = null; 145 146 return result; 147 } 148 } 149 150 String.prototype.extend({ 142 Object.extend(String.prototype, { 151 143 stripTags: function() { 152 144 return this.replace(/<\/?[^>]+>/gi, ''); 145 }, 146 147 stripScripts: function() { 148 return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), ''); 149 }, 150 151 extractScripts: function() { 152 var matchAll = new RegExp(Prototype.ScriptFragment, 'img'); 153 var matchOne = new RegExp(Prototype.ScriptFragment, 'im'); 154 return (this.match(matchAll) || []).map(function(scriptTag) { 155 return (scriptTag.match(matchOne) || ['', ''])[1]; 156 }); 157 }, 158 159 evalScripts: function() { 160 return this.extractScripts().map(eval); 153 161 }, 154 162 … … 163 171 var div = document.createElement('div'); 164 172 div.innerHTML = this.stripTags(); 165 return div.childNodes[0].nodeValue; 166 } 167 }); 173 return div.childNodes[0] ? div.childNodes[0].nodeValue : ''; 174 }, 175 176 toQueryParams: function() { 177 var pairs = this.match(/^\??(.*)$/)[1].split('&'); 178 return pairs.inject({}, function(params, pairString) { 179 var pair = pairString.split('='); 180 params[pair[0]] = pair[1]; 181 return params; 182 }); 183 }, 184 185 toArray: function() { 186 return this.split(''); 187 }, 188 189 camelize: function() { 190 var oStringList = this.split('-'); 191 if (oStringList.length == 1) return oStringList[0]; 192 193 var camelizedString = this.indexOf('-') == 0 194 ? oStringList[0].charAt(0).toUpperCase() + oStringList[0].substring(1) 195 : oStringList[0]; 196 197 for (var i = 1, len = oStringList.length; i < len; i++) { 198 var s = oStringList[i]; 199 camelizedString += s.charAt(0).toUpperCase() + s.substring(1); 200 } 201 202 return camelizedString; 203 }, 204 205 inspect: function() { 206 return "'" + this.replace('\\', '\\\\').replace("'", '\\\'') + "'"; 207 } 208 }); 209 210 String.prototype.parseQuery = String.prototype.toQueryParams; 211 212 var $break = new Object(); 213 var $continue = new Object(); 214 215 var Enumerable = { 216 each: function(iterator) { 217 var index = 0; 218 try { 219 this._each(function(value) { 220 try { 221 iterator(value, index++); 222 } catch (e) { 223 if (e != $continue) throw e; 224 } 225 }); 226 } catch (e) { 227 if (e != $break) throw e; 228 } 229 }, 230 231 all: function(iterator) { 232 var result = true; 233 this.each(function(value, index) { 234 result = result && !!(iterator || Prototype.K)(value, index); 235 if (!result) throw $break; 236 }); 237 return result; 238 }, 239 240 any: function(iterator) { 241 var result = true; 242 this.each(function(value, index) { 243 if (result = !!(iterator || Prototype.K)(value, index)) 244 throw $break; 245 }); 246 return result; 247 }, 248 249 collect: function(iterator) { 250 var results = []; 251 this.each(function(value, index) { 252 results.push(iterator(value, index)); 253 }); 254 return results; 255 }, 256 257 detect: function (iterator) { 258 var result; 259 this.each(function(value, index) { 260 if (iterator(value, index)) { 261 result = value; 262 throw $break; 263 } 264 }); 265 return result; 266 }, 267 268 findAll: function(iterator) { 269 var results = []; 270 this.each(function(value, index) { 271 if (iterator(value, index)) 272 results.push(value); 273 }); 274 return results; 275 }, 276 277 grep: function(pattern, iterator) { 278 var results = []; 279 this.each(function(value, index) { 280 var stringValue = value.toString(); 281 if (stringValue.match(pattern)) 282 results.push((iterator || Prototype.K)(value, index)); 283 }) 284 return results; 285 }, 286 287 include: function(object) { 288 var found = false; 289 this.each(function(value) { 290 if (value == object) { 291 found = true; 292 throw $break; 293 } 294 }); 295 return found; 296 }, 297 298 inject: function(memo, iterator) { 299 this.each(function(value, index) { 300 memo = iterator(memo, value, index); 301 }); 302 return memo; 303 }, 304 305 invoke: function(method) { 306 var args = $A(arguments).slice(1); 307 return this.collect(function(value) { 308 return value[method].apply(value, args); 309 }); 310 }, 311 312 max: function(iterator) { 313 var result; 314 this.each(function(value, index) { 315 value = (iterator || Prototype.K)(value, index); 316 if (value >= (result || value)) 317 result = value; 318 }); 319 return result; 320 }, 321 322 min: function(iterator) { 323 var result; 324 this.each(function(value, index) { 325 value = (iterator || Prototype.K)(value, index); 326 if (value <= (result || value)) 327 result = value; 328 }); 329 return result; 330 }, 331 332 partition: function(iterator) { 333 var trues = [], falses = []; 334 this.each(function(value, index) { 335 ((iterator || Prototype.K)(value, index) ? 336 trues : falses).push(value); 337 }); 338 return [trues, falses]; 339 }, 340 341 pluck: function(property) { 342 var results = []; 343 this.each(function(value, index) { 344 results.push(value[property]); 345 }); 346 return results; 347 }, 348 349 reject: function(iterator) { 350 var results = []; 351 this.each(function(value, index) { 352 if (!iterator(value, index)) 353 results.push(value); 354 }); 355 return results; 356 }, 357 358 sortBy: function(iterator) { 359 return this.collect(function(value, index) { 360 return {value: value, criteria: iterator(value, index)}; 361 }).sort(function(left, right) { 362 var a = left.criteria, b = right.criteria; 363 return a < b ? -1 : a > b ? 1 : 0; 364 }).pluck('value'); 365 }, 366 367 toArray: function() { 368 return this.collect(Prototype.K); 369 }, 370 371 zip: function() { 372 var iterator = Prototype.K, args = $A(arguments); 373 if (typeof args.last() == 'function') 374 iterator = args.pop(); 375 376 var collections = [this].concat(args).map($A); 377 return this.map(function(value, index) { 378 iterator(value = collections.pluck(index)); 379 return value; 380 }); 381 }, 382 383 inspect: function() { 384 return '#<Enumerable:' + this.toArray().inspect() + '>'; 385 } 386 } 387 388 Object.extend(Enumerable, { 389 map: Enumerable.collect, 390 find: Enumerable.detect, 391 select: Enumerable.findAll, 392 member: Enumerable.include, 393 entries: Enumerable.toArray 394 }); 395 var $A = Array.from = function(iterable) { 396 if (!iterable) return []; 397 if (iterable.toArray) { 398 return iterable.toArray(); 399 } else { 400 var results = []; 401 for (var i = 0; i < iterable.length; i++) 402 results.push(iterable[i]); 403 return results; 404 } 405 } 406 407 Object.extend(Array.prototype, Enumerable); 408 409 Array.prototype._reverse = Array.prototype.reverse; 410 411 Object.extend(Array.prototype, { 412 _each: function(iterator) { 413 for (var i = 0; i < this.length; i++) 414 iterator(this[i]); 415 }, 416 417 clear: function() { 418 this.length = 0; 419 return this; 420 }, 421 422 first: function() { 423 return this[0]; 424 }, 425 426 last: function() { 427 return this[this.length - 1]; 428 }, 429 430 compact: function() { 431 return this.select(function(value) { 432 return value != undefined || value != null; 433 }); 434 }, 435 436 flatten: function() { 437 return this.inject([], function(array, value) { 438 return array.concat(value.constructor == Array ? 439 value.flatten() : [value]); 440 }); 441 }, 442 443 without: function() { 444 var values = $A(arguments); 445 return this.select(function(value) { 446 return !values.include(value); 447 }); 448 }, 449 450 indexOf: function(object) { 451 for (var i = 0; i < this.length; i++) 452 if (this[i] == object) return i; 453 return -1; 454 }, 455 456 reverse: function(inline) { 457 return (inline !== false ? this : this.toArray())._reverse(); 458 }, 459 460 shift: function() { 461 var result = this[0]; 462 for (var i = 0; i < this.length - 1; i++) 463 this[i] = this[i + 1]; 464 this.length--; 465 return result; 466 }, 467 468 inspect: function() { 469 return '[' + this.map(Object.inspect).join(', ') + ']'; 470 } 471 }); 472 var Hash = { 473 _each: function(iterator) { 474 for (key in this) { 475 var value = this[key]; 476 if (typeof value == 'function') continue; 477 478 var pair = [key, value]; 479 pair.key = key; 480 pair.value = value; 481 iterator(pair); 482 } 483 }, 484 485 keys: function() { 486 return this.pluck('key'); 487 }, 488 489 values: function() { 490 return this.pluck('value'); 491 }, 492 493 merge: function(hash) { 494 return $H(hash).inject($H(this), function(mergedHash, pair) { 495 mergedHash[pair.key] = pair.value; 496 return mergedHash; 497 }); 498 }, 499 500 toQueryString: function() { 501 return this.map(function(pair) { 502 return pair.map(encodeURIComponent).join('='); 503 }).join('&'); 504 }, 505 506 inspect: function() { 507 return '#<Hash:{' + this.map(function(pair) { 508 return pair.map(Object.inspect).join(': '); 509 }).join(', ') + '}>'; 510 } 511 } 512 513 function $H(object) { 514 var hash = Object.extend({}, object || {}); 515 Object.extend(hash, Enumerable); 516 Object.extend(hash, Hash); 517 return hash; 518 } 519 ObjectRange = Class.create(); 520 Object.extend(ObjectRange.prototype, Enumerable); 521 Object.extend(ObjectRange.prototype, { 522 initialize: function(start, end, exclusive) { 523 this.start = start; 524 this.end = end; 525 this.exclusive = exclusive; 526 }, 527 528 _each: function(iterator) { 529 var value = this.start; 530 do { 531 iterator(value); 532 value = value.succ(); 533 } while (this.include(value)); 534 }, 535 536 include: function(value) { 537 if (value < this.start) 538 return false; 539 if (this.exclusive) 540 return value < this.end; 541 return value <= this.end; 542 } 543 }); 544 545 var $R = function(start, end, exclusive) { 546 return new ObjectRange(start, end, exclusive); 547 } 168 548 169 549 var Ajax = { … … 174 554 function() {return new XMLHttpRequest()} 175 555 ) || false; 176 } 177 } 556 }, 557 558 activeRequestCount: 0 559 } 560 561 Ajax.Responders = { 562 responders: [], 563 564 _each: function(iterator) { 565 this.responders._each(iterator); 566 }, 567 568 register: function(responderToAdd) { 569 if (!this.include(responderToAdd)) 570 this.responders.push(responderToAdd); 571 }, 572 573 unregister: function(responderToRemove) { 574 this.responders = this.responders.without(responderToRemove); 575 }, 576 577 dispatch: function(callback, request, transport, json) { 578 this.each(function(responder) { 579 if (responder[callback] && typeof responder[callback] == 'function') { 580 try { 581 responder[callback].apply(responder, [request, transport, json]); 582 } catch (e) {} 583 } 584 }); 585 } 586 }; 587 588 Object.extend(Ajax.Responders, Enumerable); 589 590 Ajax.Responders.register({ 591 onCreate: function() { 592 Ajax.activeRequestCount++; 593 }, 594 595 onComplete: function() { 596 Ajax.activeRequestCount--; 597 } 598 }); 178 599 179 600 Ajax.Base = function() {}; … … 184 605 asynchronous: true, 185 606 parameters: '' 186 }.extend(options || {}); 607 } 608 Object.extend(this.options, options || {}); 187 609 }, 188 610 189 611 responseIsSuccess: function() { 190 612 return this.transport.status == undefined 191 || this.transport.status == 0 613 || this.transport.status == 0 192 614 || (this.transport.status >= 200 && this.transport.status < 300); 193 615 }, … … 199 621 200 622 Ajax.Request = Class.create(); 201 Ajax.Request.Events = 623 Ajax.Request.Events = 202 624 ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; 203 625 204 Ajax.Request.prototype = (new Ajax.Base()).extend({626 Ajax.Request.prototype = Object.extend(new Ajax.Base(), { 205 627 initialize: function(url, options) { 206 628 this.transport = Ajax.getTransport(); … … 214 636 215 637 try { 216 if (this.options.method == 'get') 217 url += '?' + parameters; 218 219 this.transport.open(this.options.method, url, 638 this.url = url; 639 if (this.options.method == 'get' && parameters.length > 0) 640 this.url += (this.url.match(/\?/) ? '&' : '?') + parameters; 641 642 Ajax.Responders.dispatch('onCreate', this, this.transport); 643 644 this.transport.open(this.options.method, this.url, 220 645 this.options.asynchronous); 221 646 … … 231 656 232 657 } catch (e) { 658 this.dispatchException(e); 233 659 } 234 660 }, 235 661 236 662 setRequestHeaders: function() { 237 var requestHeaders = 663 var requestHeaders = 238 664 ['X-Requested-With', 'XMLHttpRequest', 239 665 'X-Prototype-Version', Prototype.Version]; 240 666 241 667 if (this.options.method == 'post') { 242 requestHeaders.push('Content-type', 668 requestHeaders.push('Content-type', 243 669 'application/x-www-form-urlencoded'); 244 670 245 671 /* Force "Connection: close" for Mozilla browsers to work around 246 672 * a bug where XMLHttpReqeuest sends an incorrect Content-length 247 * header. See Mozilla Bugzilla #246651. 673 * header. See Mozilla Bugzilla #246651. 248 674 */ 249 675 if (this.transport.overrideMimeType) … … 264 690 }, 265 691 692 header: function(name) { 693 try { 694 return this.transport.getResponseHeader(name); 695 } catch (e) {} 696 }, 697 698 evalJSON: function() { 699 try { 700 return eval(this.header('X-JSON')); 701 } catch (e) {} 702 }, 703 704 evalResponse: function() { 705 try { 706 return eval(this.transport.responseText); 707 } catch (e) { 708 this.dispatchException(e); 709 } 710 }, 711 266 712 respondToReadyState: function(readyState) { 267 713 var event = Ajax.Request.Events[readyState]; 268 269 if (event == 'Complete') 270 (this.options['on' + this.transport.status] 271 || this.options['on' + this.responseIsSuccess() ? 'Success' : 'Failure'] 272 || Prototype.emptyFunction)(this.transport); 273 274 (this.options['on' + event] || Prototype.emptyFunction)(this.transport); 714 var transport = this.transport, json = this.evalJSON(); 715 716 if (event == 'Complete') { 717 try { 718 (this.options['on' + this.transport.status] 719 || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')] 720 || Prototype.emptyFunction)(transport, json); 721 } catch (e) { 722 this.dispatchException(e); 723 } 724 725 if ((this.header('Content-type') || '').match(/^text\/javascript/i)) 726 this.evalResponse(); 727 } 728 729 try { 730 (this.options['on' + event] || Prototype.emptyFunction)(transport, json); 731 Ajax.Responders.dispatch('on' + event, this, transport, json); 732 } catch (e) { 733 this.dispatchException(e); 734 } 275 735 276 736 /* Avoid memory leak in MSIE: clean up the oncomplete event handler */ 277 737 if (event == 'Complete') 278 738 this.transport.onreadystatechange = Prototype.emptyFunction; 739 }, 740 741 dispatchException: function(exception) { 742 (this.options.onException || Prototype.emptyFunction)(this, exception); 743 Ajax.Responders.dispatch('onException', this, exception); 279 744 } 280 745 }); 281 746 282 747 Ajax.Updater = Class.create(); 283 Ajax.Updater.ScriptFragment = '(?:<script.*?>)((\n|.)*?)(?:<\/script>)'; 284 285 Ajax.Updater.prototype.extend(Ajax.Request.prototype).extend({ 748 749 Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), { 286 750 initialize: function(container, url, options) { 287 751 this.containers = { … … 295 759 296 760 var onComplete = this.options.onComplete || Prototype.emptyFunction; 297 this.options.onComplete = (function( ) {761 this.options.onComplete = (function(transport, object) { 298 762 this.updateContent(); 299 onComplete(t his.transport);763 onComplete(transport, object); 300 764 }).bind(this); 301 765 … … 306 770 var receiver = this.responseIsSuccess() ? 307 771 this.containers.success : this.containers.failure; 308 309 var match = new RegExp(Ajax.Updater.ScriptFragment, 'img'); 310 var response = this.transport.responseText.replace(match, '');311 var scripts = this.transport.responseText.match(match);772 var response = this.transport.responseText; 773 774 if (!this.options.evalScripts) 775 response = response.stripScripts(); 312 776 313 777 if (receiver) { … … 315 779 new this.options.insertion(receiver, response); 316 780 } else { 317 receiver.innerHTML = response;781 Element.update(receiver, response); 318 782 } 319 783 } … … 321 785 if (this.responseIsSuccess()) { 322 786 if (this.onComplete) 323 setTimeout((function() {this.onComplete( 324 this.transport)}).bind(this), 10); 325 } 326 327 if (this.options.evalScripts && scripts) { 328 match = new RegExp(Ajax.Updater.ScriptFragment, 'im'); 329 setTimeout((function() { 330 for (var i = 0; i < scripts.length; i++) 331 eval(scripts[i].match(match)[1]); 332 }).bind(this), 10); 787 setTimeout(this.onComplete.bind(this), 10); 333 788 } 334 789 } … … 336 791 337 792 Ajax.PeriodicalUpdater = Class.create(); 338 Ajax.PeriodicalUpdater.prototype = (new Ajax.Base()).extend({793 Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), { 339 794 initialize: function(container, url, options) { 340 795 this.setOptions(options); … … 342 797 343 798 this.frequency = (this.options.frequency || 2); 344 this.decay = 1;799 this.decay = (this.options.decay || 1); 345 800 346 801 this.updater = {}; … … 359 814 this.updater.onComplete = undefined; 360 815 clearTimeout(this.timer); 361 (this.onComplete || Ajax.emptyFunction).apply(this, arguments);816 (this.onComplete || Prototype.emptyFunction).apply(this, arguments); 362 817 }, 363 818 364 819 updateComplete: function(request) { 365 820 if (this.options.decay) { 366 this.decay = (request.responseText == this.lastText ? 821 this.decay = (request.responseText == this.lastText ? 367 822 this.decay * this.options.decay : 1); 368 823 369 824 this.lastText = request.responseText; 370 825 } 371 this.timer = setTimeout(this.onTimerEvent.bind(this), 826 this.timer = setTimeout(this.onTimerEvent.bind(this), 372 827 this.decay * this.frequency * 1000); 373 828 }, … … 377 832 } 378 833 }); 379 380 document.getElementsByClassName = function(className) { 381 var children = document.getElementsByTagName('*') || document.all; 382 var elements = new Array(); 383 384 for (var i = 0; i < children.length; i++) { 385 var child = children[i]; 386 var classNames = child.className.split(' '); 387 for (var j = 0; j < classNames.length; j++) { 388 if (classNames[j] == className) { 389 elements.push(child); 390 break; 391 } 392 } 393 } 394 395 return elements; 834 document.getElementsByClassName = function(className, parentElement) { 835 var children = ($(parentElement) || document.body).getElementsByTagName('*'); 836 return $A(children).inject([], function(elements, child) { 837 if (child.className.match(new RegExp("(^|\\s)" + className + "(\\s|$)"))) 838 elements.push(child); 839 return elements; 840 }); 396 841 } 397 842 … … 403 848 404 849 Object.extend(Element, { 850 visible: function(element) { 851 return $(element).style.display != 'none'; 852 }, 853 405 854 toggle: function() { 406 855 for (var i = 0; i < arguments.length; i++) { 407 856 var element = $(arguments[i]); 408 element.style.display = 409 (element.style.display == 'none' ? '' : 'none'); 857 Element[Element.visible(element) ? 'hide' : 'show'](element); 410 858 } 411 859 }, … … 429 877 element.parentNode.removeChild(element); 430 878 }, 431 879 880 update: function(element, html) { 881 $(element).innerHTML = html.stripScripts(); 882 setTimeout(function() {html.evalScripts()}, 10); 883 }, 884 432 885 getHeight: function(element) { 433 886 element = $(element); 434 return element.offsetHeight; 887 return element.offsetHeight; 888 }, 889 890 classNames: function(element) { 891 return new Element.ClassNames(element); 435 892 }, 436 893 437 894 hasClassName: function(element, className) { 438 element = $(element); 439 if (!element) 440 return; 441 var a = element.className.split(' '); 442 for (var i = 0; i < a.length; i++) { 443 if (a[i] == className) 444 return true; 445 } 446 return false; 895 if (!(element = $(element))) return; 896 return Element.classNames(element).include(className); 447 897 }, 448 898 449 899 addClassName: function(element, className) { 450 element = $(element); 451 Element.removeClassName(element, className); 452 element.className += ' ' + className; 900 if (!(element = $(element))) return; 901 return Element.classNames(element).add(className); 453 902 }, 454 903 455 904 removeClassName: function(element, className) { 456 element = $(element); 457 if (!element) 458 return; 459 var newClassName = ''; 460 var a = element.className.split(' '); 461 for (var i = 0; i < a.length; i++) { 462 if (a[i] != className) { 463 if (i > 0) 464 newClassName += ' '; 465 newClassName += a[i]; 466 } 467 } 468 element.className = newClassName; 469 }, 470 905 if (!(element = $(element))) return; 906 return Element.classNames(element).remove(className); 907 }, 908 471 909 // removes whitespace-only text node children 472 910 cleanWhitespace: function(element) { 473 varelement = $(element);911 element = $(element); 474 912 for (var i = 0; i < element.childNodes.length; i++) { 475 913 var node = element.childNodes[i]; 476 if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) 914 if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) 477 915 Element.remove(node); 478 916 } 917 }, 918 919 empty: function(element) { 920 return $(element).innerHTML.match(/^\s*$/); 921 }, 922 923 scrollTo: function(element) { 924 element = $(element); 925 var x = element.x ? element.x : element.offsetLeft, 926 y = element.y ? element.y : element.offsetTop; 927 window.scrollTo(x, y); 928 }, 929 930 getStyle: function(element, style) { 931 element = $(element); 932 var value = element.style[style.camelize()]; 933 if (!value) { 934 if (document.defaultView && document.defaultView.getComputedStyle) { 935 var css = document.defaultView.getComputedStyle(element, null); 936 value = css ? css.getPropertyValue(style) : null; 937 } else if (element.currentStyle) { 938 value = element.currentStyle[style.camelize()]; 939 } 940 } 941 942 if (window.opera && ['left', 'top', 'right', 'bottom'].include(style)) 943 if (Element.getStyle(element, 'position') == 'static') value = 'auto'; 944 945 return value == 'auto' ? null : value; 946 }, 947 948 setStyle: function(element, style) { 949 element = $(element); 950 for (name in style) 951 element.style[name.camelize()] = style[name]; 952 }, 953 954 getDimensions: function(element) { 955 element = $(element); 956 if (Element.getStyle(element, 'display') != 'none') 957 return {width: element.offsetWidth, height: element.offsetHeight}; 958 959 // All *Width and *Height properties give 0 on elements with display none, 960 // so enable the element temporarily 961 var els = element.style; 962 var originalVisibility = els.visibility; 963 var originalPosition = els.position; 964 els.visibility = 'hidden'; 965 els.position = 'absolute'; 966 els.display = ''; 967 var originalWidth = element.clientWidth; 968 var originalHeight = element.clientHeight; 969 els.display = 'none'; 970 els.position = originalPosition; 971 els.visibility = originalVisibility; 972 return {width: originalWidth, height: originalHeight}; 973 }, 974 975
