radiant 0.6.3 → 0.6.4
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of radiant might be problematic. Click here for more details.
- data/CHANGELOG +61 -7
- data/CONTRIBUTORS +15 -0
- data/app/controllers/admin/export_controller.rb +1 -1
- data/app/controllers/admin/page_controller.rb +1 -0
- data/app/controllers/admin/user_controller.rb +2 -1
- data/app/controllers/application.rb +7 -8
- data/app/helpers/admin/node_helper.rb +84 -0
- data/app/helpers/admin/page_helper.rb +1 -19
- data/app/helpers/application_helper.rb +15 -9
- data/app/models/file_not_found_page.rb +2 -2
- data/app/models/page.rb +22 -18
- data/app/models/page_context.rb +9 -0
- data/app/models/radiant/config.rb +4 -2
- data/app/models/response_cache.rb +18 -12
- data/app/models/standard_tags.rb +111 -50
- data/app/views/admin/extension/index.rhtml +2 -2
- data/app/views/admin/layout/edit.rhtml +2 -2
- data/app/views/admin/layout/remove.rhtml +2 -2
- data/app/views/admin/page/_node.rhtml +4 -26
- data/app/views/admin/page/_part.rhtml +9 -14
- data/app/views/admin/page/edit.rhtml +38 -121
- data/app/views/admin/page/index.rhtml +2 -6
- data/app/views/admin/page/remove.rhtml +2 -2
- data/app/views/admin/snippet/edit.rhtml +3 -3
- data/app/views/admin/snippet/index.rhtml +2 -2
- data/app/views/admin/snippet/remove.rhtml +2 -2
- data/app/views/admin/user/edit.rhtml +4 -4
- data/app/views/admin/user/preferences.rhtml +2 -2
- data/app/views/admin/welcome/login.rhtml +1 -1
- data/config/environment.rb +79 -78
- data/db/schema.rb +2 -0
- data/lib/local_time.rb +12 -0
- data/lib/plugins/extension_patches/lib/fixture_loading_extension.rb +1 -1
- data/lib/plugins/extension_patches/lib/mailer_view_paths_extension.rb +3 -3
- data/lib/radiant.rb +1 -1
- data/lib/radiant/extension.rb +9 -3
- data/lib/radiant/extension_loader.rb +2 -2
- data/lib/tasks/extensions.rake +23 -8
- data/public/javascripts/admin.js +89 -0
- data/public/javascripts/controls.js +486 -354
- data/public/javascripts/dragdrop.js +90 -58
- data/public/javascripts/effects.js +398 -364
- data/public/javascripts/pngfix.js +37 -37
- data/public/javascripts/prototype.js +2764 -1095
- data/public/javascripts/ruledtable.js +10 -25
- data/public/javascripts/sitemap.js +74 -112
- data/public/javascripts/string.js +1 -7
- data/public/javascripts/tabcontrol.js +71 -86
- data/public/javascripts/tag_reference_search.js +19 -26
- data/public/stylesheets/admin/main.css +11 -5
- data/test/fixtures/extensions/01_basic/lib/new_module.rb +2 -0
- data/test/fixtures/page_parts.yml +16 -1
- data/test/fixtures/pages.yml +47 -84
- data/test/functional/extension_initialization_test.rb +11 -0
- data/test/helpers/login_test_helper.rb +12 -1
- data/test/helpers/page_test_helper.rb +6 -0
- data/test/helpers/render_test_helper.rb +11 -8
- data/test/test_helper.rb +1 -12
- data/test/unit/file_not_found_page_test.rb +5 -1
- data/test/unit/local_time_test.rb +45 -0
- data/test/unit/page_context_test.rb +32 -1
- data/test/unit/page_test.rb +45 -11
- data/test/unit/radiant/config_test.rb +1 -1
- data/test/unit/response_cache_test.rb +27 -2
- data/test/unit/standard_tags_test.rb +60 -15
- data/vendor/extensions/archive/README +29 -0
- data/vendor/extensions/archive/Rakefile +25 -0
- data/{app → vendor/extensions/archive/app}/models/archive_day_index_page.rb +0 -0
- data/{app → vendor/extensions/archive/app}/models/archive_finder.rb +8 -6
- data/{app → vendor/extensions/archive/app}/models/archive_month_index_page.rb +0 -0
- data/{app → vendor/extensions/archive/app}/models/archive_page.rb +0 -0
- data/{app → vendor/extensions/archive/app}/models/archive_year_index_page.rb +0 -0
- data/vendor/extensions/archive/archive_extension.rb +19 -0
- data/{lib → vendor/extensions/archive/lib}/archive_index_tags_and_methods.rb +0 -0
- data/vendor/extensions/archive/lib/tasks/archive_extension_tasks.rake +28 -0
- data/vendor/extensions/archive/test/fixtures/pages.yml +397 -0
- data/vendor/extensions/archive/test/functional/archive_extension_test.rb +16 -0
- data/{test → vendor/extensions/archive/test}/helpers/archive_index_test_helper.rb +0 -0
- data/vendor/extensions/archive/test/test_helper.rb +19 -0
- data/{test → vendor/extensions/archive/test}/unit/archive_day_index_page_test.rb +0 -0
- data/{test → vendor/extensions/archive/test}/unit/archive_month_index_page_test.rb +0 -0
- data/{test → vendor/extensions/archive/test}/unit/archive_page_test.rb +7 -1
- data/{test → vendor/extensions/archive/test}/unit/archive_year_index_page_test.rb +0 -0
- data/vendor/rails/actionmailer/CHANGELOG +10 -0
- data/vendor/rails/actionmailer/Rakefile +1 -1
- data/vendor/rails/actionmailer/lib/action_mailer/version.rb +1 -1
- data/vendor/rails/actionpack/CHANGELOG +51 -2
- data/vendor/rails/actionpack/Rakefile +1 -1
- data/vendor/rails/actionpack/lib/action_controller/assertions/dom_assertions.rb +2 -2
- data/vendor/rails/actionpack/lib/action_controller/assertions/model_assertions.rb +1 -1
- data/vendor/rails/actionpack/lib/action_controller/assertions/response_assertions.rb +3 -0
- data/vendor/rails/actionpack/lib/action_controller/assertions/routing_assertions.rb +1 -0
- data/vendor/rails/actionpack/lib/action_controller/assertions/selector_assertions.rb +2 -0
- data/vendor/rails/actionpack/lib/action_controller/base.rb +7 -1
- data/vendor/rails/actionpack/lib/action_controller/caching.rb +39 -38
- data/vendor/rails/actionpack/lib/action_controller/cgi_ext/pstore_performance_fix.rb +30 -0
- data/vendor/rails/actionpack/lib/action_controller/cgi_ext/raw_post_data_fix.rb +1 -1
- data/vendor/rails/actionpack/lib/action_controller/cgi_process.rb +13 -4
- data/vendor/rails/actionpack/lib/action_controller/cookies.rb +5 -3
- data/vendor/rails/actionpack/lib/action_controller/filters.rb +176 -77
- data/vendor/rails/actionpack/lib/action_controller/integration.rb +31 -21
- data/vendor/rails/actionpack/lib/action_controller/macros/in_place_editing.rb +1 -1
- data/vendor/rails/actionpack/lib/action_controller/pagination.rb +7 -1
- data/vendor/rails/actionpack/lib/action_controller/resources.rb +117 -32
- data/vendor/rails/actionpack/lib/action_controller/routing.rb +56 -23
- data/vendor/rails/actionpack/lib/action_controller/test_process.rb +5 -2
- data/vendor/rails/actionpack/lib/action_controller/url_rewriter.rb +4 -1
- data/vendor/rails/actionpack/lib/action_controller/verification.rb +1 -0
- data/vendor/rails/actionpack/lib/action_pack/version.rb +1 -1
- data/vendor/rails/actionpack/lib/action_view/base.rb +25 -19
- data/vendor/rails/actionpack/lib/action_view/compiled_templates.rb +2 -2
- data/vendor/rails/actionpack/lib/action_view/helpers/active_record_helper.rb +18 -18
- data/vendor/rails/actionpack/lib/action_view/helpers/debug_helper.rb +10 -0
- data/vendor/rails/actionpack/lib/action_view/helpers/deprecated_helper.rb +3 -0
- data/vendor/rails/actionpack/lib/action_view/helpers/prototype_helper.rb +33 -17
- data/vendor/rails/actionpack/test/activerecord/pagination_test.rb +9 -0
- data/vendor/rails/actionpack/test/controller/action_pack_assertions_test.rb +13 -0
- data/vendor/rails/actionpack/test/controller/addresses_render_test.rb +4 -1
- data/vendor/rails/actionpack/test/controller/base_test.rb +1 -1
- data/vendor/rails/actionpack/test/controller/caching_test.rb +3 -2
- data/vendor/rails/actionpack/test/controller/cookie_test.rb +11 -0
- data/vendor/rails/actionpack/test/controller/deprecation/deprecated_base_methods_test.rb +18 -0
- data/vendor/rails/actionpack/test/controller/filter_params_test.rb +1 -0
- data/vendor/rails/actionpack/test/controller/filters_test.rb +149 -26
- data/vendor/rails/actionpack/test/controller/integration_test.rb +93 -8
- data/vendor/rails/actionpack/test/controller/resources_test.rb +215 -36
- data/vendor/rails/actionpack/test/controller/routing_test.rb +2 -2
- data/vendor/rails/actionpack/test/controller/test_test.rb +16 -0
- data/vendor/rails/actionpack/test/controller/url_rewriter_test.rb +66 -10
- data/vendor/rails/actionpack/test/controller/verification_test.rb +15 -0
- data/vendor/rails/actionpack/test/fixtures/test/hello_world.rxml +2 -1
- data/vendor/rails/actionpack/test/template/asset_tag_helper_test.rb +5 -0
- data/vendor/rails/actionpack/test/template/compiled_templates_test.rb +29 -17
- data/vendor/rails/actionpack/test/template/javascript_helper_test.rb +4 -4
- data/vendor/rails/actionpack/test/template/number_helper_test.rb +1 -1
- data/vendor/rails/actionpack/test/template/prototype_helper_test.rb +13 -13
- data/vendor/rails/actionwebservice/CHANGELOG +14 -0
- data/vendor/rails/actionwebservice/Rakefile +2 -2
- data/vendor/rails/actionwebservice/lib/action_web_service/version.rb +1 -1
- data/vendor/rails/activerecord/CHANGELOG +34 -0
- data/vendor/rails/activerecord/Rakefile +1 -1
- data/vendor/rails/activerecord/lib/active_record/acts/list.rb +14 -2
- data/vendor/rails/activerecord/lib/active_record/acts/tree.rb +7 -0
- data/vendor/rails/activerecord/lib/active_record/associations.rb +29 -14
- data/vendor/rails/activerecord/lib/active_record/associations/association_collection.rb +5 -1
- data/vendor/rails/activerecord/lib/active_record/associations/has_many_association.rb +2 -2
- data/vendor/rails/activerecord/lib/active_record/associations/has_many_through_association.rb +10 -0
- data/vendor/rails/activerecord/lib/active_record/base.rb +12 -3
- data/vendor/rails/activerecord/lib/active_record/calculations.rb +2 -2
- data/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb +1 -1
- data/vendor/rails/activerecord/lib/active_record/connection_adapters/oracle_adapter.rb +1 -0
- data/vendor/rails/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb +2 -2
- data/vendor/rails/activerecord/lib/active_record/connection_adapters/sqlserver_adapter.rb +54 -38
- data/vendor/rails/activerecord/lib/active_record/deprecated_finders.rb +3 -3
- data/vendor/rails/activerecord/lib/active_record/fixtures.rb +1 -1
- data/vendor/rails/activerecord/lib/active_record/timestamp.rb +0 -9
- data/vendor/rails/activerecord/lib/active_record/version.rb +1 -1
- data/vendor/rails/activerecord/test/associations/eager_test.rb +13 -0
- data/vendor/rails/activerecord/test/associations/join_model_test.rb +10 -1
- data/vendor/rails/activerecord/test/associations_test.rb +36 -3
- data/vendor/rails/activerecord/test/base_test.rb +17 -4
- data/vendor/rails/activerecord/test/defaults_test.rb +15 -0
- data/vendor/rails/activerecord/test/fixtures/author.rb +1 -0
- data/vendor/rails/activerecord/test/fixtures/binaries.yml +437 -0
- data/vendor/rails/activerecord/test/fixtures/db_definitions/schema.rb +13 -0
- data/vendor/rails/activerecord/test/fixtures/developer.rb +10 -0
- data/vendor/rails/activerecord/test/fixtures_test.rb +9 -5
- data/vendor/rails/activerecord/test/migration_test.rb +9 -10
- data/vendor/rails/activerecord/test/mixin_test.rb +47 -0
- data/vendor/rails/activerecord/test/validations_test.rb +2 -2
- data/vendor/rails/activesupport/CHANGELOG +16 -0
- data/vendor/rails/activesupport/lib/active_support/core_ext/blank.rb +9 -3
- data/vendor/rails/activesupport/lib/active_support/core_ext/hash/conversions.rb +48 -3
- data/vendor/rails/activesupport/lib/active_support/core_ext/module/introspection.rb +14 -0
- data/vendor/rails/activesupport/lib/active_support/dependencies.rb +3 -3
- data/vendor/rails/activesupport/lib/active_support/json/encoders/core.rb +5 -3
- data/vendor/rails/activesupport/lib/active_support/multibyte/chars.rb +6 -6
- data/vendor/rails/activesupport/lib/active_support/version.rb +1 -1
- data/vendor/rails/activesupport/test/core_ext/hash_ext_test.rb +37 -0
- data/vendor/rails/activesupport/test/core_ext/module_test.rb +8 -0
- data/vendor/rails/activesupport/test/dependencies_test.rb +11 -0
- data/vendor/rails/activesupport/test/{json.rb → json_test.rb} +15 -5
- data/vendor/rails/railties/CHANGELOG +25 -1
- data/vendor/rails/railties/README +32 -3
- data/vendor/rails/railties/Rakefile +5 -5
- data/vendor/rails/railties/environments/boot.rb +12 -18
- data/vendor/rails/railties/environments/environment.rb +15 -15
- data/vendor/rails/railties/lib/dispatcher.rb +1 -2
- data/vendor/rails/railties/lib/initializer.rb +33 -9
- data/vendor/rails/railties/lib/rails/version.rb +1 -1
- data/vendor/rails/railties/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb +1 -1
- data/vendor/rails/railties/lib/rails_generator/generators/components/scaffold_resource/scaffold_resource_generator.rb +1 -0
- data/vendor/rails/railties/lib/railties_path.rb +1 -1
- data/vendor/rails/railties/lib/tasks/framework.rake +4 -4
- data/vendor/rails/railties/lib/tasks/routes.rake +17 -0
- data/vendor/rails/release.rb +2 -2
- metadata +1877 -1848
data/config/environment.rb
CHANGED
@@ -1,78 +1,79 @@
|
|
1
|
-
# Uncomment below to force Rails into production mode when
|
2
|
-
# you don't control web/app server and can't set it the proper way
|
3
|
-
# ENV['RAILS_ENV'] ||= 'production'
|
4
|
-
|
5
|
-
# Bootstrap the Rails environment, frameworks, and default configuration
|
6
|
-
require File.join(File.dirname(__FILE__), 'boot')
|
7
|
-
|
8
|
-
require 'radius'
|
9
|
-
|
10
|
-
Radiant::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 ]
|
15
|
-
|
16
|
-
# Add additional load paths for when Radiant is running in instance mode
|
17
|
-
config.load_paths += %w(
|
18
|
-
app/controllers
|
19
|
-
app/models
|
20
|
-
app/helpers
|
21
|
-
lib
|
22
|
-
).map { |path| File.join(RADIANT_ROOT, path) }
|
23
|
-
config.controller_paths << File.join(RADIANT_ROOT, 'app', 'controllers')
|
24
|
-
config.view_path = File.join(RADIANT_ROOT, 'app', 'views')
|
25
|
-
|
26
|
-
# Only load the extensions named here, in the order given. By default all plugins in vendor/extensions are
|
27
|
-
# loaded, in alphabetical order. :all can be used as a placeholder for all extensions not explicitly named.
|
28
|
-
# config.extensions = [ :textile_filter, :markdown_filter, :all ]
|
29
|
-
|
30
|
-
# Force all environments to use the same logger level
|
31
|
-
# (by default production uses :info, the others :debug)
|
32
|
-
# config.log_level = :debug
|
33
|
-
|
34
|
-
# Use the database for sessions instead of the file system
|
35
|
-
# (create the session table with 'rake create_sessions_table')
|
36
|
-
# config.action_controller.session_store = :active_record_store
|
37
|
-
|
38
|
-
# Enable page/fragment caching by setting a file-based store
|
39
|
-
# (remember to create the caching directory and make it readable to the application)
|
40
|
-
# config.action_controller.fragment_cache_store = :file_store, "#{RAILS_ROOT}/fragment_cache"
|
41
|
-
config.action_controller.page_cache_directory = "#{RAILS_ROOT}/cache"
|
42
|
-
|
43
|
-
# Make Active Record use UTC-base instead of local time
|
44
|
-
config.active_record.default_timezone = :utc
|
45
|
-
|
46
|
-
# Activate observers that should always be running
|
47
|
-
config.active_record.observers = :user_action_observer
|
48
|
-
|
49
|
-
# Make sure plugins are loaded from lib and vendor
|
50
|
-
config.plugin_paths = [
|
51
|
-
"#{RAILS_ROOT}/vendor/plugins",
|
52
|
-
"#{RADIANT_ROOT}/lib/plugins",
|
53
|
-
"#{RADIANT_ROOT}/vendor/plugins"
|
54
|
-
]
|
55
|
-
|
56
|
-
# Use ActiveRecord sessions
|
57
|
-
config.action_controller.session_store = :active_record_store
|
58
|
-
|
59
|
-
# See Rails::Configuration for more options
|
60
|
-
end
|
61
|
-
|
62
|
-
# Add new inflection rules using the following format:
|
63
|
-
Inflector.inflections do |inflect|
|
64
|
-
inflect.uncountable 'config'
|
65
|
-
inflect.uncountable 'meta'
|
66
|
-
end
|
67
|
-
|
68
|
-
# Auto-require text filters
|
69
|
-
Dir["#{RADIANT_ROOT}/app/models/*_filter.rb"].each do |filter|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
ResponseCache.defaults[:
|
76
|
-
|
77
|
-
|
78
|
-
|
1
|
+
# Uncomment below to force Rails into production mode when
|
2
|
+
# you don't control web/app server and can't set it the proper way
|
3
|
+
# ENV['RAILS_ENV'] ||= 'production'
|
4
|
+
|
5
|
+
# Bootstrap the Rails environment, frameworks, and default configuration
|
6
|
+
require File.join(File.dirname(__FILE__), 'boot')
|
7
|
+
|
8
|
+
require 'radius'
|
9
|
+
|
10
|
+
Radiant::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 ]
|
15
|
+
|
16
|
+
# Add additional load paths for when Radiant is running in instance mode
|
17
|
+
config.load_paths += %w(
|
18
|
+
app/controllers
|
19
|
+
app/models
|
20
|
+
app/helpers
|
21
|
+
lib
|
22
|
+
).map { |path| File.join(RADIANT_ROOT, path) }
|
23
|
+
config.controller_paths << File.join(RADIANT_ROOT, 'app', 'controllers')
|
24
|
+
config.view_path = File.join(RADIANT_ROOT, 'app', 'views')
|
25
|
+
|
26
|
+
# Only load the extensions named here, in the order given. By default all plugins in vendor/extensions are
|
27
|
+
# loaded, in alphabetical order. :all can be used as a placeholder for all extensions not explicitly named.
|
28
|
+
# config.extensions = [ :textile_filter, :markdown_filter, :all ]
|
29
|
+
|
30
|
+
# Force all environments to use the same logger level
|
31
|
+
# (by default production uses :info, the others :debug)
|
32
|
+
# config.log_level = :debug
|
33
|
+
|
34
|
+
# Use the database for sessions instead of the file system
|
35
|
+
# (create the session table with 'rake create_sessions_table')
|
36
|
+
# config.action_controller.session_store = :active_record_store
|
37
|
+
|
38
|
+
# Enable page/fragment caching by setting a file-based store
|
39
|
+
# (remember to create the caching directory and make it readable to the application)
|
40
|
+
# config.action_controller.fragment_cache_store = :file_store, "#{RAILS_ROOT}/fragment_cache"
|
41
|
+
config.action_controller.page_cache_directory = "#{RAILS_ROOT}/cache"
|
42
|
+
|
43
|
+
# Make Active Record use UTC-base instead of local time
|
44
|
+
config.active_record.default_timezone = :utc
|
45
|
+
|
46
|
+
# Activate observers that should always be running
|
47
|
+
config.active_record.observers = :user_action_observer
|
48
|
+
|
49
|
+
# Make sure plugins are loaded from lib and vendor
|
50
|
+
config.plugin_paths = [
|
51
|
+
"#{RAILS_ROOT}/vendor/plugins",
|
52
|
+
"#{RADIANT_ROOT}/lib/plugins",
|
53
|
+
"#{RADIANT_ROOT}/vendor/plugins"
|
54
|
+
]
|
55
|
+
|
56
|
+
# Use ActiveRecord sessions
|
57
|
+
config.action_controller.session_store = :active_record_store
|
58
|
+
|
59
|
+
# See Rails::Configuration for more options
|
60
|
+
end
|
61
|
+
|
62
|
+
# Add new inflection rules using the following format:
|
63
|
+
Inflector.inflections do |inflect|
|
64
|
+
inflect.uncountable 'config'
|
65
|
+
inflect.uncountable 'meta'
|
66
|
+
end
|
67
|
+
|
68
|
+
# Auto-require text filters
|
69
|
+
Dir["#{RADIANT_ROOT}/app/models/*_filter.rb"].each do |filter|
|
70
|
+
require_dependency File.basename(filter).sub(/\.rb$/, '')
|
71
|
+
end
|
72
|
+
|
73
|
+
# Response Caching Defaults
|
74
|
+
ResponseCache.defaults[:directory] = ActionController::Base.page_cache_directory
|
75
|
+
ResponseCache.defaults[:logger] = ActionController::Base.logger
|
76
|
+
|
77
|
+
ActionView::Base.field_error_proc = Proc.new do |html, instance|
|
78
|
+
%{<div class="error-with-field">#{html} <small class="error">• #{[instance.error_message].flatten.first}</small></div>}
|
79
|
+
end
|
data/db/schema.rb
CHANGED
@@ -50,6 +50,8 @@ ActiveRecord::Schema.define(:version => 16) do
|
|
50
50
|
t.column "updated_by", :integer
|
51
51
|
t.column "virtual", :boolean, :default => false, :null => false
|
52
52
|
t.column "lock_version", :integer, :default => 0
|
53
|
+
t.column "appears_on", :date
|
54
|
+
t.column "expires_on", :date
|
53
55
|
end
|
54
56
|
|
55
57
|
create_table "sessions", :force => true do |t|
|
data/lib/local_time.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'radiant/config'
|
2
|
+
module LocalTime
|
3
|
+
def adjust_time(time)
|
4
|
+
if (tz_string = Radiant::Config["local.timezone"]) and
|
5
|
+
timezone = (TimeZone[tz_string] || TimeZone[tz_string.to_i])
|
6
|
+
# adjust time
|
7
|
+
timezone.adjust(time)
|
8
|
+
else
|
9
|
+
time
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -17,7 +17,7 @@ module Radiant
|
|
17
17
|
begin
|
18
18
|
directory = paths.pop
|
19
19
|
fixtures_map[table_name] = Fixtures.new(connection, File.split(table_name.to_s).last, class_names[table_name.to_sym], File.join(directory, table_name))
|
20
|
-
rescue
|
20
|
+
rescue SystemCallError => e
|
21
21
|
retry unless paths.empty?
|
22
22
|
raise e
|
23
23
|
end
|
@@ -43,7 +43,7 @@ module Radiant
|
|
43
43
|
next unless md = /^([^\.]+)\.([^\.]+\.[^\+]+)\.(rhtml|rxml)$/.match(basename)
|
44
44
|
template_name = basename
|
45
45
|
content_type = md.captures[1].gsub('.', '/')
|
46
|
-
@parts << Part.new(:content_type => content_type,
|
46
|
+
@parts << ActionMailer::Part.new(:content_type => content_type,
|
47
47
|
:disposition => "inline", :charset => charset,
|
48
48
|
:body => render_message(template_name, @body))
|
49
49
|
end
|
@@ -65,7 +65,7 @@ module Radiant
|
|
65
65
|
# we shift it onto the front of the parts and set the body to nil (so
|
66
66
|
# that create_mail doesn't try to render it in addition to the parts).
|
67
67
|
if !@parts.empty? && String === @body
|
68
|
-
@parts.unshift Part.new(:charset => charset, :body => @body)
|
68
|
+
@parts.unshift ActionMailer::Part.new(:charset => charset, :body => @body)
|
69
69
|
@body = nil
|
70
70
|
end
|
71
71
|
end
|
@@ -85,4 +85,4 @@ module Radiant
|
|
85
85
|
end
|
86
86
|
end
|
87
87
|
|
88
|
-
ActionMailer::Base.send(:include, Radiant::MailerViewPathsExtension)
|
88
|
+
ActionMailer::Base.send(:include, Radiant::MailerViewPathsExtension)
|
data/lib/radiant.rb
CHANGED
data/lib/radiant/extension.rb
CHANGED
@@ -80,12 +80,18 @@ module Radiant
|
|
80
80
|
begin
|
81
81
|
Radiant::Extension.const_get(const_name)
|
82
82
|
rescue
|
83
|
-
|
84
|
-
|
83
|
+
lib = "#{plugin}/lib"
|
84
|
+
init ="#{plugin}/init.rb"
|
85
|
+
if File.directory?(lib)
|
86
|
+
$LOAD_PATH << lib
|
87
|
+
Dependencies.load_paths << lib
|
88
|
+
Dependencies.load_once_paths << lib
|
89
|
+
end
|
90
|
+
require init if File.exists?(init)
|
85
91
|
Radiant::Extension.const_set const_name, plugin
|
86
92
|
end
|
87
93
|
end
|
88
94
|
end
|
89
95
|
end
|
90
96
|
end
|
91
|
-
end
|
97
|
+
end
|
@@ -78,7 +78,7 @@ module Radiant
|
|
78
78
|
extension_roots.each do |ext_path|
|
79
79
|
load_paths = %w(lib app/models app/controllers app/helpers test/helpers).collect { |p| "#{ext_path}/#{p}" }
|
80
80
|
load_paths << ext_path
|
81
|
-
load_paths.each { |p| configuration.load_paths << p }
|
81
|
+
load_paths.each { |p| configuration.load_paths << p; $LOAD_PATH << p; }
|
82
82
|
configuration.controller_paths << "#{ext_path}/app/controllers"
|
83
83
|
configuration.view_paths << "#{ext_path}/app/views"
|
84
84
|
@extension_roots << ext_path
|
@@ -133,4 +133,4 @@ module Radiant
|
|
133
133
|
end
|
134
134
|
|
135
135
|
end
|
136
|
-
end
|
136
|
+
end
|
data/lib/tasks/extensions.rake
CHANGED
@@ -22,14 +22,29 @@ namespace :db do
|
|
22
22
|
end
|
23
23
|
|
24
24
|
namespace :test do
|
25
|
-
desc "Runs tests on all available Radiant extensions"
|
25
|
+
desc "Runs tests on all available Radiant extensions, pass EXT=extension_name to test a single extension"
|
26
26
|
task :extensions => "db:test:prepare" do
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
27
|
+
if ENV["EXT"]
|
28
|
+
extension = RAILS_ROOT + "/vendor/extensions/" + ENV["EXT"]
|
29
|
+
if File.directory?(extension)
|
30
|
+
chdir extension do
|
31
|
+
if RUBY_PLATFORM =~ /win32/
|
32
|
+
system "rake.cmd test"
|
33
|
+
else
|
34
|
+
system "rake test"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
else
|
38
|
+
puts "Sorry, that extension is not installed."
|
39
|
+
end
|
40
|
+
else
|
41
|
+
Dir["#{RAILS_ROOT}/vendor/extensions/*"].sort.select { |f| File.directory?(f) }.each do |directory|
|
42
|
+
chdir directory do
|
43
|
+
if RUBY_PLATFORM =~ /win32/
|
44
|
+
system "rake.cmd test"
|
45
|
+
else
|
46
|
+
system "rake test"
|
47
|
+
end
|
33
48
|
end
|
34
49
|
end
|
35
50
|
end
|
@@ -39,4 +54,4 @@ end
|
|
39
54
|
# Load any custom rakefiles from extensions
|
40
55
|
[RAILS_ROOT, RADIANT_ROOT].uniq.each do |root|
|
41
56
|
Dir[root + '/vendor/extensions/**/tasks/**/*.rake'].sort.each { |ext| load ext }
|
42
|
-
end
|
57
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
document.observe('dom:loaded', function() {
|
2
|
+
when('site-map', function(table) { new SiteMap(table) });
|
3
|
+
|
4
|
+
when('page_title', function(title) {
|
5
|
+
var slug = $('page_slug'),
|
6
|
+
breadcrumb = $('page_breadcrumb'),
|
7
|
+
oldTitle = title.value;
|
8
|
+
|
9
|
+
if (!slug || !breadcrumb) return;
|
10
|
+
|
11
|
+
new Form.Element.Observer(title, 0.15, function() {
|
12
|
+
if (oldTitle.toSlug() == slug.value) slug.value = title.value.toSlug();
|
13
|
+
if (oldTitle == breadcrumb.value) breadcrumb.value = title.value;
|
14
|
+
oldTitle = title.value;
|
15
|
+
});
|
16
|
+
});
|
17
|
+
|
18
|
+
when($$('#pages div.part > input[type=hidden]:first-child'), function(parts) {
|
19
|
+
tabControl = new TabControl('tab-control');
|
20
|
+
|
21
|
+
parts.each(function(part, index) {
|
22
|
+
var page = part.up('.page');
|
23
|
+
tabControl.addTab('tab-' + (index + 1), part.value, page.id);
|
24
|
+
});
|
25
|
+
|
26
|
+
tabControl.autoSelect();
|
27
|
+
});
|
28
|
+
});
|
29
|
+
|
30
|
+
// When object is available, do function fn.
|
31
|
+
function when(obj, fn) {
|
32
|
+
if (Object.isString(obj)) obj = /^[\w-]+$/.test(obj) ? $(obj) : $(document.body).down(obj);
|
33
|
+
if (Object.isArray(obj) && !obj.length) return;
|
34
|
+
if (obj) fn(obj);
|
35
|
+
}
|
36
|
+
|
37
|
+
function part_added() {
|
38
|
+
var partNameField = $('part-name-field');
|
39
|
+
var partIndexField = $('part-index-field');
|
40
|
+
var index = parseInt(partIndexField.value) + 1;
|
41
|
+
var tab = 'tab-' + index;
|
42
|
+
var caption = partNameField.value;
|
43
|
+
var page = 'page-' + index;
|
44
|
+
tabControl.addTab(tab, caption, page);
|
45
|
+
Element.hide('add-part-popup');
|
46
|
+
Element.hide('busy');
|
47
|
+
partNameField.value = '';
|
48
|
+
partIndexField.value = (index + 1).toString();
|
49
|
+
$('add-part-button').disabled = false;
|
50
|
+
Field.focus(partNameField);
|
51
|
+
tabControl.select(tab);
|
52
|
+
}
|
53
|
+
function part_loading() {
|
54
|
+
$('add-part-button').disabled = true;
|
55
|
+
$('busy').appear();
|
56
|
+
}
|
57
|
+
function valid_part_name() {
|
58
|
+
var partNameField = $('part-name-field');
|
59
|
+
var name = partNameField.value.downcase().strip();
|
60
|
+
var result = true;
|
61
|
+
if (name == '') {
|
62
|
+
alert('Part name cannot be empty.');
|
63
|
+
return false;
|
64
|
+
}
|
65
|
+
tabControl.tabs.each(function(pair){
|
66
|
+
if (tabControl.tabs.get(pair.key).caption == name) {
|
67
|
+
result = false;
|
68
|
+
alert('Part name must be unique.');
|
69
|
+
throw $break;
|
70
|
+
}
|
71
|
+
})
|
72
|
+
return result;
|
73
|
+
}
|
74
|
+
function center(element) {
|
75
|
+
var header = $('header')
|
76
|
+
element = $(element);
|
77
|
+
element.style.position = 'absolute';
|
78
|
+
var dim = Element.getDimensions(element);
|
79
|
+
var top = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop;
|
80
|
+
element.style.top = (top + 200) + 'px';
|
81
|
+
element.style.left = ((header.offsetWidth - dim.width) / 2) + 'px';
|
82
|
+
}
|
83
|
+
function toggle_add_part_popup() {
|
84
|
+
var popup = $('add-part-popup');
|
85
|
+
var partNameField = $('part-name-field');
|
86
|
+
center(popup);
|
87
|
+
Element.toggle(popup);
|
88
|
+
Field.focus(partNameField);
|
89
|
+
}
|
@@ -1,6 +1,8 @@
|
|
1
|
-
//
|
2
|
-
|
3
|
-
//
|
1
|
+
// script.aculo.us controls.js v1.8.0, Tue Nov 06 15:01:40 +0300 2007
|
2
|
+
|
3
|
+
// Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
|
4
|
+
// (c) 2005-2007 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
|
5
|
+
// (c) 2005-2007 Jon Tirsen (http://www.tirsen.com)
|
4
6
|
// Contributors:
|
5
7
|
// Richard Livsey
|
6
8
|
// Rahul Bhargava
|
@@ -37,22 +39,23 @@
|
|
37
39
|
if(typeof Effect == 'undefined')
|
38
40
|
throw("controls.js requires including script.aculo.us' effects.js library");
|
39
41
|
|
40
|
-
var Autocompleter = {}
|
41
|
-
Autocompleter.Base =
|
42
|
-
Autocompleter.Base.prototype = {
|
42
|
+
var Autocompleter = { }
|
43
|
+
Autocompleter.Base = Class.create({
|
43
44
|
baseInitialize: function(element, update, options) {
|
44
|
-
|
45
|
+
element = $(element)
|
46
|
+
this.element = element;
|
45
47
|
this.update = $(update);
|
46
48
|
this.hasFocus = false;
|
47
49
|
this.changed = false;
|
48
50
|
this.active = false;
|
49
51
|
this.index = 0;
|
50
52
|
this.entryCount = 0;
|
53
|
+
this.oldElementValue = this.element.value;
|
51
54
|
|
52
55
|
if(this.setOptions)
|
53
56
|
this.setOptions(options);
|
54
57
|
else
|
55
|
-
this.options = options || {};
|
58
|
+
this.options = options || { };
|
56
59
|
|
57
60
|
this.options.paramName = this.options.paramName || this.element.name;
|
58
61
|
this.options.tokens = this.options.tokens || [];
|
@@ -74,6 +77,9 @@ Autocompleter.Base.prototype = {
|
|
74
77
|
|
75
78
|
if(typeof(this.options.tokens) == 'string')
|
76
79
|
this.options.tokens = new Array(this.options.tokens);
|
80
|
+
// Force carriage returns as token delimiters anyway
|
81
|
+
if (!this.options.tokens.include('\n'))
|
82
|
+
this.options.tokens.push('\n');
|
77
83
|
|
78
84
|
this.observer = null;
|
79
85
|
|
@@ -81,15 +87,14 @@ Autocompleter.Base.prototype = {
|
|
81
87
|
|
82
88
|
Element.hide(this.update);
|
83
89
|
|
84
|
-
Event.observe(this.element,
|
85
|
-
Event.observe(this.element,
|
90
|
+
Event.observe(this.element, 'blur', this.onBlur.bindAsEventListener(this));
|
91
|
+
Event.observe(this.element, 'keypress', this.onKeyPress.bindAsEventListener(this));
|
86
92
|
},
|
87
93
|
|
88
94
|
show: function() {
|
89
95
|
if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update);
|
90
96
|
if(!this.iefix &&
|
91
|
-
(
|
92
|
-
(navigator.userAgent.indexOf('Opera')<0) &&
|
97
|
+
(Prototype.Browser.IE) &&
|
93
98
|
(Element.getStyle(this.update, 'position')=='absolute')) {
|
94
99
|
new Insertion.After(this.update,
|
95
100
|
'<iframe id="' + this.update.id + '_iefix" '+
|
@@ -139,17 +144,17 @@ Autocompleter.Base.prototype = {
|
|
139
144
|
case Event.KEY_UP:
|
140
145
|
this.markPrevious();
|
141
146
|
this.render();
|
142
|
-
if(
|
147
|
+
if(Prototype.Browser.WebKit) Event.stop(event);
|
143
148
|
return;
|
144
149
|
case Event.KEY_DOWN:
|
145
150
|
this.markNext();
|
146
151
|
this.render();
|
147
|
-
if(
|
152
|
+
if(Prototype.Browser.WebKit) Event.stop(event);
|
148
153
|
return;
|
149
154
|
}
|
150
155
|
else
|
151
156
|
if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN ||
|
152
|
-
(
|
157
|
+
(Prototype.Browser.WebKit > 0 && event.keyCode == 0)) return;
|
153
158
|
|
154
159
|
this.changed = true;
|
155
160
|
this.hasFocus = true;
|
@@ -195,7 +200,6 @@ Autocompleter.Base.prototype = {
|
|
195
200
|
this.index==i ?
|
196
201
|
Element.addClassName(this.getEntry(i),"selected") :
|
197
202
|
Element.removeClassName(this.getEntry(i),"selected");
|
198
|
-
|
199
203
|
if(this.hasFocus) {
|
200
204
|
this.show();
|
201
205
|
this.active = true;
|
@@ -238,21 +242,22 @@ Autocompleter.Base.prototype = {
|
|
238
242
|
}
|
239
243
|
var value = '';
|
240
244
|
if (this.options.select) {
|
241
|
-
var nodes =
|
245
|
+
var nodes = $(selectedElement).select('.' + this.options.select) || [];
|
242
246
|
if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select);
|
243
247
|
} else
|
244
248
|
value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal');
|
245
249
|
|
246
|
-
var
|
247
|
-
if (
|
248
|
-
var newValue = this.element.value.substr(0,
|
249
|
-
var whitespace = this.element.value.substr(
|
250
|
+
var bounds = this.getTokenBounds();
|
251
|
+
if (bounds[0] != -1) {
|
252
|
+
var newValue = this.element.value.substr(0, bounds[0]);
|
253
|
+
var whitespace = this.element.value.substr(bounds[0]).match(/^\s+/);
|
250
254
|
if (whitespace)
|
251
255
|
newValue += whitespace[0];
|
252
|
-
this.element.value = newValue + value;
|
256
|
+
this.element.value = newValue + value + this.element.value.substr(bounds[1]);
|
253
257
|
} else {
|
254
258
|
this.element.value = value;
|
255
259
|
}
|
260
|
+
this.oldElementValue = this.element.value;
|
256
261
|
this.element.focus();
|
257
262
|
|
258
263
|
if (this.options.afterUpdateElement)
|
@@ -296,39 +301,48 @@ Autocompleter.Base.prototype = {
|
|
296
301
|
|
297
302
|
onObserverEvent: function() {
|
298
303
|
this.changed = false;
|
304
|
+
this.tokenBounds = null;
|
299
305
|
if(this.getToken().length>=this.options.minChars) {
|
300
|
-
this.startIndicator();
|
301
306
|
this.getUpdatedChoices();
|
302
307
|
} else {
|
303
308
|
this.active = false;
|
304
309
|
this.hide();
|
305
310
|
}
|
311
|
+
this.oldElementValue = this.element.value;
|
306
312
|
},
|
307
313
|
|
308
314
|
getToken: function() {
|
309
|
-
var
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
var
|
320
|
-
|
321
|
-
for (var
|
322
|
-
|
323
|
-
if (
|
324
|
-
|
315
|
+
var bounds = this.getTokenBounds();
|
316
|
+
return this.element.value.substring(bounds[0], bounds[1]).strip();
|
317
|
+
},
|
318
|
+
|
319
|
+
getTokenBounds: function() {
|
320
|
+
if (null != this.tokenBounds) return this.tokenBounds;
|
321
|
+
var value = this.element.value;
|
322
|
+
if (value.strip().empty()) return [-1, 0];
|
323
|
+
var diff = arguments.callee.getFirstDifferencePos(value, this.oldElementValue);
|
324
|
+
var offset = (diff == this.oldElementValue.length ? 1 : 0);
|
325
|
+
var prevTokenPos = -1, nextTokenPos = value.length;
|
326
|
+
var tp;
|
327
|
+
for (var index = 0, l = this.options.tokens.length; index < l; ++index) {
|
328
|
+
tp = value.lastIndexOf(this.options.tokens[index], diff + offset - 1);
|
329
|
+
if (tp > prevTokenPos) prevTokenPos = tp;
|
330
|
+
tp = value.indexOf(this.options.tokens[index], diff + offset);
|
331
|
+
if (-1 != tp && tp < nextTokenPos) nextTokenPos = tp;
|
325
332
|
}
|
326
|
-
return
|
333
|
+
return (this.tokenBounds = [prevTokenPos + 1, nextTokenPos]);
|
327
334
|
}
|
328
|
-
}
|
335
|
+
});
|
336
|
+
|
337
|
+
Autocompleter.Base.prototype.getTokenBounds.getFirstDifferencePos = function(newS, oldS) {
|
338
|
+
var boundary = Math.min(newS.length, oldS.length);
|
339
|
+
for (var index = 0; index < boundary; ++index)
|
340
|
+
if (newS[index] != oldS[index])
|
341
|
+
return index;
|
342
|
+
return boundary;
|
343
|
+
};
|
329
344
|
|
330
|
-
Ajax.Autocompleter = Class.create(
|
331
|
-
Object.extend(Object.extend(Ajax.Autocompleter.prototype, Autocompleter.Base.prototype), {
|
345
|
+
Ajax.Autocompleter = Class.create(Autocompleter.Base, {
|
332
346
|
initialize: function(element, update, url, options) {
|
333
347
|
this.baseInitialize(element, update, options);
|
334
348
|
this.options.asynchronous = true;
|
@@ -338,7 +352,9 @@ Object.extend(Object.extend(Ajax.Autocompleter.prototype, Autocompleter.Base.pro
|
|
338
352
|
},
|
339
353
|
|
340
354
|
getUpdatedChoices: function() {
|
341
|
-
|
355
|
+
this.startIndicator();
|
356
|
+
|
357
|
+
var entry = encodeURIComponent(this.options.paramName) + '=' +
|
342
358
|
encodeURIComponent(this.getToken());
|
343
359
|
|
344
360
|
this.options.parameters = this.options.callback ?
|
@@ -346,14 +362,13 @@ Object.extend(Object.extend(Ajax.Autocompleter.prototype, Autocompleter.Base.pro
|
|
346
362
|
|
347
363
|
if(this.options.defaultParams)
|
348
364
|
this.options.parameters += '&' + this.options.defaultParams;
|
349
|
-
|
365
|
+
|
350
366
|
new Ajax.Request(this.url, this.options);
|
351
367
|
},
|
352
368
|
|
353
369
|
onComplete: function(request) {
|
354
370
|
this.updateChoices(request.responseText);
|
355
371
|
}
|
356
|
-
|
357
372
|
});
|
358
373
|
|
359
374
|
// The local array autocompleter. Used when you'd prefer to
|
@@ -391,8 +406,7 @@ Object.extend(Object.extend(Ajax.Autocompleter.prototype, Autocompleter.Base.pro
|
|
391
406
|
// In that case, the other options above will not apply unless
|
392
407
|
// you support them.
|
393
408
|
|
394
|
-
Autocompleter.Local = Class.create(
|
395
|
-
Autocompleter.Local.prototype = Object.extend(new Autocompleter.Base(), {
|
409
|
+
Autocompleter.Local = Class.create(Autocompleter.Base, {
|
396
410
|
initialize: function(element, update, array, options) {
|
397
411
|
this.baseInitialize(element, update, options);
|
398
412
|
this.options.array = array;
|
@@ -448,13 +462,12 @@ Autocompleter.Local.prototype = Object.extend(new Autocompleter.Base(), {
|
|
448
462
|
ret = ret.concat(partial.slice(0, instance.options.choices - ret.length))
|
449
463
|
return "<ul>" + ret.join('') + "</ul>";
|
450
464
|
}
|
451
|
-
}, options || {});
|
465
|
+
}, options || { });
|
452
466
|
}
|
453
467
|
});
|
454
468
|
|
455
|
-
// AJAX in-place editor
|
456
|
-
//
|
457
|
-
// see documentation on http://wiki.script.aculo.us/scriptaculous/show/Ajax.InPlaceEditor
|
469
|
+
// AJAX in-place editor and collection editor
|
470
|
+
// Full rewrite by Christophe Porteneuve <tdd@tddsworld.com> (April 2007).
|
458
471
|
|
459
472
|
// Use this if you notice weird scrolling problems on some browsers,
|
460
473
|
// the DOM might be a bit confused when this gets called so do this
|
@@ -465,353 +478,472 @@ Field.scrollFreeActivate = function(field) {
|
|
465
478
|
}, 1);
|
466
479
|
}
|
467
480
|
|
468
|
-
Ajax.InPlaceEditor = Class.create(
|
469
|
-
Ajax.InPlaceEditor.defaultHighlightColor = "#FFFF99";
|
470
|
-
Ajax.InPlaceEditor.prototype = {
|
481
|
+
Ajax.InPlaceEditor = Class.create({
|
471
482
|
initialize: function(element, url, options) {
|
472
483
|
this.url = url;
|
473
|
-
this.element = $(element);
|
474
|
-
|
475
|
-
this.
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
clickToEditText: "Click to edit",
|
483
|
-
okText: "ok",
|
484
|
-
rows: 1,
|
485
|
-
onComplete: function(transport, element) {
|
486
|
-
new Effect.Highlight(element, {startcolor: this.options.highlightcolor});
|
487
|
-
},
|
488
|
-
onFailure: function(transport) {
|
489
|
-
alert("Error communicating with the server: " + transport.responseText.stripTags());
|
490
|
-
},
|
491
|
-
callback: function(form) {
|
492
|
-
return Form.serialize(form);
|
493
|
-
},
|
494
|
-
handleLineBreaks: true,
|
495
|
-
loadingText: 'Loading...',
|
496
|
-
savingClassName: 'inplaceeditor-saving',
|
497
|
-
loadingClassName: 'inplaceeditor-loading',
|
498
|
-
formClassName: 'inplaceeditor-form',
|
499
|
-
highlightcolor: Ajax.InPlaceEditor.defaultHighlightColor,
|
500
|
-
highlightendcolor: "#FFFFFF",
|
501
|
-
externalControl: null,
|
502
|
-
submitOnBlur: false,
|
503
|
-
ajaxOptions: {},
|
504
|
-
evalScripts: false
|
505
|
-
}, options || {});
|
506
|
-
|
507
|
-
if(!this.options.formId && this.element.id) {
|
508
|
-
this.options.formId = this.element.id + "-inplaceeditor";
|
509
|
-
if ($(this.options.formId)) {
|
510
|
-
// there's already a form with that name, don't specify an id
|
511
|
-
this.options.formId = null;
|
512
|
-
}
|
484
|
+
this.element = element = $(element);
|
485
|
+
this.prepareOptions();
|
486
|
+
this._controls = { };
|
487
|
+
arguments.callee.dealWithDeprecatedOptions(options); // DEPRECATION LAYER!!!
|
488
|
+
Object.extend(this.options, options || { });
|
489
|
+
if (!this.options.formId && this.element.id) {
|
490
|
+
this.options.formId = this.element.id + '-inplaceeditor';
|
491
|
+
if ($(this.options.formId))
|
492
|
+
this.options.formId = '';
|
513
493
|
}
|
514
|
-
|
515
|
-
if (this.options.externalControl) {
|
494
|
+
if (this.options.externalControl)
|
516
495
|
this.options.externalControl = $(this.options.externalControl);
|
517
|
-
|
518
|
-
|
519
|
-
this.
|
520
|
-
if (!this.originalBackground) {
|
521
|
-
this.originalBackground = "transparent";
|
522
|
-
}
|
523
|
-
|
496
|
+
if (!this.options.externalControl)
|
497
|
+
this.options.externalControlOnly = false;
|
498
|
+
this._originalBackground = this.element.getStyle('background-color') || 'transparent';
|
524
499
|
this.element.title = this.options.clickToEditText;
|
525
|
-
|
526
|
-
this.
|
527
|
-
this.
|
528
|
-
this.
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
this.
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
|
551
|
-
if (
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
this.createEditField();
|
563
|
-
|
564
|
-
if (this.options.textarea) {
|
565
|
-
var br = document.createElement("br");
|
566
|
-
this.form.appendChild(br);
|
567
|
-
}
|
568
|
-
|
569
|
-
if (this.options.okButton) {
|
570
|
-
okButton = document.createElement("input");
|
571
|
-
okButton.type = "submit";
|
572
|
-
okButton.value = this.options.okText;
|
573
|
-
okButton.className = 'editor_ok_button';
|
574
|
-
this.form.appendChild(okButton);
|
575
|
-
}
|
576
|
-
|
577
|
-
if (this.options.cancelLink) {
|
578
|
-
cancelLink = document.createElement("a");
|
579
|
-
cancelLink.href = "#";
|
580
|
-
cancelLink.appendChild(document.createTextNode(this.options.cancelText));
|
581
|
-
cancelLink.onclick = this.onclickCancel.bind(this);
|
582
|
-
cancelLink.className = 'editor_cancel';
|
583
|
-
this.form.appendChild(cancelLink);
|
500
|
+
this._boundCancelHandler = this.handleFormCancellation.bind(this);
|
501
|
+
this._boundComplete = (this.options.onComplete || Prototype.emptyFunction).bind(this);
|
502
|
+
this._boundFailureHandler = this.handleAJAXFailure.bind(this);
|
503
|
+
this._boundSubmitHandler = this.handleFormSubmission.bind(this);
|
504
|
+
this._boundWrapperHandler = this.wrapUp.bind(this);
|
505
|
+
this.registerListeners();
|
506
|
+
},
|
507
|
+
checkForEscapeOrReturn: function(e) {
|
508
|
+
if (!this._editing || e.ctrlKey || e.altKey || e.shiftKey) return;
|
509
|
+
if (Event.KEY_ESC == e.keyCode)
|
510
|
+
this.handleFormCancellation(e);
|
511
|
+
else if (Event.KEY_RETURN == e.keyCode)
|
512
|
+
this.handleFormSubmission(e);
|
513
|
+
},
|
514
|
+
createControl: function(mode, handler, extraClasses) {
|
515
|
+
var control = this.options[mode + 'Control'];
|
516
|
+
var text = this.options[mode + 'Text'];
|
517
|
+
if ('button' == control) {
|
518
|
+
var btn = document.createElement('input');
|
519
|
+
btn.type = 'submit';
|
520
|
+
btn.value = text;
|
521
|
+
btn.className = 'editor_' + mode + '_button';
|
522
|
+
if ('cancel' == mode)
|
523
|
+
btn.onclick = this._boundCancelHandler;
|
524
|
+
this._form.appendChild(btn);
|
525
|
+
this._controls[mode] = btn;
|
526
|
+
} else if ('link' == control) {
|
527
|
+
var link = document.createElement('a');
|
528
|
+
link.href = '#';
|
529
|
+
link.appendChild(document.createTextNode(text));
|
530
|
+
link.onclick = 'cancel' == mode ? this._boundCancelHandler : this._boundSubmitHandler;
|
531
|
+
link.className = 'editor_' + mode + '_link';
|
532
|
+
if (extraClasses)
|
533
|
+
link.className += ' ' + extraClasses;
|
534
|
+
this._form.appendChild(link);
|
535
|
+
this._controls[mode] = link;
|
584
536
|
}
|
585
537
|
},
|
586
|
-
hasHTMLLineBreaks: function(string) {
|
587
|
-
if (!this.options.handleLineBreaks) return false;
|
588
|
-
return string.match(/<br/i) || string.match(/<p>/i);
|
589
|
-
},
|
590
|
-
convertHTMLLineBreaks: function(string) {
|
591
|
-
return string.replace(/<br>/gi, "\n").replace(/<br\/>/gi, "\n").replace(/<\/p>/gi, "\n").replace(/<p>/gi, "");
|
592
|
-
},
|
593
538
|
createEditField: function() {
|
594
|
-
var text;
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
}
|
600
|
-
|
601
|
-
var obj = this;
|
602
|
-
|
603
|
-
if (this.options.rows == 1 && !this.hasHTMLLineBreaks(text)) {
|
604
|
-
this.options.textarea = false;
|
605
|
-
var textField = document.createElement("input");
|
606
|
-
textField.obj = this;
|
607
|
-
textField.type = "text";
|
608
|
-
textField.name = this.options.paramName;
|
609
|
-
textField.value = text;
|
610
|
-
textField.style.backgroundColor = this.options.highlightcolor;
|
611
|
-
textField.className = 'editor_field';
|
539
|
+
var text = (this.options.loadTextURL ? this.options.loadingText : this.getText());
|
540
|
+
var fld;
|
541
|
+
if (1 >= this.options.rows && !/\r|\n/.test(this.getText())) {
|
542
|
+
fld = document.createElement('input');
|
543
|
+
fld.type = 'text';
|
612
544
|
var size = this.options.size || this.options.cols || 0;
|
613
|
-
if (
|
614
|
-
if (this.options.submitOnBlur)
|
615
|
-
textField.onblur = this.onSubmit.bind(this);
|
616
|
-
this.editField = textField;
|
545
|
+
if (0 < size) fld.size = size;
|
617
546
|
} else {
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
textArea.name = this.options.paramName;
|
622
|
-
textArea.value = this.convertHTMLLineBreaks(text);
|
623
|
-
textArea.rows = this.options.rows;
|
624
|
-
textArea.cols = this.options.cols || 40;
|
625
|
-
textArea.className = 'editor_field';
|
626
|
-
if (this.options.submitOnBlur)
|
627
|
-
textArea.onblur = this.onSubmit.bind(this);
|
628
|
-
this.editField = textArea;
|
547
|
+
fld = document.createElement('textarea');
|
548
|
+
fld.rows = (1 >= this.options.rows ? this.options.autoRows : this.options.rows);
|
549
|
+
fld.cols = this.options.cols || 40;
|
629
550
|
}
|
630
|
-
|
631
|
-
|
551
|
+
fld.name = this.options.paramName;
|
552
|
+
fld.value = text; // No HTML breaks conversion anymore
|
553
|
+
fld.className = 'editor_field';
|
554
|
+
if (this.options.submitOnBlur)
|
555
|
+
fld.onblur = this._boundSubmitHandler;
|
556
|
+
this._controls.editor = fld;
|
557
|
+
if (this.options.loadTextURL)
|
632
558
|
this.loadExternalText();
|
633
|
-
|
634
|
-
|
559
|
+
this._form.appendChild(this._controls.editor);
|
560
|
+
},
|
561
|
+
createForm: function() {
|
562
|
+
var ipe = this;
|
563
|
+
function addText(mode, condition) {
|
564
|
+
var text = ipe.options['text' + mode + 'Controls'];
|
565
|
+
if (!text || condition === false) return;
|
566
|
+
ipe._form.appendChild(document.createTextNode(text));
|
567
|
+
};
|
568
|
+
this._form = $(document.createElement('form'));
|
569
|
+
this._form.id = this.options.formId;
|
570
|
+
this._form.addClassName(this.options.formClassName);
|
571
|
+
this._form.onsubmit = this._boundSubmitHandler;
|
572
|
+
this.createEditField();
|
573
|
+
if ('textarea' == this._controls.editor.tagName.toLowerCase())
|
574
|
+
this._form.appendChild(document.createElement('br'));
|
575
|
+
if (this.options.onFormCustomization)
|
576
|
+
this.options.onFormCustomization(this, this._form);
|
577
|
+
addText('Before', this.options.okControl || this.options.cancelControl);
|
578
|
+
this.createControl('ok', this._boundSubmitHandler);
|
579
|
+
addText('Between', this.options.okControl && this.options.cancelControl);
|
580
|
+
this.createControl('cancel', this._boundCancelHandler, 'editor_cancel');
|
581
|
+
addText('After', this.options.okControl || this.options.cancelControl);
|
582
|
+
},
|
583
|
+
destroy: function() {
|
584
|
+
if (this._oldInnerHTML)
|
585
|
+
this.element.innerHTML = this._oldInnerHTML;
|
586
|
+
this.leaveEditMode();
|
587
|
+
this.unregisterListeners();
|
588
|
+
},
|
589
|
+
enterEditMode: function(e) {
|
590
|
+
if (this._saving || this._editing) return;
|
591
|
+
this._editing = true;
|
592
|
+
this.triggerCallback('onEnterEditMode');
|
593
|
+
if (this.options.externalControl)
|
594
|
+
this.options.externalControl.hide();
|
595
|
+
this.element.hide();
|
596
|
+
this.createForm();
|
597
|
+
this.element.parentNode.insertBefore(this._form, this.element);
|
598
|
+
if (!this.options.loadTextURL)
|
599
|
+
this.postProcessEditField();
|
600
|
+
if (e) Event.stop(e);
|
601
|
+
},
|
602
|
+
enterHover: function(e) {
|
603
|
+
if (this.options.hoverClassName)
|
604
|
+
this.element.addClassName(this.options.hoverClassName);
|
605
|
+
if (this._saving) return;
|
606
|
+
this.triggerCallback('onEnterHover');
|
635
607
|
},
|
636
608
|
getText: function() {
|
637
609
|
return this.element.innerHTML;
|
638
610
|
},
|
639
|
-
|
640
|
-
|
641
|
-
this.
|
642
|
-
|
643
|
-
this.
|
644
|
-
Object.extend({
|
645
|
-
asynchronous: true,
|
646
|
-
onComplete: this.onLoadedExternalText.bind(this)
|
647
|
-
}, this.options.ajaxOptions)
|
648
|
-
);
|
649
|
-
},
|
650
|
-
onLoadedExternalText: function(transport) {
|
651
|
-
Element.removeClassName(this.form, this.options.loadingClassName);
|
652
|
-
this.editField.disabled = false;
|
653
|
-
this.editField.value = transport.responseText.stripTags();
|
654
|
-
Field.scrollFreeActivate(this.editField);
|
655
|
-
},
|
656
|
-
onclickCancel: function() {
|
657
|
-
this.onComplete();
|
658
|
-
this.leaveEditMode();
|
659
|
-
return false;
|
660
|
-
},
|
661
|
-
onFailure: function(transport) {
|
662
|
-
this.options.onFailure(transport);
|
663
|
-
if (this.oldInnerHTML) {
|
664
|
-
this.element.innerHTML = this.oldInnerHTML;
|
665
|
-
this.oldInnerHTML = null;
|
611
|
+
handleAJAXFailure: function(transport) {
|
612
|
+
this.triggerCallback('onFailure', transport);
|
613
|
+
if (this._oldInnerHTML) {
|
614
|
+
this.element.innerHTML = this._oldInnerHTML;
|
615
|
+
this._oldInnerHTML = null;
|
666
616
|
}
|
667
|
-
return false;
|
668
617
|
},
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
this.
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
this.
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
}, this.options.ajaxOptions));
|
698
|
-
}
|
699
|
-
// stop the event to avoid a page refresh in Safari
|
700
|
-
if (arguments.length > 1) {
|
701
|
-
Event.stop(arguments[0]);
|
618
|
+
handleFormCancellation: function(e) {
|
619
|
+
this.wrapUp();
|
620
|
+
if (e) Event.stop(e);
|
621
|
+
},
|
622
|
+
handleFormSubmission: function(e) {
|
623
|
+
var form = this._form;
|
624
|
+
var value = $F(this._controls.editor);
|
625
|
+
this.prepareSubmission();
|
626
|
+
var params = this.options.callback(form, value) || '';
|
627
|
+
if (Object.isString(params))
|
628
|
+
params = params.toQueryParams();
|
629
|
+
params.editorId = this.element.id;
|
630
|
+
if (this.options.htmlResponse) {
|
631
|
+
var options = Object.extend({ evalScripts: true }, this.options.ajaxOptions);
|
632
|
+
Object.extend(options, {
|
633
|
+
parameters: params,
|
634
|
+
onComplete: this._boundWrapperHandler,
|
635
|
+
onFailure: this._boundFailureHandler
|
636
|
+
});
|
637
|
+
new Ajax.Updater({ success: this.element }, this.url, options);
|
638
|
+
} else {
|
639
|
+
var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
|
640
|
+
Object.extend(options, {
|
641
|
+
parameters: params,
|
642
|
+
onComplete: this._boundWrapperHandler,
|
643
|
+
onFailure: this._boundFailureHandler
|
644
|
+
});
|
645
|
+
new Ajax.Request(this.url, options);
|
702
646
|
}
|
703
|
-
|
647
|
+
if (e) Event.stop(e);
|
648
|
+
},
|
649
|
+
leaveEditMode: function() {
|
650
|
+
this.element.removeClassName(this.options.savingClassName);
|
651
|
+
this.removeForm();
|
652
|
+
this.leaveHover();
|
653
|
+
this.element.style.backgroundColor = this._originalBackground;
|
654
|
+
this.element.show();
|
655
|
+
if (this.options.externalControl)
|
656
|
+
this.options.externalControl.show();
|
657
|
+
this._saving = false;
|
658
|
+
this._editing = false;
|
659
|
+
this._oldInnerHTML = null;
|
660
|
+
this.triggerCallback('onLeaveEditMode');
|
661
|
+
},
|
662
|
+
leaveHover: function(e) {
|
663
|
+
if (this.options.hoverClassName)
|
664
|
+
this.element.removeClassName(this.options.hoverClassName);
|
665
|
+
if (this._saving) return;
|
666
|
+
this.triggerCallback('onLeaveHover');
|
704
667
|
},
|
705
|
-
|
706
|
-
this.
|
668
|
+
loadExternalText: function() {
|
669
|
+
this._form.addClassName(this.options.loadingClassName);
|
670
|
+
this._controls.editor.disabled = true;
|
671
|
+
var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
|
672
|
+
Object.extend(options, {
|
673
|
+
parameters: 'editorId=' + encodeURIComponent(this.element.id),
|
674
|
+
onComplete: Prototype.emptyFunction,
|
675
|
+
onSuccess: function(transport) {
|
676
|
+
this._form.removeClassName(this.options.loadingClassName);
|
677
|
+
var text = transport.responseText;
|
678
|
+
if (this.options.stripLoadedTextTags)
|
679
|
+
text = text.stripTags();
|
680
|
+
this._controls.editor.value = text;
|
681
|
+
this._controls.editor.disabled = false;
|
682
|
+
this.postProcessEditField();
|
683
|
+
}.bind(this),
|
684
|
+
onFailure: this._boundFailureHandler
|
685
|
+
});
|
686
|
+
new Ajax.Request(this.options.loadTextURL, options);
|
687
|
+
},
|
688
|
+
postProcessEditField: function() {
|
689
|
+
var fpc = this.options.fieldPostCreation;
|
690
|
+
if (fpc)
|
691
|
+
$(this._controls.editor)['focus' == fpc ? 'focus' : 'activate']();
|
692
|
+
},
|
693
|
+
prepareOptions: function() {
|
694
|
+
this.options = Object.clone(Ajax.InPlaceEditor.DefaultOptions);
|
695
|
+
Object.extend(this.options, Ajax.InPlaceEditor.DefaultCallbacks);
|
696
|
+
[this._extraDefaultOptions].flatten().compact().each(function(defs) {
|
697
|
+
Object.extend(this.options, defs);
|
698
|
+
}.bind(this));
|
699
|
+
},
|
700
|
+
prepareSubmission: function() {
|
701
|
+
this._saving = true;
|
707
702
|
this.removeForm();
|
708
703
|
this.leaveHover();
|
709
704
|
this.showSaving();
|
710
705
|
},
|
706
|
+
registerListeners: function() {
|
707
|
+
this._listeners = { };
|
708
|
+
var listener;
|
709
|
+
$H(Ajax.InPlaceEditor.Listeners).each(function(pair) {
|
710
|
+
listener = this[pair.value].bind(this);
|
711
|
+
this._listeners[pair.key] = listener;
|
712
|
+
if (!this.options.externalControlOnly)
|
713
|
+
this.element.observe(pair.key, listener);
|
714
|
+
if (this.options.externalControl)
|
715
|
+
this.options.externalControl.observe(pair.key, listener);
|
716
|
+
}.bind(this));
|
717
|
+
},
|
718
|
+
removeForm: function() {
|
719
|
+
if (!this._form) return;
|
720
|
+
this._form.remove();
|
721
|
+
this._form = null;
|
722
|
+
this._controls = { };
|
723
|
+
},
|
711
724
|
showSaving: function() {
|
712
|
-
this.
|
725
|
+
this._oldInnerHTML = this.element.innerHTML;
|
713
726
|
this.element.innerHTML = this.options.savingText;
|
714
|
-
|
715
|
-
this.element.style.backgroundColor = this.
|
716
|
-
|
727
|
+
this.element.addClassName(this.options.savingClassName);
|
728
|
+
this.element.style.backgroundColor = this._originalBackground;
|
729
|
+
this.element.show();
|
717
730
|
},
|
718
|
-
|
719
|
-
if(this.
|
720
|
-
|
721
|
-
this.form = null;
|
731
|
+
triggerCallback: function(cbName, arg) {
|
732
|
+
if ('function' == typeof this.options[cbName]) {
|
733
|
+
this.options[cbName](this, arg);
|
722
734
|
}
|
723
735
|
},
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
this.
|
729
|
-
|
730
|
-
|
736
|
+
unregisterListeners: function() {
|
737
|
+
$H(this._listeners).each(function(pair) {
|
738
|
+
if (!this.options.externalControlOnly)
|
739
|
+
this.element.stopObserving(pair.key, pair.value);
|
740
|
+
if (this.options.externalControl)
|
741
|
+
this.options.externalControl.stopObserving(pair.key, pair.value);
|
742
|
+
}.bind(this));
|
731
743
|
},
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
744
|
+
wrapUp: function(transport) {
|
745
|
+
this.leaveEditMode();
|
746
|
+
// Can't use triggerCallback due to backward compatibility: requires
|
747
|
+
// binding + direct element
|
748
|
+
this._boundComplete(transport, this.element);
|
749
|
+
}
|
750
|
+
});
|
751
|
+
|
752
|
+
Object.extend(Ajax.InPlaceEditor.prototype, {
|
753
|
+
dispose: Ajax.InPlaceEditor.prototype.destroy
|
754
|
+
});
|
755
|
+
|
756
|
+
Ajax.InPlaceCollectionEditor = Class.create(Ajax.InPlaceEditor, {
|
757
|
+
initialize: function($super, element, url, options) {
|
758
|
+
this._extraDefaultOptions = Ajax.InPlaceCollectionEditor.DefaultOptions;
|
759
|
+
$super(element, url, options);
|
760
|
+
},
|
761
|
+
|
762
|
+
createEditField: function() {
|
763
|
+
var list = document.createElement('select');
|
764
|
+
list.name = this.options.paramName;
|
765
|
+
list.size = 1;
|
766
|
+
this._controls.editor = list;
|
767
|
+
this._collection = this.options.collection || [];
|
768
|
+
if (this.options.loadCollectionURL)
|
769
|
+
this.loadCollection();
|
770
|
+
else
|
771
|
+
this.checkForExternalText();
|
772
|
+
this._form.appendChild(this._controls.editor);
|
773
|
+
},
|
774
|
+
|
775
|
+
loadCollection: function() {
|
776
|
+
this._form.addClassName(this.options.loadingClassName);
|
777
|
+
this.showLoadingText(this.options.loadingCollectionText);
|
778
|
+
var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
|
779
|
+
Object.extend(options, {
|
780
|
+
parameters: 'editorId=' + encodeURIComponent(this.element.id),
|
781
|
+
onComplete: Prototype.emptyFunction,
|
782
|
+
onSuccess: function(transport) {
|
783
|
+
var js = transport.responseText.strip();
|
784
|
+
if (!/^\[.*\]$/.test(js)) // TODO: improve sanity check
|
785
|
+
throw 'Server returned an invalid collection representation.';
|
786
|
+
this._collection = eval(js);
|
787
|
+
this.checkForExternalText();
|
788
|
+
}.bind(this),
|
789
|
+
onFailure: this.onFailure
|
742
790
|
});
|
791
|
+
new Ajax.Request(this.options.loadCollectionURL, options);
|
743
792
|
},
|
744
|
-
|
745
|
-
|
746
|
-
this.
|
747
|
-
this.
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
793
|
+
|
794
|
+
showLoadingText: function(text) {
|
795
|
+
this._controls.editor.disabled = true;
|
796
|
+
var tempOption = this._controls.editor.firstChild;
|
797
|
+
if (!tempOption) {
|
798
|
+
tempOption = document.createElement('option');
|
799
|
+
tempOption.value = '';
|
800
|
+
this._controls.editor.appendChild(tempOption);
|
801
|
+
tempOption.selected = true;
|
752
802
|
}
|
753
|
-
|
754
|
-
this.saving = false;
|
755
|
-
this.oldInnerHTML = null;
|
756
|
-
this.onLeaveEditMode();
|
803
|
+
tempOption.update((text || '').stripScripts().stripTags());
|
757
804
|
},
|
758
|
-
|
759
|
-
|
760
|
-
this.
|
805
|
+
|
806
|
+
checkForExternalText: function() {
|
807
|
+
this._text = this.getText();
|
808
|
+
if (this.options.loadTextURL)
|
809
|
+
this.loadExternalText();
|
810
|
+
else
|
811
|
+
this.buildOptionList();
|
761
812
|
},
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
813
|
+
|
814
|
+
loadExternalText: function() {
|
815
|
+
this.showLoadingText(this.options.loadingText);
|
816
|
+
var options = Object.extend({ method: 'get' }, this.options.ajaxOptions);
|
817
|
+
Object.extend(options, {
|
818
|
+
parameters: 'editorId=' + encodeURIComponent(this.element.id),
|
819
|
+
onComplete: Prototype.emptyFunction,
|
820
|
+
onSuccess: function(transport) {
|
821
|
+
this._text = transport.responseText.strip();
|
822
|
+
this.buildOptionList();
|
823
|
+
}.bind(this),
|
824
|
+
onFailure: this.onFailure
|
825
|
+
});
|
826
|
+
new Ajax.Request(this.options.loadTextURL, options);
|
827
|
+
},
|
828
|
+
|
829
|
+
buildOptionList: function() {
|
830
|
+
this._form.removeClassName(this.options.loadingClassName);
|
831
|
+
this._collection = this._collection.map(function(entry) {
|
832
|
+
return 2 === entry.length ? entry : [entry, entry].flatten();
|
833
|
+
});
|
834
|
+
var marker = ('value' in this.options) ? this.options.value : this._text;
|
835
|
+
var textFound = this._collection.any(function(entry) {
|
836
|
+
return entry[0] == marker;
|
837
|
+
}.bind(this));
|
838
|
+
this._controls.editor.update('');
|
839
|
+
var option;
|
840
|
+
this._collection.each(function(entry, index) {
|
841
|
+
option = document.createElement('option');
|
842
|
+
option.value = entry[0];
|
843
|
+
option.selected = textFound ? entry[0] == marker : 0 == index;
|
844
|
+
option.appendChild(document.createTextNode(entry[1]));
|
845
|
+
this._controls.editor.appendChild(option);
|
846
|
+
}.bind(this));
|
847
|
+
this._controls.editor.disabled = false;
|
848
|
+
Field.scrollFreeActivate(this._controls.editor);
|
777
849
|
}
|
778
|
-
};
|
850
|
+
});
|
779
851
|
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
}
|
852
|
+
//**** DEPRECATION LAYER FOR InPlace[Collection]Editor! ****
|
853
|
+
//**** This only exists for a while, in order to let ****
|
854
|
+
//**** users adapt to the new API. Read up on the new ****
|
855
|
+
//**** API and convert your code to it ASAP! ****
|
856
|
+
|
857
|
+
Ajax.InPlaceEditor.prototype.initialize.dealWithDeprecatedOptions = function(options) {
|
858
|
+
if (!options) return;
|
859
|
+
function fallback(name, expr) {
|
860
|
+
if (name in options || expr === undefined) return;
|
861
|
+
options[name] = expr;
|
862
|
+
};
|
863
|
+
fallback('cancelControl', (options.cancelLink ? 'link' : (options.cancelButton ? 'button' :
|
864
|
+
options.cancelLink == options.cancelButton == false ? false : undefined)));
|
865
|
+
fallback('okControl', (options.okLink ? 'link' : (options.okButton ? 'button' :
|
866
|
+
options.okLink == options.okButton == false ? false : undefined)));
|
867
|
+
fallback('highlightColor', options.highlightcolor);
|
868
|
+
fallback('highlightEndColor', options.highlightendcolor);
|
869
|
+
};
|
799
870
|
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
871
|
+
Object.extend(Ajax.InPlaceEditor, {
|
872
|
+
DefaultOptions: {
|
873
|
+
ajaxOptions: { },
|
874
|
+
autoRows: 3, // Use when multi-line w/ rows == 1
|
875
|
+
cancelControl: 'link', // 'link'|'button'|false
|
876
|
+
cancelText: 'cancel',
|
877
|
+
clickToEditText: 'Click to edit',
|
878
|
+
externalControl: null, // id|elt
|
879
|
+
externalControlOnly: false,
|
880
|
+
fieldPostCreation: 'activate', // 'activate'|'focus'|false
|
881
|
+
formClassName: 'inplaceeditor-form',
|
882
|
+
formId: null, // id|elt
|
883
|
+
highlightColor: '#ffff99',
|
884
|
+
highlightEndColor: '#ffffff',
|
885
|
+
hoverClassName: '',
|
886
|
+
htmlResponse: true,
|
887
|
+
loadingClassName: 'inplaceeditor-loading',
|
888
|
+
loadingText: 'Loading...',
|
889
|
+
okControl: 'button', // 'link'|'button'|false
|
890
|
+
okText: 'ok',
|
891
|
+
paramName: 'value',
|
892
|
+
rows: 1, // If 1 and multi-line, uses autoRows
|
893
|
+
savingClassName: 'inplaceeditor-saving',
|
894
|
+
savingText: 'Saving...',
|
895
|
+
size: 0,
|
896
|
+
stripLoadedTextTags: false,
|
897
|
+
submitOnBlur: false,
|
898
|
+
textAfterControls: '',
|
899
|
+
textBeforeControls: '',
|
900
|
+
textBetweenControls: ''
|
901
|
+
},
|
902
|
+
DefaultCallbacks: {
|
903
|
+
callback: function(form) {
|
904
|
+
return Form.serialize(form);
|
905
|
+
},
|
906
|
+
onComplete: function(transport, element) {
|
907
|
+
// For backward compatibility, this one is bound to the IPE, and passes
|
908
|
+
// the element directly. It was too often customized, so we don't break it.
|
909
|
+
new Effect.Highlight(element, {
|
910
|
+
startcolor: this.options.highlightColor, keepBackgroundImage: true });
|
911
|
+
},
|
912
|
+
onEnterEditMode: null,
|
913
|
+
onEnterHover: function(ipe) {
|
914
|
+
ipe.element.style.backgroundColor = ipe.options.highlightColor;
|
915
|
+
if (ipe._effect)
|
916
|
+
ipe._effect.cancel();
|
917
|
+
},
|
918
|
+
onFailure: function(transport, ipe) {
|
919
|
+
alert('Error communication with the server: ' + transport.responseText.stripTags());
|
920
|
+
},
|
921
|
+
onFormCustomization: null, // Takes the IPE and its generated form, after editor, before controls.
|
922
|
+
onLeaveEditMode: null,
|
923
|
+
onLeaveHover: function(ipe) {
|
924
|
+
ipe._effect = new Effect.Highlight(ipe.element, {
|
925
|
+
startcolor: ipe.options.highlightColor, endcolor: ipe.options.highlightEndColor,
|
926
|
+
restorecolor: ipe._originalBackground, keepBackgroundImage: true
|
927
|
+
});
|
805
928
|
}
|
929
|
+
},
|
930
|
+
Listeners: {
|
931
|
+
click: 'enterEditMode',
|
932
|
+
keydown: 'checkForEscapeOrReturn',
|
933
|
+
mouseover: 'enterHover',
|
934
|
+
mouseout: 'leaveHover'
|
806
935
|
}
|
807
936
|
});
|
808
937
|
|
938
|
+
Ajax.InPlaceCollectionEditor.DefaultOptions = {
|
939
|
+
loadingCollectionText: 'Loading options...'
|
940
|
+
};
|
941
|
+
|
809
942
|
// Delayed observer, like Form.Element.Observer,
|
810
943
|
// but waits for delay after last key input
|
811
944
|
// Ideal for live-search fields
|
812
945
|
|
813
|
-
Form.Element.DelayedObserver = Class.create(
|
814
|
-
Form.Element.DelayedObserver.prototype = {
|
946
|
+
Form.Element.DelayedObserver = Class.create({
|
815
947
|
initialize: function(element, delay, callback) {
|
816
948
|
this.delay = delay || 0.5;
|
817
949
|
this.element = $(element);
|
@@ -830,4 +962,4 @@ Form.Element.DelayedObserver.prototype = {
|
|
830
962
|
this.timer = null;
|
831
963
|
this.callback(this.element, $F(this.element));
|
832
964
|
}
|
833
|
-
};
|
965
|
+
});
|