aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.codeclimate.yml27
-rw-r--r--.rubocop.yml27
-rw-r--r--.travis.yml7
-rw-r--r--Gemfile11
-rw-r--r--Gemfile.lock85
-rw-r--r--actioncable/CHANGELOG.md3
-rw-r--r--actioncable/README.md76
-rw-r--r--actioncable/lib/action_cable/channel/periodic_timers.rb4
-rw-r--r--actioncable/lib/action_cable/connection/stream.rb1
-rw-r--r--actioncable/lib/action_cable/connection/subscriptions.rb6
-rw-r--r--actioncable/lib/action_cable/engine.rb9
-rw-r--r--actioncable/lib/action_cable/server/base.rb16
-rw-r--r--actioncable/lib/action_cable/server/broadcasting.rb8
-rw-r--r--actioncable/lib/action_cable/server/configuration.rb10
-rw-r--r--actioncable/lib/action_cable/server/worker.rb12
-rw-r--r--actioncable/lib/action_cable/subscription_adapter/subscriber_map.rb6
-rw-r--r--actioncable/lib/rails/generators/channel/templates/application_cable/channel.rb2
-rw-r--r--actioncable/lib/rails/generators/channel/templates/application_cable/connection.rb2
-rw-r--r--actioncable/lib/rails/generators/channel/templates/channel.rb1
-rw-r--r--actioncable/test/channel/stream_test.rb4
-rw-r--r--actioncable/test/client/echo_channel.rb22
-rw-r--r--actioncable/test/client_test.rb79
-rw-r--r--actioncable/test/connection/client_socket_test.rb14
-rw-r--r--actioncable/test/connection/subscriptions_test.rb1
-rw-r--r--actioncable/test/server/broadcasting_test.rb53
-rw-r--r--actioncable/test/subscription_adapter/subscriber_map_test.rb17
-rw-r--r--actionmailer/lib/action_mailer/base.rb5
-rw-r--r--actionpack/actionpack.gemspec2
-rw-r--r--actionpack/lib/abstract_controller/base.rb7
-rw-r--r--actionpack/lib/abstract_controller/callbacks.rb2
-rw-r--r--actionpack/lib/abstract_controller/rendering.rb2
-rw-r--r--actionpack/lib/action_controller/base.rb8
-rw-r--r--actionpack/lib/action_controller/metal/etag_with_template_digest.rb8
-rw-r--r--actionpack/lib/action_controller/metal/strong_parameters.rb39
-rw-r--r--actionpack/lib/action_controller/renderer.rb2
-rw-r--r--actionpack/lib/action_dispatch.rb1
-rw-r--r--actionpack/lib/action_dispatch/middleware/debug_exceptions.rb8
-rw-r--r--actionpack/lib/action_dispatch/middleware/debug_locks.rb122
-rw-r--r--actionpack/lib/action_dispatch/routing.rb8
-rw-r--r--actionpack/lib/action_dispatch/routing/mapper.rb12
-rw-r--r--actionpack/lib/action_dispatch/routing/polymorphic_routes.rb4
-rw-r--r--actionpack/lib/action_dispatch/testing/integration.rb34
-rw-r--r--actionpack/test/controller/integration_test.rb30
-rw-r--r--actionpack/test/controller/parameters/nested_parameters_permit_test.rb (renamed from actionpack/test/controller/parameters/nested_parameters_test.rb)2
-rw-r--r--actionpack/test/controller/parameters/parameters_permit_test.rb6
-rw-r--r--actionpack/test/controller/render_test.rb52
-rw-r--r--actionpack/test/controller/send_file_test.rb15
-rw-r--r--actionpack/test/dispatch/cookies_test.rb4
-rw-r--r--actionpack/test/dispatch/debug_exceptions_test.rb23
-rw-r--r--actionpack/test/dispatch/mapper_test.rb12
-rw-r--r--actionpack/test/dispatch/request/json_params_parsing_test.rb6
-rw-r--r--actionpack/test/dispatch/routing_test.rb30
-rw-r--r--actionpack/test/fixtures/test/with_implicit_template.erb1
-rw-r--r--actionview/CHANGELOG.md46
-rw-r--r--actionview/lib/action_view/base.rb12
-rw-r--r--actionview/lib/action_view/digestor.rb11
-rw-r--r--actionview/lib/action_view/helpers/asset_tag_helper.rb4
-rw-r--r--actionview/lib/action_view/helpers/date_helper.rb3
-rw-r--r--actionview/lib/action_view/helpers/form_helper.rb65
-rw-r--r--actionview/lib/action_view/helpers/form_options_helper.rb2
-rw-r--r--actionview/lib/action_view/helpers/form_tag_helper.rb19
-rw-r--r--actionview/lib/action_view/helpers/number_helper.rb2
-rw-r--r--actionview/lib/action_view/helpers/tag_helper.rb264
-rw-r--r--actionview/lib/action_view/helpers/tags/base.rb4
-rw-r--r--actionview/lib/action_view/helpers/tags/datetime_field.rb2
-rw-r--r--actionview/lib/action_view/helpers/tags/file_field.rb15
-rw-r--r--actionview/lib/action_view/helpers/text_helper.rb9
-rw-r--r--actionview/lib/action_view/template/handlers/raw.rb2
-rw-r--r--actionview/test/actionpack/controller/render_test.rb5
-rw-r--r--actionview/test/activerecord/debug_helper_test.rb5
-rw-r--r--actionview/test/fixtures/digestor/api/comments/_comment.json.erb1
-rw-r--r--actionview/test/fixtures/digestor/api/comments/_comments.json.erb1
-rw-r--r--actionview/test/fixtures/digestor/messages/thread.json.erb1
-rw-r--r--actionview/test/fixtures/test/_builder_tag_nested_in_content_tag.erb3
-rw-r--r--actionview/test/template/asset_tag_helper_test.rb4
-rw-r--r--actionview/test/template/date_helper_test.rb11
-rw-r--r--actionview/test/template/digestor_test.rb42
-rw-r--r--actionview/test/template/form_helper_test.rb123
-rw-r--r--actionview/test/template/form_options_helper_test.rb11
-rw-r--r--actionview/test/template/form_tag_helper_test.rb6
-rw-r--r--actionview/test/template/render_test.rb7
-rw-r--r--actionview/test/template/tag_helper_test.rb164
-rw-r--r--activejob/lib/active_job/logging.rb2
-rw-r--r--activejob/lib/active_job/queue_adapters/sucker_punch_adapter.rb2
-rw-r--r--activejob/lib/active_job/test_helper.rb15
-rw-r--r--activejob/test/cases/logging_test.rb7
-rw-r--r--activejob/test/cases/test_helper_test.rb12
-rw-r--r--activejob/test/jobs/overridden_logging_job.rb9
-rw-r--r--activemodel/lib/active_model/errors.rb19
-rw-r--r--activemodel/lib/active_model/type/date.rb4
-rw-r--r--activemodel/lib/active_model/validations.rb2
-rw-r--r--activemodel/test/cases/errors_test.rb6
-rw-r--r--activerecord/CHANGELOG.md25
-rw-r--r--activerecord/lib/active_record/associations/has_many_association.rb12
-rw-r--r--activerecord/lib/active_record/attribute.rb12
-rw-r--r--activerecord/lib/active_record/attribute_methods.rb24
-rw-r--r--activerecord/lib/active_record/attribute_set/yaml_encoder.rb2
-rw-r--r--activerecord/lib/active_record/attributes.rb4
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb9
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb14
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb39
-rw-r--r--activerecord/lib/active_record/connection_adapters/mysql/column.rb7
-rw-r--r--activerecord/lib/active_record/connection_adapters/mysql/database_statements.rb13
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb4
-rw-r--r--activerecord/lib/active_record/connection_handling.rb10
-rw-r--r--activerecord/lib/active_record/enum.rb2
-rw-r--r--activerecord/lib/active_record/fixtures.rb2
-rw-r--r--activerecord/lib/active_record/inheritance.rb3
-rw-r--r--activerecord/lib/active_record/internal_metadata.rb13
-rw-r--r--activerecord/lib/active_record/persistence.rb7
-rw-r--r--activerecord/lib/active_record/query_cache.rb14
-rw-r--r--activerecord/lib/active_record/relation.rb2
-rw-r--r--activerecord/lib/active_record/relation/finder_methods.rb14
-rw-r--r--activerecord/lib/active_record/relation/predicate_builder.rb6
-rw-r--r--activerecord/lib/active_record/relation/predicate_builder/basic_object_handler.rb8
-rw-r--r--activerecord/lib/active_record/relation/predicate_builder/range_handler.rb8
-rw-r--r--activerecord/lib/active_record/relation/query_methods.rb2
-rw-r--r--activerecord/lib/active_record/result.rb8
-rw-r--r--activerecord/lib/active_record/runtime_registry.rb4
-rw-r--r--activerecord/lib/active_record/tasks/mysql_database_tasks.rb1
-rw-r--r--activerecord/lib/active_record/tasks/postgresql_database_tasks.rb3
-rw-r--r--activerecord/lib/active_record/touch_later.rb7
-rw-r--r--activerecord/lib/active_record/transactions.rb8
-rw-r--r--activerecord/lib/active_record/validations/uniqueness.rb6
-rw-r--r--activerecord/lib/rails/generators/active_record/model/model_generator.rb14
-rw-r--r--activerecord/test/cases/adapters/mysql2/schema_test.rb21
-rw-r--r--activerecord/test/cases/adapters/postgresql/array_test.rb7
-rw-r--r--activerecord/test/cases/adapters/sqlite3/quoting_test.rb178
-rw-r--r--activerecord/test/cases/adapters/sqlite3/statement_pool_test.rb28
-rw-r--r--activerecord/test/cases/associations/eager_test.rb4
-rw-r--r--activerecord/test/cases/associations/left_outer_join_association_test.rb2
-rw-r--r--activerecord/test/cases/attribute_methods_test.rb23
-rw-r--r--activerecord/test/cases/attribute_test.rb7
-rw-r--r--activerecord/test/cases/base_test.rb8
-rw-r--r--activerecord/test/cases/batches_test.rb4
-rw-r--r--activerecord/test/cases/column_definition_test.rb7
-rw-r--r--activerecord/test/cases/date_test.rb (renamed from activerecord/test/cases/invalid_date_test.rb)14
-rw-r--r--activerecord/test/cases/dirty_test.rb28
-rw-r--r--activerecord/test/cases/enum_test.rb4
-rw-r--r--activerecord/test/cases/finder_test.rb6
-rw-r--r--activerecord/test/cases/migration/foreign_key_test.rb13
-rw-r--r--activerecord/test/cases/migration_test.rb15
-rw-r--r--activerecord/test/cases/multiparameter_attributes_test.rb14
-rw-r--r--activerecord/test/cases/primary_keys_test.rb20
-rw-r--r--activerecord/test/cases/query_cache_test.rb29
-rw-r--r--activerecord/test/cases/result_test.rb10
-rw-r--r--activerecord/test/cases/tasks/mysql_rake_test.rb8
-rw-r--r--activerecord/test/cases/tasks/postgresql_rake_test.rb4
-rw-r--r--activerecord/test/cases/test_case.rb4
-rw-r--r--activerecord/test/cases/validations/i18n_validation_test.rb6
-rw-r--r--activerecord/test/schema/schema.rb15
-rw-r--r--activesupport/CHANGELOG.md26
-rw-r--r--activesupport/lib/active_support/cache.rb4
-rw-r--r--activesupport/lib/active_support/callbacks.rb9
-rw-r--r--activesupport/lib/active_support/concurrency/latch.rb17
-rw-r--r--activesupport/lib/active_support/concurrency/share_lock.rb50
-rw-r--r--activesupport/lib/active_support/core_ext/date/conversions.rb6
-rw-r--r--activesupport/lib/active_support/core_ext/hash/compact.rb13
-rw-r--r--activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb4
-rw-r--r--activesupport/lib/active_support/core_ext/module/delegation.rb4
-rw-r--r--activesupport/lib/active_support/core_ext/object/json.rb14
-rw-r--r--activesupport/lib/active_support/dependencies/interlock.rb4
-rw-r--r--activesupport/lib/active_support/deprecation/behaviors.rb2
-rw-r--r--activesupport/lib/active_support/evented_file_update_checker.rb49
-rw-r--r--activesupport/lib/active_support/inflector/methods.rb8
-rw-r--r--activesupport/lib/active_support/json/decoding.rb11
-rw-r--r--activesupport/lib/active_support/key_generator.rb8
-rw-r--r--activesupport/lib/active_support/logger.rb18
-rw-r--r--activesupport/lib/active_support/ordered_options.rb2
-rw-r--r--activesupport/lib/active_support/per_thread_registry.rb2
-rw-r--r--activesupport/lib/active_support/test_case.rb7
-rw-r--r--activesupport/lib/active_support/testing/assertions.rb2
-rw-r--r--activesupport/lib/active_support/testing/isolation.rb11
-rw-r--r--activesupport/lib/active_support/testing/time_helpers.rb6
-rw-r--r--activesupport/test/broadcast_logger_test.rb134
-rw-r--r--activesupport/test/core_ext/date_ext_test.rb11
-rw-r--r--activesupport/test/core_ext/hash_ext_test.rb10
-rw-r--r--activesupport/test/deprecation_test.rb2
-rw-r--r--activesupport/test/evented_file_update_checker_test.rb44
-rw-r--r--activesupport/test/json/decoding_test.rb16
-rw-r--r--activesupport/test/json/encoding_test_cases.rb4
-rw-r--r--activesupport/test/key_generator_test.rb17
-rw-r--r--activesupport/test/logger_test.rb12
-rw-r--r--activesupport/test/message_encryptor_test.rb4
-rw-r--r--activesupport/test/multibyte_conformance_test.rb20
-rw-r--r--activesupport/test/multibyte_grapheme_break_conformance_test.rb32
-rw-r--r--activesupport/test/multibyte_normalization_conformance_test.rb27
-rw-r--r--activesupport/test/multibyte_test_helpers.rb22
-rw-r--r--activesupport/test/testing/file_fixtures_test.rb6
-rw-r--r--guides/assets/images/getting_started/template_is_missing_articles_new.pngbin6174 -> 587962 bytes
-rw-r--r--guides/assets/javascripts/guides.js6
-rw-r--r--guides/assets/javascripts/syntaxhighlighter.js20
-rw-r--r--guides/assets/javascripts/syntaxhighlighter/shBrushAS3.js59
-rw-r--r--guides/assets/javascripts/syntaxhighlighter/shBrushAppleScript.js75
-rw-r--r--guides/assets/javascripts/syntaxhighlighter/shBrushBash.js59
-rw-r--r--guides/assets/javascripts/syntaxhighlighter/shBrushCSharp.js65
-rw-r--r--guides/assets/javascripts/syntaxhighlighter/shBrushColdFusion.js100
-rw-r--r--guides/assets/javascripts/syntaxhighlighter/shBrushCpp.js97
-rw-r--r--guides/assets/javascripts/syntaxhighlighter/shBrushCss.js91
-rw-r--r--guides/assets/javascripts/syntaxhighlighter/shBrushDelphi.js55
-rw-r--r--guides/assets/javascripts/syntaxhighlighter/shBrushDiff.js41
-rw-r--r--guides/assets/javascripts/syntaxhighlighter/shBrushErlang.js52
-rw-r--r--guides/assets/javascripts/syntaxhighlighter/shBrushGroovy.js67
-rw-r--r--guides/assets/javascripts/syntaxhighlighter/shBrushJScript.js52
-rw-r--r--guides/assets/javascripts/syntaxhighlighter/shBrushJava.js57
-rw-r--r--guides/assets/javascripts/syntaxhighlighter/shBrushJavaFX.js58
-rw-r--r--guides/assets/javascripts/syntaxhighlighter/shBrushPerl.js72
-rw-r--r--guides/assets/javascripts/syntaxhighlighter/shBrushPhp.js88
-rw-r--r--guides/assets/javascripts/syntaxhighlighter/shBrushPlain.js33
-rw-r--r--guides/assets/javascripts/syntaxhighlighter/shBrushPowerShell.js74
-rw-r--r--guides/assets/javascripts/syntaxhighlighter/shBrushPython.js64
-rw-r--r--guides/assets/javascripts/syntaxhighlighter/shBrushRuby.js55
-rw-r--r--guides/assets/javascripts/syntaxhighlighter/shBrushSass.js94
-rw-r--r--guides/assets/javascripts/syntaxhighlighter/shBrushScala.js51
-rw-r--r--guides/assets/javascripts/syntaxhighlighter/shBrushSql.js66
-rw-r--r--guides/assets/javascripts/syntaxhighlighter/shBrushVb.js56
-rw-r--r--guides/assets/javascripts/syntaxhighlighter/shBrushXml.js69
-rw-r--r--guides/assets/javascripts/syntaxhighlighter/shCore.js17
-rw-r--r--guides/assets/stylesheets/syntaxhighlighter/shCoreDefault.css328
-rw-r--r--guides/assets/stylesheets/syntaxhighlighter/shCoreDjango.css331
-rw-r--r--guides/assets/stylesheets/syntaxhighlighter/shCoreEclipse.css339
-rw-r--r--guides/assets/stylesheets/syntaxhighlighter/shCoreEmacs.css324
-rw-r--r--guides/assets/stylesheets/syntaxhighlighter/shCoreFadeToGrey.css328
-rw-r--r--guides/assets/stylesheets/syntaxhighlighter/shCoreMDUltra.css324
-rw-r--r--guides/assets/stylesheets/syntaxhighlighter/shCoreMidnight.css324
-rw-r--r--guides/assets/stylesheets/syntaxhighlighter/shCoreRDark.css324
-rw-r--r--guides/assets/stylesheets/syntaxhighlighter/shThemeDefault.css117
-rw-r--r--guides/assets/stylesheets/syntaxhighlighter/shThemeDjango.css120
-rw-r--r--guides/assets/stylesheets/syntaxhighlighter/shThemeEclipse.css128
-rw-r--r--guides/assets/stylesheets/syntaxhighlighter/shThemeEmacs.css113
-rw-r--r--guides/assets/stylesheets/syntaxhighlighter/shThemeFadeToGrey.css117
-rwxr-xr-xguides/assets/stylesheets/syntaxhighlighter/shThemeMDUltra.css113
-rw-r--r--guides/assets/stylesheets/syntaxhighlighter/shThemeMidnight.css113
-rw-r--r--guides/assets/stylesheets/syntaxhighlighter/shThemeRDark.css113
-rw-r--r--guides/rails_guides/generator.rb6
-rw-r--r--guides/source/4_2_release_notes.md2
-rw-r--r--guides/source/5_0_release_notes.md206
-rw-r--r--guides/source/action_cable_overview.md13
-rw-r--r--guides/source/action_controller_overview.md15
-rw-r--r--guides/source/action_mailer_basics.md2
-rw-r--r--guides/source/action_view_overview.md2
-rw-r--r--guides/source/active_job_basics.md22
-rw-r--r--guides/source/active_record_callbacks.md4
-rw-r--r--guides/source/active_record_postgresql.md4
-rw-r--r--guides/source/active_record_validations.md12
-rw-r--r--guides/source/active_support_core_extensions.md3
-rw-r--r--guides/source/api_app.md13
-rw-r--r--guides/source/api_documentation_guidelines.md2
-rw-r--r--guides/source/command_line.md2
-rw-r--r--guides/source/configuring.md34
-rw-r--r--guides/source/contributing_to_ruby_on_rails.md16
-rw-r--r--guides/source/credits.html.erb2
-rw-r--r--guides/source/documents.yaml7
-rw-r--r--guides/source/engines.md8
-rw-r--r--guides/source/getting_started.md27
-rw-r--r--guides/source/i18n.md7
-rw-r--r--guides/source/layout.html.erb12
-rw-r--r--guides/source/rails_application_templates.md4
-rw-r--r--guides/source/rails_on_rack.md17
-rw-r--r--guides/source/routing.md6
-rw-r--r--guides/source/testing.md162
-rw-r--r--guides/source/upgrading_ruby_on_rails.md226
-rw-r--r--railties/CHANGELOG.md17
-rw-r--r--railties/lib/rails/application/configuration.rb3
-rw-r--r--railties/lib/rails/application/finisher.rb9
-rw-r--r--railties/lib/rails/backtrace_cleaner.rb2
-rw-r--r--railties/lib/rails/commands/console.rb12
-rw-r--r--railties/lib/rails/generators/app_base.rb6
-rw-r--r--railties/lib/rails/generators/erb/mailer/mailer_generator.rb7
-rw-r--r--railties/lib/rails/generators/erb/mailer/templates/layout.html.erb.tt13
-rw-r--r--railties/lib/rails/generators/erb/mailer/templates/layout.text.erb.tt1
-rw-r--r--railties/lib/rails/generators/rails/app/app_generator.rb10
-rw-r--r--railties/lib/rails/generators/rails/app/templates/app/assets/config/manifest.js.tt2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/app/channels/application_cable/channel.rb1
-rw-r--r--railties/lib/rails/generators/rails/app/templates/app/channels/application_cable/connection.rb1
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt3
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults.rb.tt55
-rw-r--r--railties/lib/rails/generators/rails/app/templates/public/robots.txt4
-rw-r--r--railties/lib/rails/generators/rails/plugin/plugin_generator.rb2
-rw-r--r--railties/lib/rails/generators/test_unit/scaffold/templates/api_functional_test.rb10
-rw-r--r--railties/lib/rails/source_annotation_extractor.rb6
-rw-r--r--railties/lib/rails/tasks/framework.rake8
-rw-r--r--railties/test/application/assets_test.rb2
-rw-r--r--railties/test/application/routing_test.rb19
-rw-r--r--railties/test/backtrace_cleaner_test.rb24
-rw-r--r--railties/test/generators/app_generator_test.rb108
-rw-r--r--railties/test/generators/mailer_generator_test.rb8
-rw-r--r--railties/test/generators/model_generator_test.rb14
-rw-r--r--railties/test/generators/namespaced_generators_test.rb12
-rw-r--r--railties/test/generators/plugin_generator_test.rb96
-rw-r--r--railties/test/generators/resource_generator_test.rb4
-rw-r--r--railties/test/generators/scaffold_controller_generator_test.rb4
-rw-r--r--railties/test/generators/scaffold_generator_test.rb6
-rw-r--r--railties/test/generators/shared_generator_tests.rb35
-rw-r--r--railties/test/isolation/abstract_unit.rb1
-rw-r--r--railties/test/rails_info_controller_test.rb6
-rw-r--r--railties/test/railties/engine_test.rb6
-rw-r--r--tasks/release.rb40
298 files changed, 3157 insertions, 6779 deletions
diff --git a/.codeclimate.yml b/.codeclimate.yml
new file mode 100644
index 0000000000..877c67873d
--- /dev/null
+++ b/.codeclimate.yml
@@ -0,0 +1,27 @@
+engines:
+ rubocop:
+ enabled: true
+
+ratings:
+ paths:
+ - "**.rb"
+
+exclude_paths:
+ - actioncable/lib/rails/generators/
+ - actioncable/test/
+ - actionmailer/lib/rails/generators/
+ - actionmailer/test/
+ - actionpack/test/
+ - actionview/test/
+ - activejob/lib/rails/generators/
+ - activejob/test/
+ - activemodel/test/
+ - activerecord/lib/rails/generators/
+ - activerecord/test/
+ - activesupport/test/
+ - railties/lib/rails/generators/
+ - railties/test/
+ - ci/
+ - guides/
+ - tasks/
+ - tools/
diff --git a/.rubocop.yml b/.rubocop.yml
new file mode 100644
index 0000000000..dd8db6af3a
--- /dev/null
+++ b/.rubocop.yml
@@ -0,0 +1,27 @@
+AllCops:
+ TargetRubyVersion: 2.3
+ DisabledByDefault: true
+
+# Two spaces, no tabs (for indentation).
+Style/IndentationWidth:
+ enabled: true
+
+# No trailing whitespace.
+Style/TrailingWhitespace:
+ enabled: true
+
+# Blank lines should not have any spaces.
+Style/TrailingBlankLines:
+ enabled: true
+
+# Use Ruby >= 1.9 syntax for hashes. Prefer { a: :b } over { :a => :b }.
+Style/HashSyntax:
+ enabled: true
+
+# Prefer &&/|| over and/or.
+Style/AndOr:
+ enabled: true
+
+# Use my_method(my_arg) not my_method( my_arg ) or my_method my_arg.
+Lint/RequireParentheses:
+ enabled: true
diff --git a/.travis.yml b/.travis.yml
index 461bd172c1..f01b58ecb3 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -16,11 +16,7 @@ addons:
postgresql: "9.4"
bundler_args: --without test --jobs 3 --retry 3
-#FIXME: Remove bundler uninstall on Travis when https://github.com/bundler/bundler/issues/4493 is fixed.
before_install:
- - rvm @global do gem uninstall bundler --all --ignore-dependencies --executables
- - rvm @global do gem install bundler -v '1.11.2'
- - bundle --version
- "rm ${BUNDLE_GEMFILE}.lock"
- "[ -f /tmp/beanstalkd-1.10/Makefile ] || (curl -L https://github.com/kr/beanstalkd/archive/v1.10.tar.gz | tar xz -C /tmp)"
- "pushd /tmp/beanstalkd-1.10 && make && (./beanstalkd &); popd"
@@ -88,6 +84,3 @@ notifications:
on_failure: always
rooms:
- secure: "YA1alef1ESHWGFNVwvmVGCkMe4cUy4j+UcNvMUESraceiAfVyRMAovlQBGs6\n9kBRm7DHYBUXYC2ABQoJbQRLDr/1B5JPf/M8+Qd7BKu8tcDC03U01SMHFLpO\naOs/HLXcDxtnnpL07tGVsm0zhMc5N8tq4/L3SHxK7Vi+TacwQzI="
-
-git:
- depth: 1
diff --git a/Gemfile b/Gemfile
index c851d32dea..1d58c413ed 100644
--- a/Gemfile
+++ b/Gemfile
@@ -11,8 +11,9 @@ gem 'mocha', '~> 0.14', require: false
gem 'rack-cache', '~> 1.2'
gem 'jquery-rails'
-gem 'coffee-rails', github: 'rails/coffee-rails'
-gem 'turbolinks', github: 'turbolinks/turbolinks-rails'
+gem 'coffee-rails'
+gem 'sass-rails'
+gem 'turbolinks', '~> 5'
# require: false so bcrypt is loaded only when has_secure_password is used.
# This is to avoid Active Model (and by extension the entire framework)
@@ -68,8 +69,8 @@ group :cable do
# Lock to 1.1.1 until the fix for https://github.com/faye/faye/issues/394 is released
gem 'faye', '1.1.1', require: false
- gem 'blade', '~> 0.5.5', require: false
- gem 'blade-sauce_labs_plugin', '~> 0.5.1', require: false
+ gem 'blade', require: false
+ gem 'blade-sauce_labs_plugin', require: false
end
# Add your own local bundler stuff.
@@ -89,7 +90,7 @@ group :test do
end
platforms :ruby, :mswin, :mswin64, :mingw, :x64_mingw do
- gem 'nokogiri', '>= 1.6.7.1'
+ gem 'nokogiri', '>= 1.6.8'
# Needed for compiling the ActionDispatch::Journey parser.
gem 'racc', '>=1.4.6', require: false
diff --git a/Gemfile.lock b/Gemfile.lock
index ed325aef55..a62a71521e 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -22,27 +22,12 @@ GIT
delayed_job (>= 3.0, < 5)
GIT
- remote: git://github.com/rails/coffee-rails.git
- revision: aa2e623cbda4f3c789a0a15d1f707239e68f5736
- specs:
- coffee-rails (4.1.1)
- coffee-script (>= 2.2.0)
- railties (>= 4.0.0, < 5.2.x)
-
-GIT
remote: git://github.com/sass/sass.git
revision: 3fda1cbe70d615e7ef96e28db4fd1f8a3ebb5505
branch: stable
specs:
sass (3.4.22)
-GIT
- remote: git://github.com/turbolinks/turbolinks-rails.git
- revision: 65884729016dbb4d032f12bb01b7e7c1ddeb68ac
- specs:
- turbolinks (5.0.0.beta2)
- turbolinks-source
-
PATH
remote: .
specs:
@@ -59,7 +44,7 @@ PATH
actionpack (5.1.0.alpha)
actionview (= 5.1.0.alpha)
activesupport (= 5.1.0.alpha)
- rack (~> 2.x)
+ rack (~> 2.0)
rack-test (~> 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.2)
@@ -116,7 +101,7 @@ GEM
bcrypt (3.1.11-x86-mingw32)
beaneater (1.0.0)
benchmark-ips (2.6.1)
- blade (0.5.5)
+ blade (0.5.6)
activesupport (>= 3.0.0)
blade-qunit_adapter (~> 1.20.0)
coffee-script
@@ -126,11 +111,11 @@ GEM
faye
sprockets (>= 3.0)
sprockets-export (~> 0.9.1)
- thin (~> 1.6.0)
+ thin (>= 1.6.0)
thor (~> 0.19.1)
useragent (~> 0.16.7)
blade-qunit_adapter (1.20.0)
- blade-sauce_labs_plugin (0.5.1)
+ blade-sauce_labs_plugin (0.5.2)
childprocess
faraday
selenium-webdriver
@@ -140,6 +125,9 @@ GEM
byebug (8.2.5)
childprocess (0.5.9)
ffi (~> 1.0, >= 1.0.11)
+ coffee-rails (4.2.1)
+ coffee-script (>= 2.2.0)
+ railties (>= 4.0.0, < 5.2.x)
coffee-script (2.4.1)
coffee-script-source
execjs
@@ -166,7 +154,7 @@ GEM
eventmachine (1.2.0.1)
eventmachine (1.2.0.1-x64-mingw32)
eventmachine (1.2.0.1-x86-mingw32)
- execjs (2.6.0)
+ execjs (2.7.0)
faraday (0.9.2)
multipart-post (>= 1.2, < 3)
faye (1.1.1)
@@ -208,7 +196,7 @@ GEM
mime-types (3.0)
mime-types-data (~> 3.2015)
mime-types-data (3.2016.0221)
- mini_portile2 (2.0.0)
+ mini_portile2 (2.1.0)
minitest (5.3.3)
mocha (0.14.0)
metaclass (~> 0.0.1)
@@ -220,16 +208,20 @@ GEM
mysql2 (0.4.4-x64-mingw32)
mysql2 (0.4.4-x86-mingw32)
nio4r (1.2.1)
- nokogiri (1.6.7.2)
- mini_portile2 (~> 2.0.0.rc2)
- nokogiri (1.6.7.2-x64-mingw32)
- mini_portile2 (~> 2.0.0.rc2)
- nokogiri (1.6.7.2-x86-mingw32)
- mini_portile2 (~> 2.0.0.rc2)
+ nokogiri (1.6.8)
+ mini_portile2 (~> 2.1.0)
+ pkg-config (~> 1.1.7)
+ nokogiri (1.6.8-x64-mingw32)
+ mini_portile2 (~> 2.1.0)
+ pkg-config (~> 1.1.7)
+ nokogiri (1.6.8-x86-mingw32)
+ mini_portile2 (~> 2.1.0)
+ pkg-config (~> 1.1.7)
pg (0.18.4)
pg (0.18.4-x64-mingw32)
pg (0.18.4-x86-mingw32)
- psych (2.0.17)
+ pkg-config (1.1.7)
+ psych (2.1.0)
puma (3.4.0)
qu (0.2.0)
multi_json
@@ -239,8 +231,7 @@ GEM
simple_uuid
que (0.11.4)
racc (1.4.14)
- rack (2.0.0.rc1)
- json
+ rack (2.0.1)
rack-cache (1.6.1)
rack (>= 0.4)
rack-test (0.6.3)
@@ -273,6 +264,12 @@ GEM
rufus-scheduler (~> 3.2)
rubyzip (1.2.0)
rufus-scheduler (3.2.1)
+ sass-rails (5.0.5)
+ railties (>= 4.0.0, < 6)
+ sass (~> 3.1)
+ sprockets (>= 2.8, < 4.0)
+ sprockets-rails (>= 2.0, < 4.0)
+ tilt (>= 1.1, < 3)
sdoc (0.4.1)
json (~> 1.7, >= 1.7.7)
rdoc (~> 4.0)
@@ -296,11 +293,11 @@ GEM
serverengine (~> 1.5.11)
thor
thread (~> 0.1.7)
- sprockets (3.6.0)
+ sprockets (3.6.1)
concurrent-ruby (~> 1.0)
rack (> 1, < 3)
sprockets-export (0.9.1)
- sprockets-rails (3.0.4)
+ sprockets-rails (3.1.1)
actionpack (>= 4.0)
activesupport (>= 4.0)
sprockets (>= 3.0.0)
@@ -310,14 +307,17 @@ GEM
stackprof (0.2.9)
sucker_punch (2.0.2)
concurrent-ruby (~> 1.0.0)
- thin (1.6.2)
- daemons (>= 1.0.9)
- eventmachine (>= 1.0.0)
- rack (>= 1.0.0)
+ thin (1.7.0)
+ daemons (~> 1.0, >= 1.0.9)
+ eventmachine (~> 1.0, >= 1.0.4)
+ rack (>= 1, < 3)
thor (0.19.1)
thread (0.1.7)
thread_safe (0.3.5)
- turbolinks-source (5.0.0.beta4)
+ tilt (2.0.5)
+ turbolinks (5.0.0)
+ turbolinks-source (~> 5)
+ turbolinks-source (5.0.0)
tzinfo (1.2.2)
thread_safe (~> 0.1)
tzinfo-data (1.2016.4)
@@ -348,10 +348,10 @@ DEPENDENCIES
backburner
bcrypt (~> 3.1.11)
benchmark-ips
- blade (~> 0.5.5)
- blade-sauce_labs_plugin (~> 0.5.1)
+ blade
+ blade-sauce_labs_plugin
byebug
- coffee-rails!
+ coffee-rails
dalli (>= 2.2.1)
delayed_job!
delayed_job_active_record!
@@ -365,7 +365,7 @@ DEPENDENCIES
minitest (< 5.3.4)
mocha (~> 0.14)
mysql2 (>= 0.4.4)
- nokogiri (>= 1.6.7.1)
+ nokogiri (>= 1.6.8)
pg (>= 0.18.0)
psych (~> 2.0)
puma
@@ -381,6 +381,7 @@ DEPENDENCIES
resque (< 1.26)
resque-scheduler
sass!
+ sass-rails
sdoc (~> 0.4.0)
sequel
sidekiq
@@ -388,7 +389,7 @@ DEPENDENCIES
sqlite3 (~> 1.3.6)
stackprof
sucker_punch
- turbolinks!
+ turbolinks (~> 5)
tzinfo-data
uglifier (>= 1.3.0)
w3c_validators
diff --git a/actioncable/CHANGELOG.md b/actioncable/CHANGELOG.md
index a767857607..9aee32ddb4 100644
--- a/actioncable/CHANGELOG.md
+++ b/actioncable/CHANGELOG.md
@@ -1,2 +1,5 @@
+* Add ActiveSupport::Notifications hook to Broadcaster#broadcast
+
+ *Matthew Wear*
Please check [5-0-stable](https://github.com/rails/rails/blob/5-0-stable/actioncable/CHANGELOG.md) for previous changes.
diff --git a/actioncable/README.md b/actioncable/README.md
index fa6a3ed0df..28e2602cbf 100644
--- a/actioncable/README.md
+++ b/actioncable/README.md
@@ -7,7 +7,6 @@ and scalable. It's a full-stack offering that provides both a client-side
JavaScript framework and a server-side Ruby framework. You have access to your full
domain model written with Active Record or your ORM of choice.
-
## Terminology
A single Action Cable server can handle multiple connection instances. It has one
@@ -300,7 +299,6 @@ The rebroadcast will be received by all connected clients, _including_ the clien
See the [rails/actioncable-examples](https://github.com/rails/actioncable-examples) repository for a full example of how to setup Action Cable in a Rails app, and how to add channels.
-
## Configuration
Action Cable has three required configurations: a subscription adapter, allowed request origins, and the cable server URL (which can optionally be set on the client side).
@@ -378,11 +376,11 @@ App.cable = ActionCable.createConsumer()
### Other Configurations
-The other common option to configure is the log tags applied to the per-connection logger. Here's close to what we're using in Basecamp:
+The other common option to configure is the log tags applied to the per-connection logger. Here's an example that uses the user account id if available, else "no-account" while tagging:
```ruby
-Rails.application.config.action_cable.log_tags = [
- -> request { request.env['bc.account_id'] || "no-account" },
+config.action_cable.log_tags = [
+ -> request { request.env['user_account_id'] || "no-account" },
:action_cable,
-> request { request.uuid }
]
@@ -460,6 +458,74 @@ with all the popular application servers -- Unicorn, Puma and Passenger.
Action Cable does not work with WEBrick, because WEBrick does not support the
Rack socket hijacking API.
+## Frontend assets
+
+Action Cable's frontend assets are distributed through two channels: the
+official gem and npm package, both titled `actioncable`.
+
+### Gem usage
+
+Through the `actioncable` gem, Action Cable's frontend assets are
+available through the Rails Asset Pipeline. Create a `cable.js` or
+`cable.coffee` file (this is automatically done for you with Rails
+generators), and then simply require the assets:
+
+In JavaScript...
+
+```javascript
+//= require action_cable
+```
+
+... and in CoffeeScript:
+
+```coffeescript
+#= require action_cable
+```
+
+### npm usage
+
+In addition to being available through the `actioncable` gem, Action Cable's
+frontend JS assets are also bundled in an officially supported npm module,
+intended for usage in standalone frontend applications that communicate with a
+Rails application. A common use case for this could be if you have a decoupled
+frontend application written in React, Ember.js, etc. and want to add real-time
+WebSocket functionality.
+
+### Installation
+
+```
+npm install actioncable --save
+```
+
+### Usage
+
+The `ActionCable` constant is available as a `require`-able module, so
+you only have to require the package to gain access to the API that is
+provided.
+
+In JavaScript...
+
+```javascript
+ActionCable = require('actioncable')
+
+var cable = ActionCable.createConsumer('wss://RAILS-API-PATH.com/cable')
+
+cable.subscriptions.create('AppearanceChannel', {
+ // normal channel code goes here...
+});
+```
+
+and in CoffeeScript...
+
+```coffeescript
+ActionCable = require('actioncable')
+
+cable = ActionCable.createConsumer('wss://RAILS-API-PATH.com/cable')
+
+cable.subscriptions.create 'AppearanceChannel',
+ # normal channel code goes here...
+```
+
## License
Action Cable is released under the MIT license:
diff --git a/actioncable/lib/action_cable/channel/periodic_timers.rb b/actioncable/lib/action_cable/channel/periodic_timers.rb
index dab604440f..41511312fc 100644
--- a/actioncable/lib/action_cable/channel/periodic_timers.rb
+++ b/actioncable/lib/action_cable/channel/periodic_timers.rb
@@ -64,9 +64,7 @@ module ActionCable
def start_periodic_timer(callback, every:)
connection.server.event_loop.timer every do
- connection.worker_pool.async_invoke connection do
- instance_exec(&callback)
- end
+ connection.worker_pool.async_exec self, connection: connection, &callback
end
end
diff --git a/actioncable/lib/action_cable/connection/stream.rb b/actioncable/lib/action_cable/connection/stream.rb
index 0cf59091bc..c250cf92fc 100644
--- a/actioncable/lib/action_cable/connection/stream.rb
+++ b/actioncable/lib/action_cable/connection/stream.rb
@@ -50,6 +50,7 @@ module ActionCable
def clean_rack_hijack
return unless @rack_hijack_io
@event_loop.detach(@rack_hijack_io, self)
+ @rack_hijack_io.close
@rack_hijack_io = nil
end
end
diff --git a/actioncable/lib/action_cable/connection/subscriptions.rb b/actioncable/lib/action_cable/connection/subscriptions.rb
index 3742f248d1..6051818bfb 100644
--- a/actioncable/lib/action_cable/connection/subscriptions.rb
+++ b/actioncable/lib/action_cable/connection/subscriptions.rb
@@ -26,12 +26,12 @@ module ActionCable
id_key = data['identifier']
id_options = ActiveSupport::JSON.decode(id_key).with_indifferent_access
- subscription_klass = connection.server.channel_classes[id_options[:channel]]
+ subscription_klass = id_options[:channel].safe_constantize
- if subscription_klass
+ if subscription_klass && ActionCable::Channel::Base >= subscription_klass
subscriptions[id_key] ||= subscription_klass.new(connection, id_key, id_options)
else
- logger.error "Subscription class not found (#{data.inspect})"
+ logger.error "Subscription class not found: #{id_options[:channel].inspect}"
end
end
diff --git a/actioncable/lib/action_cable/engine.rb b/actioncable/lib/action_cable/engine.rb
index 8ce1b24962..34f9952c71 100644
--- a/actioncable/lib/action_cable/engine.rb
+++ b/actioncable/lib/action_cable/engine.rb
@@ -22,7 +22,7 @@ module ActionCable
initializer "action_cable.set_configs" do |app|
options = app.config.action_cable
- options.allowed_request_origins ||= "http://localhost:3000" if ::Rails.env.development?
+ options.allowed_request_origins ||= /https?:\/\/localhost:\d+/ if ::Rails.env.development?
app.paths.add "config/cable", with: "config/cable.yml"
@@ -31,11 +31,8 @@ module ActionCable
self.cable = Rails.application.config_for(config_path).with_indifferent_access
end
- if 'ApplicationCable::Connection'.safe_constantize
- self.connection_class = ApplicationCable::Connection
- end
-
- self.channel_paths = Rails.application.paths['app/channels'].existent
+ previous_connection_class = self.connection_class
+ self.connection_class = -> { 'ApplicationCable::Connection'.safe_constantize || previous_connection_class.call }
options.each { |k,v| send("#{k}=", v) }
end
diff --git a/actioncable/lib/action_cable/server/base.rb b/actioncable/lib/action_cable/server/base.rb
index 717a60fe4f..0ad1e408a9 100644
--- a/actioncable/lib/action_cable/server/base.rb
+++ b/actioncable/lib/action_cable/server/base.rb
@@ -19,13 +19,13 @@ module ActionCable
def initialize
@mutex = Monitor.new
- @remote_connections = @event_loop = @worker_pool = @channel_classes = @pubsub = nil
+ @remote_connections = @event_loop = @worker_pool = @pubsub = nil
end
# Called by Rack to setup the server.
def call(env)
setup_heartbeat_timer
- config.connection_class.new(self, env).process
+ config.connection_class.call.new(self, env).process
end
# Disconnect all the connections identified by `identifiers` on this server or any others via RemoteConnections.
@@ -67,16 +67,6 @@ module ActionCable
@worker_pool || @mutex.synchronize { @worker_pool ||= ActionCable::Server::Worker.new(max_size: config.worker_pool_size) }
end
- # Requires and returns a hash of all of the channel class constants, which are keyed by name.
- def channel_classes
- @channel_classes || @mutex.synchronize do
- @channel_classes ||= begin
- config.channel_paths.each { |channel_path| require channel_path }
- config.channel_class_names.each_with_object({}) { |name, hash| hash[name] = name.constantize }
- end
- end
- end
-
# Adapter used for all streams/broadcasting.
def pubsub
@pubsub || @mutex.synchronize { @pubsub ||= config.pubsub_adapter.new(self) }
@@ -84,7 +74,7 @@ module ActionCable
# All of the identifiers applied to the connection class associated with this server.
def connection_identifiers
- config.connection_class.identifiers
+ config.connection_class.call.identifiers
end
end
diff --git a/actioncable/lib/action_cable/server/broadcasting.rb b/actioncable/lib/action_cable/server/broadcasting.rb
index 8f93564113..1fc58baa3e 100644
--- a/actioncable/lib/action_cable/server/broadcasting.rb
+++ b/actioncable/lib/action_cable/server/broadcasting.rb
@@ -39,8 +39,12 @@ module ActionCable
def broadcast(message)
server.logger.info "[ActionCable] Broadcasting to #{broadcasting}: #{message.inspect}"
- encoded = coder ? coder.encode(message) : message
- server.pubsub.broadcast broadcasting, encoded
+
+ payload = { broadcasting: broadcasting, message: message, coder: coder }
+ ActiveSupport::Notifications.instrument("broadcast.action_cable", payload) do
+ encoded = coder ? coder.encode(message) : message
+ server.pubsub.broadcast broadcasting, encoded
+ end
end
end
end
diff --git a/actioncable/lib/action_cable/server/configuration.rb b/actioncable/lib/action_cable/server/configuration.rb
index 0bb378cf03..ada1ac22cc 100644
--- a/actioncable/lib/action_cable/server/configuration.rb
+++ b/actioncable/lib/action_cable/server/configuration.rb
@@ -8,23 +8,15 @@ module ActionCable
attr_accessor :disable_request_forgery_protection, :allowed_request_origins
attr_accessor :cable, :url, :mount_path
- attr_accessor :channel_paths # :nodoc:
-
def initialize
@log_tags = []
- @connection_class = ActionCable::Connection::Base
+ @connection_class = -> { ActionCable::Connection::Base }
@worker_pool_size = 4
@disable_request_forgery_protection = false
end
- def channel_class_names
- @channel_class_names ||= channel_paths.collect do |channel_path|
- Pathname.new(channel_path).basename.to_s.split('.').first.camelize
- end
- end
-
# Returns constant of subscription adapter specified in config/cable.yml.
# If the adapter cannot be found, this will default to the Redis adapter.
# Also makes sure proper dependencies are required.
diff --git a/actioncable/lib/action_cable/server/worker.rb b/actioncable/lib/action_cable/server/worker.rb
index a638ff72e7..f3a4fc5a5b 100644
--- a/actioncable/lib/action_cable/server/worker.rb
+++ b/actioncable/lib/action_cable/server/worker.rb
@@ -42,16 +42,20 @@ module ActionCable
self.connection = nil
end
- def async_invoke(receiver, method, *args, connection: receiver)
+ def async_exec(receiver, *args, connection:, &block)
+ async_invoke receiver, :instance_exec, *args, connection: connection, &block
+ end
+
+ def async_invoke(receiver, method, *args, connection: receiver, &block)
@executor.post do
- invoke(receiver, method, *args, connection: connection)
+ invoke(receiver, method, *args, connection: connection, &block)
end
end
- def invoke(receiver, method, *args, connection:)
+ def invoke(receiver, method, *args, connection:, &block)
work(connection) do
begin
- receiver.send method, *args
+ receiver.send method, *args, &block
rescue Exception => e
logger.error "There was an exception - #{e.class}(#{e.message})"
logger.error e.backtrace.join("\n")
diff --git a/actioncable/lib/action_cable/subscription_adapter/subscriber_map.rb b/actioncable/lib/action_cable/subscription_adapter/subscriber_map.rb
index 37eed09793..4ec513e3ba 100644
--- a/actioncable/lib/action_cable/subscription_adapter/subscriber_map.rb
+++ b/actioncable/lib/action_cable/subscription_adapter/subscriber_map.rb
@@ -32,7 +32,11 @@ module ActionCable
end
def broadcast(channel, message)
- list = @sync.synchronize { @subscribers[channel].dup }
+ list = @sync.synchronize do
+ return if !@subscribers.key?(channel)
+ @subscribers[channel].dup
+ end
+
list.each do |subscriber|
invoke_callback(subscriber, message)
end
diff --git a/actioncable/lib/rails/generators/channel/templates/application_cable/channel.rb b/actioncable/lib/rails/generators/channel/templates/application_cable/channel.rb
index 17a85f60f9..d672697283 100644
--- a/actioncable/lib/rails/generators/channel/templates/application_cable/channel.rb
+++ b/actioncable/lib/rails/generators/channel/templates/application_cable/channel.rb
@@ -1,5 +1,3 @@
-# Be sure to restart your server when you modify this file. Action Cable runs in
-# a loop that does not support auto reloading.
module ApplicationCable
class Channel < ActionCable::Channel::Base
end
diff --git a/actioncable/lib/rails/generators/channel/templates/application_cable/connection.rb b/actioncable/lib/rails/generators/channel/templates/application_cable/connection.rb
index 93f28c4306..0ff5442f47 100644
--- a/actioncable/lib/rails/generators/channel/templates/application_cable/connection.rb
+++ b/actioncable/lib/rails/generators/channel/templates/application_cable/connection.rb
@@ -1,5 +1,3 @@
-# Be sure to restart your server when you modify this file. Action Cable runs in
-# a loop that does not support auto reloading.
module ApplicationCable
class Connection < ActionCable::Connection::Base
end
diff --git a/actioncable/lib/rails/generators/channel/templates/channel.rb b/actioncable/lib/rails/generators/channel/templates/channel.rb
index 7bff3341c1..4bcfb2be4d 100644
--- a/actioncable/lib/rails/generators/channel/templates/channel.rb
+++ b/actioncable/lib/rails/generators/channel/templates/channel.rb
@@ -1,4 +1,3 @@
-# Be sure to restart your server when you modify this file. Action Cable runs in a loop that does not support auto reloading.
<% module_namespacing do -%>
class <%= class_name %>Channel < ApplicationCable::Channel
def subscribed
diff --git a/actioncable/test/channel/stream_test.rb b/actioncable/test/channel/stream_test.rb
index 0b0c72ccf6..38543920d3 100644
--- a/actioncable/test/channel/stream_test.rb
+++ b/actioncable/test/channel/stream_test.rb
@@ -128,10 +128,6 @@ module ActionCable::StreamTests
setup do
@server = TestServer.new(subscription_adapter: ActionCable::SubscriptionAdapter::Inline)
@server.config.allowed_request_origins = %w( http://rubyonrails.com )
- @server.stubs(:channel_classes).returns(
- ChatChannel.name => ChatChannel,
- UserCallbackChannel.name => UserCallbackChannel,
- )
end
test 'custom encoder' do
diff --git a/actioncable/test/client/echo_channel.rb b/actioncable/test/client/echo_channel.rb
deleted file mode 100644
index 5a7bac25c5..0000000000
--- a/actioncable/test/client/echo_channel.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-class EchoChannel < ActionCable::Channel::Base
- def subscribed
- stream_from "global"
- end
-
- def unsubscribed
- 'Goodbye from EchoChannel!'
- end
-
- def ding(data)
- transmit(dong: data['message'])
- end
-
- def delay(data)
- sleep 1
- transmit(dong: data['message'])
- end
-
- def bulk(data)
- ActionCable.server.broadcast "global", wide: data['message']
- end
-end
diff --git a/actioncable/test/client_test.rb b/actioncable/test/client_test.rb
index fe503fd703..82d9f12fdd 100644
--- a/actioncable/test/client_test.rb
+++ b/actioncable/test/client_test.rb
@@ -1,27 +1,48 @@
require 'test_helper'
require 'concurrent'
-require 'active_support/core_ext/hash/indifferent_access'
-require 'pathname'
-
require 'faye/websocket'
require 'json'
+require 'active_support/hash_with_indifferent_access'
+
class ClientTest < ActionCable::TestCase
WAIT_WHEN_EXPECTING_EVENT = 8
WAIT_WHEN_NOT_EXPECTING_EVENT = 0.5
+ class EchoChannel < ActionCable::Channel::Base
+ def subscribed
+ stream_from "global"
+ end
+
+ def unsubscribed
+ 'Goodbye from EchoChannel!'
+ end
+
+ def ding(data)
+ transmit(dong: data['message'])
+ end
+
+ def delay(data)
+ sleep 1
+ transmit(dong: data['message'])
+ end
+
+ def bulk(data)
+ ActionCable.server.broadcast "global", wide: data['message']
+ end
+ end
+
def setup
ActionCable.instance_variable_set(:@server, nil)
server = ActionCable.server
server.config.logger = Logger.new(StringIO.new).tap { |l| l.level = Logger::UNKNOWN }
- server.config.cable = { adapter: 'async' }.with_indifferent_access
+ server.config.cable = ActiveSupport::HashWithIndifferentAccess.new(adapter: 'async')
server.config.use_faye = ENV['FAYE'].present?
# and now the "real" setup for our test:
server.config.disable_request_forgery_protection = true
- server.config.channel_paths = [ File.expand_path('client/echo_channel.rb', __dir__) ]
Thread.new { EventMachine.run } unless EventMachine.reactor_running?
Thread.pass until EventMachine.reactor_running?
@@ -148,10 +169,10 @@ class ClientTest < ActionCable::TestCase
with_puma_server do |port|
c = faye_client(port)
assert_equal({"type" => "welcome"}, c.read_message) # pop the first welcome message off the stack
- c.send_message command: 'subscribe', identifier: JSON.generate(channel: 'EchoChannel')
- assert_equal({"identifier"=>"{\"channel\":\"EchoChannel\"}", "type"=>"confirm_subscription"}, c.read_message)
- c.send_message command: 'message', identifier: JSON.generate(channel: 'EchoChannel'), data: JSON.generate(action: 'ding', message: 'hello')
- assert_equal({"identifier"=>"{\"channel\":\"EchoChannel\"}", "message"=>{"dong"=>"hello"}}, c.read_message)
+ c.send_message command: 'subscribe', identifier: JSON.generate(channel: 'ClientTest::EchoChannel')
+ assert_equal({"identifier"=>"{\"channel\":\"ClientTest::EchoChannel\"}", "type"=>"confirm_subscription"}, c.read_message)
+ c.send_message command: 'message', identifier: JSON.generate(channel: 'ClientTest::EchoChannel'), data: JSON.generate(action: 'ding', message: 'hello')
+ assert_equal({"identifier"=>"{\"channel\":\"ClientTest::EchoChannel\"}", "message"=>{"dong"=>"hello"}}, c.read_message)
c.close
end
end
@@ -165,12 +186,12 @@ class ClientTest < ActionCable::TestCase
clients.map {|c| Concurrent::Future.execute {
assert_equal({"type" => "welcome"}, c.read_message) # pop the first welcome message off the stack
- c.send_message command: 'subscribe', identifier: JSON.generate(channel: 'EchoChannel')
- assert_equal({"identifier"=>'{"channel":"EchoChannel"}', "type"=>"confirm_subscription"}, c.read_message)
- c.send_message command: 'message', identifier: JSON.generate(channel: 'EchoChannel'), data: JSON.generate(action: 'ding', message: 'hello')
- assert_equal({"identifier"=>'{"channel":"EchoChannel"}', "message"=>{"dong"=>"hello"}}, c.read_message)
+ c.send_message command: 'subscribe', identifier: JSON.generate(channel: 'ClientTest::EchoChannel')
+ assert_equal({"identifier"=>'{"channel":"ClientTest::EchoChannel"}', "type"=>"confirm_subscription"}, c.read_message)
+ c.send_message command: 'message', identifier: JSON.generate(channel: 'ClientTest::EchoChannel'), data: JSON.generate(action: 'ding', message: 'hello')
+ assert_equal({"identifier"=>'{"channel":"ClientTest::EchoChannel"}', "message"=>{"dong"=>"hello"}}, c.read_message)
barrier_1.wait WAIT_WHEN_EXPECTING_EVENT
- c.send_message command: 'message', identifier: JSON.generate(channel: 'EchoChannel'), data: JSON.generate(action: 'bulk', message: 'hello')
+ c.send_message command: 'message', identifier: JSON.generate(channel: 'ClientTest::EchoChannel'), data: JSON.generate(action: 'bulk', message: 'hello')
barrier_2.wait WAIT_WHEN_EXPECTING_EVENT
assert_equal clients.size, c.read_messages(clients.size).size
} }.each(&:wait!)
@@ -185,10 +206,10 @@ class ClientTest < ActionCable::TestCase
clients.map {|c| Concurrent::Future.execute {
assert_equal({"type" => "welcome"}, c.read_message) # pop the first welcome message off the stack
- c.send_message command: 'subscribe', identifier: JSON.generate(channel: 'EchoChannel')
- assert_equal({"identifier"=>'{"channel":"EchoChannel"}', "type"=>"confirm_subscription"}, c.read_message)
- c.send_message command: 'message', identifier: JSON.generate(channel: 'EchoChannel'), data: JSON.generate(action: 'ding', message: 'hello')
- assert_equal({"identifier"=>'{"channel":"EchoChannel"}', "message"=>{"dong"=>"hello"}}, c.read_message)
+ c.send_message command: 'subscribe', identifier: JSON.generate(channel: 'ClientTest::EchoChannel')
+ assert_equal({"identifier"=>'{"channel":"ClientTest::EchoChannel"}', "type"=>"confirm_subscription"}, c.read_message)
+ c.send_message command: 'message', identifier: JSON.generate(channel: 'ClientTest::EchoChannel'), data: JSON.generate(action: 'ding', message: 'hello')
+ assert_equal({"identifier"=>'{"channel":"ClientTest::EchoChannel"}', "message"=>{"dong"=>"hello"}}, c.read_message)
} }.each(&:wait!)
clients.map {|c| Concurrent::Future.execute { c.close } }.each(&:wait!)
@@ -199,17 +220,17 @@ class ClientTest < ActionCable::TestCase
with_puma_server do |port|
c = faye_client(port)
assert_equal({"type" => "welcome"}, c.read_message) # pop the first welcome message off the stack
- c.send_message command: 'subscribe', identifier: JSON.generate(channel: 'EchoChannel')
- assert_equal({"identifier"=>"{\"channel\":\"EchoChannel\"}", "type"=>"confirm_subscription"}, c.read_message)
- c.send_message command: 'message', identifier: JSON.generate(channel: 'EchoChannel'), data: JSON.generate(action: 'delay', message: 'hello')
+ c.send_message command: 'subscribe', identifier: JSON.generate(channel: 'ClientTest::EchoChannel')
+ assert_equal({"identifier"=>"{\"channel\":\"ClientTest::EchoChannel\"}", "type"=>"confirm_subscription"}, c.read_message)
+ c.send_message command: 'message', identifier: JSON.generate(channel: 'ClientTest::EchoChannel'), data: JSON.generate(action: 'delay', message: 'hello')
c.close # disappear before write
c = faye_client(port)
assert_equal({"type" => "welcome"}, c.read_message) # pop the first welcome message off the stack
- c.send_message command: 'subscribe', identifier: JSON.generate(channel: 'EchoChannel')
- assert_equal({"identifier"=>"{\"channel\":\"EchoChannel\"}", "type"=>"confirm_subscription"}, c.read_message)
- c.send_message command: 'message', identifier: JSON.generate(channel: 'EchoChannel'), data: JSON.generate(action: 'ding', message: 'hello')
- assert_equal({"identifier"=>'{"channel":"EchoChannel"}', "message"=>{"dong"=>"hello"}}, c.read_message)
+ c.send_message command: 'subscribe', identifier: JSON.generate(channel: 'ClientTest::EchoChannel')
+ assert_equal({"identifier"=>"{\"channel\":\"ClientTest::EchoChannel\"}", "type"=>"confirm_subscription"}, c.read_message)
+ c.send_message command: 'message', identifier: JSON.generate(channel: 'ClientTest::EchoChannel'), data: JSON.generate(action: 'ding', message: 'hello')
+ assert_equal({"identifier"=>'{"channel":"ClientTest::EchoChannel"}', "message"=>{"dong"=>"hello"}}, c.read_message)
c.close # disappear before read
end
end
@@ -217,12 +238,12 @@ class ClientTest < ActionCable::TestCase
def test_unsubscribe_client
with_puma_server do |port|
app = ActionCable.server
- identifier = JSON.generate(channel: 'EchoChannel')
+ identifier = JSON.generate(channel: 'ClientTest::EchoChannel')
c = faye_client(port)
assert_equal({"type" => "welcome"}, c.read_message)
c.send_message command: 'subscribe', identifier: identifier
- assert_equal({"identifier"=>"{\"channel\":\"EchoChannel\"}", "type"=>"confirm_subscription"}, c.read_message)
+ assert_equal({"identifier"=>"{\"channel\":\"ClientTest::EchoChannel\"}", "type"=>"confirm_subscription"}, c.read_message)
assert_equal(1, app.connections.count)
assert(app.remote_connections.where(identifier: identifier))
@@ -242,8 +263,8 @@ class ClientTest < ActionCable::TestCase
with_puma_server do |port|
c = faye_client(port)
assert_equal({"type" => "welcome"}, c.read_message)
- c.send_message command: 'subscribe', identifier: JSON.generate(channel: 'EchoChannel')
- assert_equal({"identifier"=>"{\"channel\":\"EchoChannel\"}", "type"=>"confirm_subscription"}, c.read_message)
+ c.send_message command: 'subscribe', identifier: JSON.generate(channel: 'ClientTest::EchoChannel')
+ assert_equal({"identifier"=>"{\"channel\":\"ClientTest::EchoChannel\"}", "type"=>"confirm_subscription"}, c.read_message)
ActionCable.server.restart
c.wait_for_close
diff --git a/actioncable/test/connection/client_socket_test.rb b/actioncable/test/connection/client_socket_test.rb
index 4af071b4da..fe9077ae7f 100644
--- a/actioncable/test/connection/client_socket_test.rb
+++ b/actioncable/test/connection/client_socket_test.rb
@@ -48,6 +48,20 @@ class ActionCable::Connection::ClientSocketTest < ActionCable::TestCase
end
end
+ test 'closes hijacked i/o socket at shutdown' do
+ skip if ENV['FAYE'].present?
+
+ run_in_eventmachine do
+ connection = open_connection
+
+ client = connection.websocket.send(:websocket)
+ client.instance_variable_get('@stream')
+ .instance_variable_get('@rack_hijack_io')
+ .expects(:close)
+ connection.close
+ end
+ end
+
private
def open_connection
env = Rack::MockRequest.env_for '/test',
diff --git a/actioncable/test/connection/subscriptions_test.rb b/actioncable/test/connection/subscriptions_test.rb
index 53e8547245..a5b1e5dcf3 100644
--- a/actioncable/test/connection/subscriptions_test.rb
+++ b/actioncable/test/connection/subscriptions_test.rb
@@ -24,7 +24,6 @@ class ActionCable::Connection::SubscriptionsTest < ActionCable::TestCase
setup do
@server = TestServer.new
- @server.stubs(:channel_classes).returns(ChatChannel.name => ChatChannel)
@chat_identifier = ActiveSupport::JSON.encode(id: 1, channel: 'ActionCable::Connection::SubscriptionsTest::ChatChannel')
end
diff --git a/actioncable/test/server/broadcasting_test.rb b/actioncable/test/server/broadcasting_test.rb
index 3b4a7eaf90..ed377b7d5d 100644
--- a/actioncable/test/server/broadcasting_test.rb
+++ b/actioncable/test/server/broadcasting_test.rb
@@ -1,10 +1,7 @@
require "test_helper"
+require "stubs/test_server"
class BroadcastingTest < ActiveSupport::TestCase
- class TestServer
- include ActionCable::Server::Broadcasting
- end
-
test "fetching a broadcaster converts the broadcasting queue to a string" do
broadcasting = :test_queue
server = TestServer.new
@@ -12,4 +9,52 @@ class BroadcastingTest < ActiveSupport::TestCase
assert_equal "test_queue", broadcaster.broadcasting
end
+
+ test "broadcast generates notification" do
+ begin
+ server = TestServer.new
+
+ events = []
+ ActiveSupport::Notifications.subscribe "broadcast.action_cable" do |*args|
+ events << ActiveSupport::Notifications::Event.new(*args)
+ end
+
+ broadcasting = "test_queue"
+ message = { body: "test message" }
+ server.broadcast(broadcasting, message)
+
+ assert_equal 1, events.length
+ assert_equal "broadcast.action_cable", events[0].name
+ assert_equal broadcasting, events[0].payload[:broadcasting]
+ assert_equal message, events[0].payload[:message]
+ assert_equal ActiveSupport::JSON, events[0].payload[:coder]
+ ensure
+ ActiveSupport::Notifications.unsubscribe "broadcast.action_cable"
+ end
+ end
+
+ test "broadcaster from broadcaster_for generates notification" do
+ begin
+ server = TestServer.new
+
+ events = []
+ ActiveSupport::Notifications.subscribe "broadcast.action_cable" do |*args|
+ events << ActiveSupport::Notifications::Event.new(*args)
+ end
+
+ broadcasting = "test_queue"
+ message = { body: "test message" }
+
+ broadcaster = server.broadcaster_for(broadcasting)
+ broadcaster.broadcast(message)
+
+ assert_equal 1, events.length
+ assert_equal "broadcast.action_cable", events[0].name
+ assert_equal broadcasting, events[0].payload[:broadcasting]
+ assert_equal message, events[0].payload[:message]
+ assert_equal ActiveSupport::JSON, events[0].payload[:coder]
+ ensure
+ ActiveSupport::Notifications.unsubscribe "broadcast.action_cable"
+ end
+ end
end
diff --git a/actioncable/test/subscription_adapter/subscriber_map_test.rb b/actioncable/test/subscription_adapter/subscriber_map_test.rb
new file mode 100644
index 0000000000..5965ac2b90
--- /dev/null
+++ b/actioncable/test/subscription_adapter/subscriber_map_test.rb
@@ -0,0 +1,17 @@
+require 'test_helper'
+
+class SubscriberMapTest < ActionCable::TestCase
+ test "broadcast should not change subscribers" do
+ setup_subscription_map
+ origin = @subscription_map.instance_variable_get(:@subscribers).dup
+
+ @subscription_map.broadcast('not_exist_channel', '')
+
+ assert_equal origin, @subscription_map.instance_variable_get(:@subscribers)
+ end
+
+ private
+ def setup_subscription_map
+ @subscription_map = ActionCable::SubscriptionAdapter::SubscriberMap.new
+ end
+end
diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb
index 6e0ae8a0a9..e766221008 100644
--- a/actionmailer/lib/action_mailer/base.rb
+++ b/actionmailer/lib/action_mailer/base.rb
@@ -390,9 +390,8 @@ module ActionMailer
# to use it. Defaults to <tt>true</tt>.
# * <tt>:openssl_verify_mode</tt> - When using TLS, you can set how OpenSSL checks the certificate. This is
# really useful if you need to validate a self-signed and/or a wildcard certificate. You can use the name
- # of an OpenSSL verify constant (<tt>'none'</tt>, <tt>'peer'</tt>, <tt>'client_once'</tt>,
- # <tt>'fail_if_no_peer_cert'</tt>) or directly the constant (<tt>OpenSSL::SSL::VERIFY_NONE</tt>,
- # <tt>OpenSSL::SSL::VERIFY_PEER</tt>, ...).
+ # of an OpenSSL verify constant (<tt>'none'</tt> or <tt>'peer'</tt>) or directly the constant
+ # (<tt>OpenSSL::SSL::VERIFY_NONE</tt> or <tt>OpenSSL::SSL::VERIFY_PEER</tt>).
# <tt>:ssl/:tls</tt> Enables the SMTP connection to use SMTP/TLS (SMTPS: SMTP over direct TLS connection)
#
# * <tt>sendmail_settings</tt> - Allows you to override options for the <tt>:sendmail</tt> delivery method.
diff --git a/actionpack/actionpack.gemspec b/actionpack/actionpack.gemspec
index 965fafff5f..f912a72efe 100644
--- a/actionpack/actionpack.gemspec
+++ b/actionpack/actionpack.gemspec
@@ -21,7 +21,7 @@ Gem::Specification.new do |s|
s.add_dependency 'activesupport', version
- s.add_dependency 'rack', '~> 2.x'
+ s.add_dependency 'rack', '~> 2.0'
s.add_dependency 'rack-test', '~> 0.6.3'
s.add_dependency 'rails-html-sanitizer', '~> 1.0', '>= 1.0.2'
s.add_dependency 'rails-dom-testing', '~> 2.0'
diff --git a/actionpack/lib/abstract_controller/base.rb b/actionpack/lib/abstract_controller/base.rb
index d4317399ed..aa06f70433 100644
--- a/actionpack/lib/abstract_controller/base.rb
+++ b/actionpack/lib/abstract_controller/base.rb
@@ -150,6 +150,13 @@ module AbstractController
_find_action_name(action_name)
end
+ # Tests if a response body is set. Used to determine if the
+ # +process_action+ callback needs to be terminated in
+ # +AbstractController::Callbacks+.
+ def performed?
+ response_body
+ end
+
# Returns true if the given controller is capable of rendering
# a path. A subclass of +AbstractController::Base+
# may return false. An Email controller for example does not
diff --git a/actionpack/lib/abstract_controller/callbacks.rb b/actionpack/lib/abstract_controller/callbacks.rb
index d63ce9c1c3..3ef8da86fa 100644
--- a/actionpack/lib/abstract_controller/callbacks.rb
+++ b/actionpack/lib/abstract_controller/callbacks.rb
@@ -9,7 +9,7 @@ module AbstractController
included do
define_callbacks :process_action,
- terminator: ->(controller, result_lambda) { result_lambda.call if result_lambda.is_a?(Proc); controller.response_body },
+ terminator: ->(controller, result_lambda) { result_lambda.call if result_lambda.is_a?(Proc); controller.performed? },
skip_after_callbacks_if_terminated: true
end
diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb
index a6fb0dbe1d..4ba2c26949 100644
--- a/actionpack/lib/abstract_controller/rendering.rb
+++ b/actionpack/lib/abstract_controller/rendering.rb
@@ -122,7 +122,7 @@ module AbstractController
def _normalize_render(*args, &block)
options = _normalize_args(*args, &block)
#TODO: remove defined? when we restore AP <=> AV dependency
- if defined?(request) && request.variant.present?
+ if defined?(request) && !request.nil? && request.variant.present?
options[:variant] = request.variant
end
_normalize_options(options)
diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb
index d546d7260c..251289d4bb 100644
--- a/actionpack/lib/action_controller/base.rb
+++ b/actionpack/lib/action_controller/base.rb
@@ -32,7 +32,7 @@ module ActionController
# new post), it initiates a redirect instead. This redirect works by returning an external
# "302 Moved" HTTP response that takes the user to the index action.
#
- # These two methods represent the two basic action archetypes used in Action Controllers. Get-and-show and do-and-redirect.
+ # These two methods represent the two basic action archetypes used in Action Controllers: Get-and-show and do-and-redirect.
# Most actions are variations on these themes.
#
# == Requests
@@ -51,8 +51,8 @@ module ActionController
# == Parameters
#
# All request parameters, whether they come from a query string in the URL or form data submitted through a POST request are
- # available through the params method which returns a hash. For example, an action that was performed through
- # <tt>/posts?category=All&limit=5</tt> will include <tt>{ "category" => "All", "limit" => "5" }</tt> in params.
+ # available through the <tt>params</tt> method which returns a hash. For example, an action that was performed through
+ # <tt>/posts?category=All&limit=5</tt> will include <tt>{ "category" => "All", "limit" => "5" }</tt> in <tt>params</tt>.
#
# It's also possible to construct multi-dimensional parameter hashes by specifying keys using brackets, such as:
#
@@ -60,7 +60,7 @@ module ActionController
# <input type="text" name="post[address]" value="hyacintvej">
#
# A request stemming from a form holding these inputs will include <tt>{ "post" => { "name" => "david", "address" => "hyacintvej" } }</tt>.
- # If the address input had been named <tt>post[address][street]</tt>, the params would have included
+ # If the address input had been named <tt>post[address][street]</tt>, the <tt>params</tt> would have included
# <tt>{ "post" => { "address" => { "street" => "hyacintvej" } } }</tt>. There's no limit to the depth of the nesting.
#
# == Sessions
diff --git a/actionpack/lib/action_controller/metal/etag_with_template_digest.rb b/actionpack/lib/action_controller/metal/etag_with_template_digest.rb
index 669cf55bca..75ac996793 100644
--- a/actionpack/lib/action_controller/metal/etag_with_template_digest.rb
+++ b/actionpack/lib/action_controller/metal/etag_with_template_digest.rb
@@ -39,8 +39,14 @@ module ActionController
end
end
+ # Pick the template digest to include in the ETag. If the +:template+ option
+ # is present, use the named template. If +:template+ is nil or absent, use
+ # the default controller/action template. If +:template+ is false, omit the
+ # template digest from the ETag.
def pick_template_for_etag(options)
- options.fetch(:template) { "#{controller_name}/#{action_name}" }
+ unless options[:template] == false
+ options[:template] || "#{controller_name}/#{action_name}"
+ end
end
def lookup_and_digest_template(template)
diff --git a/actionpack/lib/action_controller/metal/strong_parameters.rb b/actionpack/lib/action_controller/metal/strong_parameters.rb
index 46589901fd..b326695ce2 100644
--- a/actionpack/lib/action_controller/metal/strong_parameters.rb
+++ b/actionpack/lib/action_controller/metal/strong_parameters.rb
@@ -58,8 +58,7 @@ module ActionController
# })
#
# permitted = params.require(:person).permit(:name, :age)
- # permitted # => {"name"=>"Francesco", "age"=>22}
- # permitted.class # => ActionController::Parameters
+ # permitted # => <ActionController::Parameters {"name"=>"Francesco", "age"=>22} permitted: true>
# permitted.permitted? # => true
#
# Person.first.update!(permitted)
@@ -87,7 +86,7 @@ module ActionController
#
# params = ActionController::Parameters.new(a: "123", b: "456")
# params.permit(:c)
- # # => {}
+ # # => <ActionController::Parameters {} permitted: true>
#
# ActionController::Parameters.action_on_unpermitted_parameters = :raise
#
@@ -107,6 +106,8 @@ module ActionController
# params["key"] # => "value"
class Parameters
cattr_accessor :permit_all_parameters, instance_accessor: false
+ self.permit_all_parameters = false
+
cattr_accessor :action_on_unpermitted_parameters, instance_accessor: false
delegate :keys, :key?, :has_key?, :values, :has_value?, :value?, :empty?, :include?,
@@ -255,7 +256,7 @@ module ActionController
# either present or the singleton +false+, returns said value:
#
# ActionController::Parameters.new(person: { name: 'Francesco' }).require(:person)
- # # => {"name"=>"Francesco"}
+ # # => <ActionController::Parameters {"name"=>"Francesco"} permitted: false>
#
# Otherwise raises <tt>ActionController::ParameterMissing</tt>:
#
@@ -276,12 +277,12 @@ module ActionController
# returned:
#
# params = ActionController::Parameters.new(user: { ... }, profile: { ... })
- # user_params, profile_params = params.require(:user, :profile)
+ # user_params, profile_params = params.require([:user, :profile])
#
# Otherwise, the method re-raises the first exception found:
#
# params = ActionController::Parameters.new(user: {}, profile: {})
- # user_params, profile_params = params.require(:user, :profile)
+ # user_params, profile_params = params.require([:user, :profile])
# # ActionController::ParameterMissing: param is missing or the value is empty: user
#
# Technically this method can be used to fetch terminal values:
@@ -374,13 +375,13 @@ module ActionController
# })
#
# params.require(:person).permit(:contact)
- # # => {}
+ # # => <ActionController::Parameters {} permitted: true>
#
# params.require(:person).permit(contact: :phone)
- # # => {"contact"=>{"phone"=>"555-1234"}}
+ # # => <ActionController::Parameters {"contact"=><ActionController::Parameters {"phone"=>"555-1234"} permitted: true>} permitted: true>
#
# params.require(:person).permit(contact: [ :email, :phone ])
- # # => {"contact"=>{"email"=>"none@test.com", "phone"=>"555-1234"}}
+ # # => <ActionController::Parameters {"contact"=><ActionController::Parameters {"email"=>"none@test.com", "phone"=>"555-1234"} permitted: true>} permitted: true>
def permit(*filters)
params = self.class.new
@@ -402,7 +403,7 @@ module ActionController
# returns +nil+.
#
# params = ActionController::Parameters.new(person: { name: 'Francesco' })
- # params[:person] # => {"name"=>"Francesco"}
+ # params[:person] # => <ActionController::Parameters {"name"=>"Francesco"} permitted: false>
# params[:none] # => nil
def [](key)
convert_hashes_to_parameters(key, @parameters[key])
@@ -421,7 +422,7 @@ module ActionController
# is given, then that will be run and its result returned.
#
# params = ActionController::Parameters.new(person: { name: 'Francesco' })
- # params.fetch(:person) # => {"name"=>"Francesco"}
+ # params.fetch(:person) # => <ActionController::Parameters {"name"=>"Francesco"} permitted: false>
# params.fetch(:none) # => ActionController::ParameterMissing: param is missing or the value is empty: none
# params.fetch(:none, 'Francesco') # => "Francesco"
# params.fetch(:none) { 'Francesco' } # => "Francesco"
@@ -457,8 +458,8 @@ module ActionController
# don't exist, returns an empty hash.
#
# params = ActionController::Parameters.new(a: 1, b: 2, c: 3)
- # params.slice(:a, :b) # => {"a"=>1, "b"=>2}
- # params.slice(:d) # => {}
+ # params.slice(:a, :b) # => <ActionController::Parameters {"a"=>1, "b"=>2} permitted: false>
+ # params.slice(:d) # => <ActionController::Parameters {} permitted: false>
def slice(*keys)
new_instance_with_inherited_permitted_status(@parameters.slice(*keys))
end
@@ -474,8 +475,8 @@ module ActionController
# filters out the given +keys+.
#
# params = ActionController::Parameters.new(a: 1, b: 2, c: 3)
- # params.except(:a, :b) # => {"c"=>3}
- # params.except(:d) # => {"a"=>1,"b"=>2,"c"=>3}
+ # params.except(:a, :b) # => <ActionController::Parameters {"c"=>3} permitted: false>
+ # params.except(:d) # => <ActionController::Parameters {"a"=>1, "b"=>2, "c"=>3} permitted: false>
def except(*keys)
new_instance_with_inherited_permitted_status(@parameters.except(*keys))
end
@@ -483,8 +484,8 @@ module ActionController
# Removes and returns the key/value pairs matching the given keys.
#
# params = ActionController::Parameters.new(a: 1, b: 2, c: 3)
- # params.extract!(:a, :b) # => {"a"=>1, "b"=>2}
- # params # => {"c"=>3}
+ # params.extract!(:a, :b) # => <ActionController::Parameters {"a"=>1, "b"=>2} permitted: false>
+ # params # => <ActionController::Parameters {"c"=>3} permitted: false>
def extract!(*keys)
new_instance_with_inherited_permitted_status(@parameters.extract!(*keys))
end
@@ -494,7 +495,7 @@ module ActionController
#
# params = ActionController::Parameters.new(a: 1, b: 2, c: 3)
# params.transform_values { |x| x * 2 }
- # # => {"a"=>2, "b"=>4, "c"=>6}
+ # # => <ActionController::Parameters {"a"=>2, "b"=>4, "c"=>6} permitted: false>
def transform_values(&block)
if block
new_instance_with_inherited_permitted_status(
@@ -577,7 +578,7 @@ module ActionController
# params = ActionController::Parameters.new(a: 1)
# params.permit!
# params.permitted? # => true
- # copy_params = params.dup # => {"a"=>1}
+ # copy_params = params.dup # => <ActionController::Parameters {"a"=>1} permitted: true>
# copy_params.permitted? # => true
def dup
super.tap do |duplicate|
diff --git a/actionpack/lib/action_controller/renderer.rb b/actionpack/lib/action_controller/renderer.rb
index 5ff4a658ad..a8c8d66682 100644
--- a/actionpack/lib/action_controller/renderer.rb
+++ b/actionpack/lib/action_controller/renderer.rb
@@ -1,7 +1,7 @@
require 'active_support/core_ext/hash/keys'
module ActionController
- # ActionController::Renderer allows to render arbitrary templates
+ # ActionController::Renderer allows you to render arbitrary templates
# without requirement of being in controller actions.
#
# You get a concrete renderer class by invoking ActionController::Base#renderer.
diff --git a/actionpack/lib/action_dispatch.rb b/actionpack/lib/action_dispatch.rb
index 01d49475de..17aa115f15 100644
--- a/actionpack/lib/action_dispatch.rb
+++ b/actionpack/lib/action_dispatch.rb
@@ -50,6 +50,7 @@ module ActionDispatch
autoload :Callbacks
autoload :Cookies
autoload :DebugExceptions
+ autoload :DebugLocks
autoload :ExceptionWrapper
autoload :Executor
autoload :Flash
diff --git a/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb b/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb
index 5f758d641a..8974258cf7 100644
--- a/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb
+++ b/actionpack/lib/action_dispatch/middleware/debug_exceptions.rb
@@ -36,6 +36,14 @@ module ActionDispatch
def debug_hash(object)
object.to_hash.sort_by { |k, _| k.to_s }.map { |k, v| "#{k}: #{v.inspect rescue $!.message}" }.join("\n")
end
+
+ def render(*)
+ if logger = ActionView::Base.logger
+ logger.silence { super }
+ else
+ super
+ end
+ end
end
def initialize(app, routes_app = nil, response_format = :default)
diff --git a/actionpack/lib/action_dispatch/middleware/debug_locks.rb b/actionpack/lib/action_dispatch/middleware/debug_locks.rb
new file mode 100644
index 0000000000..13254d08de
--- /dev/null
+++ b/actionpack/lib/action_dispatch/middleware/debug_locks.rb
@@ -0,0 +1,122 @@
+module ActionDispatch
+ # This middleware can be used to diagnose deadlocks in the autoload interlock.
+ #
+ # To use it, insert it near the top of the middleware stack, using
+ # <tt>config/application.rb</tt>:
+ #
+ # config.middleware.insert_before Rack::Sendfile, ActionDispatch::DebugLocks
+ #
+ # After restarting the application and re-triggering the deadlock condition,
+ # <tt>/rails/locks</tt> will show a summary of all threads currently known to
+ # the interlock, which lock level they are holding or awaiting, and their
+ # current backtrace.
+ #
+ # Generally a deadlock will be caused by the interlock conflicting with some
+ # other external lock or blocking I/O call. These cannot be automatically
+ # identified, but should be visible in the displayed backtraces.
+ #
+ # NOTE: The formatting and content of this middleware's output is intended for
+ # human consumption, and should be expected to change between releases.
+ #
+ # This middleware exposes operational details of the server, with no access
+ # control. It should only be enabled when in use, and removed thereafter.
+ class DebugLocks
+ def initialize(app, path = '/rails/locks')
+ @app = app
+ @path = path
+ end
+
+ def call(env)
+ req = ActionDispatch::Request.new env
+
+ if req.get?
+ path = req.path_info.chomp('/'.freeze)
+ if path == @path
+ return render_details(req)
+ end
+ end
+
+ @app.call(env)
+ end
+
+ private
+ def render_details(req)
+ threads = ActiveSupport::Dependencies.interlock.raw_state do |threads|
+ # The Interlock itself comes to a complete halt as long as this block
+ # is executing. That gives us a more consistent picture of everything,
+ # but creates a pretty strong Observer Effect.
+ #
+ # Most directly, that means we need to do as little as possible in
+ # this block. More widely, it means this middleware should remain a
+ # strictly diagnostic tool (to be used when something has gone wrong),
+ # and not for any sort of general monitoring.
+
+ threads.each.with_index do |(thread, info), idx|
+ info[:index] = idx
+ info[:backtrace] = thread.backtrace
+ end
+
+ threads
+ end
+
+ str = threads.map do |thread, info|
+ if info[:exclusive]
+ lock_state = 'Exclusive'
+ elsif info[:sharing] > 0
+ lock_state = 'Sharing'
+ lock_state << " x#{info[:sharing]}" if info[:sharing] > 1
+ else
+ lock_state = 'No lock'
+ end
+
+ if info[:waiting]
+ lock_state << ' (yielded share)'
+ end
+
+ msg = "Thread #{info[:index]} [0x#{thread.__id__.to_s(16)} #{thread.status || 'dead'}] #{lock_state}\n"
+
+ if info[:sleeper]
+ msg << " Waiting in #{info[:sleeper]}"
+ msg << " to #{info[:purpose].to_s.inspect}" unless info[:purpose].nil?
+ msg << "\n"
+
+ if info[:compatible]
+ compat = info[:compatible].map { |c| c == false ? "share" : c.to_s.inspect }
+ msg << " may be pre-empted for: #{compat.join(', ')}\n"
+ end
+
+ blockers = threads.values.select { |binfo| blocked_by?(info, binfo, threads.values) }
+ msg << " blocked by: #{blockers.map {|i| i[:index] }.join(', ')}\n" if blockers.any?
+ end
+
+ blockees = threads.values.select { |binfo| blocked_by?(binfo, info, threads.values) }
+ msg << " blocking: #{blockees.map {|i| i[:index] }.join(', ')}\n" if blockees.any?
+
+ msg << "\n#{info[:backtrace].join("\n")}\n" if info[:backtrace]
+ end.join("\n\n---\n\n\n")
+
+ [200, { "Content-Type" => "text/plain", "Content-Length" => str.size }, [str]]
+ end
+
+ def blocked_by?(victim, blocker, all_threads)
+ return false if victim.equal?(blocker)
+
+ case victim[:sleeper]
+ when :start_sharing
+ blocker[:exclusive] ||
+ (!victim[:waiting] && blocker[:compatible] && !blocker[:compatible].include?(false))
+ when :start_exclusive
+ blocker[:sharing] > 0 ||
+ blocker[:exclusive] ||
+ (blocker[:compatible] && !blocker[:compatible].include?(victim[:purpose]))
+ when :yield_shares
+ blocker[:exclusive]
+ when :stop_exclusive
+ blocker[:exclusive] ||
+ victim[:compatible] &&
+ victim[:compatible].include?(blocker[:purpose]) &&
+ all_threads.all? { |other| !other[:compatible] || blocker.equal?(other) || other[:compatible].include?(blocker[:purpose]) }
+ end
+ end
+ end
+end
diff --git a/actionpack/lib/action_dispatch/routing.rb b/actionpack/lib/action_dispatch/routing.rb
index dd6ac9db9c..61ebd0b8db 100644
--- a/actionpack/lib/action_dispatch/routing.rb
+++ b/actionpack/lib/action_dispatch/routing.rb
@@ -89,7 +89,7 @@ module ActionDispatch
#
# Example:
#
- # # In routes.rb
+ # # In config/routes.rb
# get '/login' => 'accounts#login', as: 'login'
#
# # With render, redirect_to, tests, etc.
@@ -101,7 +101,7 @@ module ActionDispatch
#
# Use <tt>root</tt> as a shorthand to name a route for the root path "/".
#
- # # In routes.rb
+ # # In config/routes.rb
# root to: 'blogs#index'
#
# # would recognize http://www.example.com/ as
@@ -114,7 +114,7 @@ module ActionDispatch
# Note: when using +controller+, the route is simply named after the
# method you call on the block parameter rather than map.
#
- # # In routes.rb
+ # # In config/routes.rb
# controller :blog do
# get 'blog/show' => :list
# get 'blog/delete' => :delete
@@ -196,7 +196,7 @@ module ActionDispatch
#
# Rails.application.reload_routes!
#
- # This will clear all named routes and reload routes.rb if the file has been modified from
+ # This will clear all named routes and reload config/routes.rb if the file has been modified from
# last load. To absolutely force reloading, use <tt>reload!</tt>.
#
# == Testing Routes
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb
index 8ff3b42a40..e2cf75da3a 100644
--- a/actionpack/lib/action_dispatch/routing/mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/mapper.rb
@@ -106,7 +106,7 @@ module ActionDispatch
@ast = ast
@anchor = anchor
@via = via
- @internal = options[:internal]
+ @internal = options.delete(:internal)
path_params = ast.find_all(&:symbol?).map(&:to_sym)
@@ -1062,6 +1062,10 @@ module ActionDispatch
def merge_shallow_scope(parent, child) #:nodoc:
child ? true : false
end
+
+ def merge_to_scope(parent, child)
+ child
+ end
end
# Resource routing allows you to quickly declare all of the common routes
@@ -1582,6 +1586,10 @@ module ActionDispatch
raise ArgumentError, "Unknown scope #{on.inspect} given to :on"
end
+ if @scope[:to]
+ options[:to] ||= @scope[:to]
+ end
+
if @scope[:controller] && @scope[:action]
options[:to] ||= "#{@scope[:controller]}##{@scope[:action]}"
end
@@ -2021,7 +2029,7 @@ to this:
class Scope # :nodoc:
OPTIONS = [:path, :shallow_path, :as, :shallow_prefix, :module,
:controller, :action, :path_names, :constraints,
- :shallow, :blocks, :defaults, :via, :format, :options]
+ :shallow, :blocks, :defaults, :via, :format, :options, :to]
RESOURCE_SCOPES = [:resource, :resources]
RESOURCE_METHOD_SCOPES = [:collection, :member, :new]
diff --git a/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb b/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb
index 9934f5547a..3156acf615 100644
--- a/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb
+++ b/actionpack/lib/action_dispatch/routing/polymorphic_routes.rb
@@ -4,7 +4,7 @@ module ActionDispatch
# given an Active Record model instance. They are to be used in combination with
# ActionController::Resources.
#
- # These methods are useful when you want to generate correct URL or path to a RESTful
+ # These methods are useful when you want to generate the correct URL or path to a RESTful
# resource without having to know the exact type of the record in question.
#
# Nested resources and/or namespaces are also supported, as illustrated in the example:
@@ -79,7 +79,7 @@ module ActionDispatch
# polymorphic_url([blog, post], anchor: 'my_anchor', script_name: "/my_app")
# # => "http://example.com/my_app/blogs/1/posts/1#my_anchor"
#
- # For all of these options, see the documentation for <tt>url_for</tt>.
+ # For all of these options, see the documentation for {url_for}[rdoc-ref:ActionDispatch::Routing::UrlFor].
#
# ==== Functionality
#
diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb
index 8777666f9f..10cd1e5787 100644
--- a/actionpack/lib/action_dispatch/testing/integration.rb
+++ b/actionpack/lib/action_dispatch/testing/integration.rb
@@ -327,17 +327,17 @@ module ActionDispatch
request_encoder = RequestEncoder.encoder(as)
if path =~ %r{://}
- location = URI.parse(path)
- https! URI::HTTPS === location if location.scheme
- if url_host = location.host
- default = Rack::Request::DEFAULT_PORTS[location.scheme]
- url_host += ":#{location.port}" if default != location.port
- host! url_host
+ path = build_expanded_path(path, request_encoder) do |location|
+ https! URI::HTTPS === location if location.scheme
+
+ if url_host = location.host
+ default = Rack::Request::DEFAULT_PORTS[location.scheme]
+ url_host += ":#{location.port}" if default != location.port
+ host! url_host
+ end
end
- path = request_encoder.append_format_to location.path
- path = location.query ? "#{path}?#{location.query}" : path
- else
- path = request_encoder.append_format_to path
+ elsif as
+ path = build_expanded_path(path, request_encoder)
end
hostname, port = host.split(':')
@@ -396,6 +396,13 @@ module ActionDispatch
"#{env['rack.url_scheme']}://#{env['SERVER_NAME']}:#{env['SERVER_PORT']}#{path}"
end
+ def build_expanded_path(path, request_encoder)
+ location = URI.parse(path)
+ yield location if block_given?
+ path = request_encoder.append_format_to location.path
+ location.query ? "#{path}?#{location.query}" : path
+ end
+
class RequestEncoder # :nodoc:
@encoders = {}
@@ -416,8 +423,11 @@ module ActionDispatch
end
def append_format_to(path)
- path << @path_format unless @url_encoded_form
- path
+ if @url_encoded_form
+ path
+ else
+ path + @path_format
+ end
end
def content_type
diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb
index 97571c1308..3b89531e90 100644
--- a/actionpack/test/controller/integration_test.rb
+++ b/actionpack/test/controller/integration_test.rb
@@ -1147,6 +1147,22 @@ class IntegrationRequestEncodersTest < ActionDispatch::IntegrationTest
end
end
+ def test_standard_json_encoding_works
+ with_routing do |routes|
+ routes.draw do
+ ActiveSupport::Deprecation.silence do
+ post ':action' => FooController
+ end
+ end
+
+ post '/foos_json.json', params: { foo: 'fighters' }.to_json,
+ headers: { 'Content-Type' => 'application/json' }
+
+ assert_response :success
+ assert_equal({ 'foo' => 'fighters' }, response.parsed_body)
+ end
+ end
+
def test_encoding_as_json
post_to_foos as: :json do
assert_response :success
@@ -1194,6 +1210,20 @@ class IntegrationRequestEncodersTest < ActionDispatch::IntegrationTest
end
end
+ def test_get_parameters_with_as_option
+ with_routing do |routes|
+ routes.draw do
+ ActiveSupport::Deprecation.silence do
+ get ':action' => FooController
+ end
+ end
+
+ get '/foos_json?foo=heyo', as: :json
+
+ assert_equal({ 'foo' => 'heyo' }, response.parsed_body)
+ end
+ end
+
private
def post_to_foos(as:)
with_routing do |routes|
diff --git a/actionpack/test/controller/parameters/nested_parameters_test.rb b/actionpack/test/controller/parameters/nested_parameters_permit_test.rb
index 7151a8567c..5cf6f0d4e8 100644
--- a/actionpack/test/controller/parameters/nested_parameters_test.rb
+++ b/actionpack/test/controller/parameters/nested_parameters_permit_test.rb
@@ -1,7 +1,7 @@
require 'abstract_unit'
require 'action_controller/metal/strong_parameters'
-class NestedParametersTest < ActiveSupport::TestCase
+class NestedParametersPermitTest < ActiveSupport::TestCase
def assert_filtered_out(params, key)
assert !params.has_key?(key), "key #{key.inspect} has not been filtered out"
end
diff --git a/actionpack/test/controller/parameters/parameters_permit_test.rb b/actionpack/test/controller/parameters/parameters_permit_test.rb
index b75eb0e3bf..2eed2996f6 100644
--- a/actionpack/test/controller/parameters/parameters_permit_test.rb
+++ b/actionpack/test/controller/parameters/parameters_permit_test.rb
@@ -369,4 +369,10 @@ class ParametersPermitTest < ActiveSupport::TestCase
refute params.permit(foo: [:bar]).has_key?(:foo)
refute params.permit(foo: :bar).has_key?(:foo)
end
+
+ test '#permitted? is false by default' do
+ params = ActionController::Parameters.new
+
+ assert_equal false, params.permitted?
+ end
end
diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb
index f42efd35af..652c06af19 100644
--- a/actionpack/test/controller/render_test.rb
+++ b/actionpack/test/controller/render_test.rb
@@ -2,6 +2,9 @@ require 'abstract_unit'
require 'controller/fake_models'
class TestControllerWithExtraEtags < ActionController::Base
+ def self.controller_name; 'test'; end
+ def self.controller_path; 'test'; end
+
etag { nil }
etag { 'ab' }
etag { :cde }
@@ -17,7 +20,7 @@ class TestControllerWithExtraEtags < ActionController::Base
end
def strong
- render plain: "stale" if stale?(strong_etag: 'strong')
+ render plain: "stale" if stale?(strong_etag: 'strong', template: false)
end
def with_template
@@ -25,6 +28,10 @@ class TestControllerWithExtraEtags < ActionController::Base
render plain: 'stale'
end
end
+
+ def with_implicit_template
+ fresh_when(etag: '123')
+ end
end
class ImplicitRenderTestController < ActionController::Base
@@ -528,20 +535,28 @@ class EtagRenderTest < ActionController::TestCase
get :with_template
assert_response :not_modified
- # Modify the template digest
- path = File.expand_path('../../fixtures/test/hello_world.erb', __FILE__)
- old = File.read(path)
+ modify_template(:hello_world) do
+ request.if_none_match = etag
+ get :with_template
+ assert_response :ok
+ assert_not_equal etag, @response.etag
+ end
+ end
- begin
- File.write path, 'foo'
- ActionView::LookupContext::DetailsKey.clear
+ def test_etag_reflects_implicit_template_digest
+ get :with_implicit_template
+ assert_response :ok
+ assert_not_nil etag = @response.etag
+ request.if_none_match = etag
+ get :with_implicit_template
+ assert_response :not_modified
+
+ modify_template(:with_implicit_template) do
request.if_none_match = etag
- get :with_template
+ get :with_implicit_template
assert_response :ok
assert_not_equal etag, @response.etag
- ensure
- File.write path, old
end
end
@@ -553,6 +568,16 @@ class EtagRenderTest < ActionController::TestCase
def strong_etag(record)
%("#{Digest::MD5.hexdigest(ActiveSupport::Cache.expand_cache_key(record))}")
end
+
+ def modify_template(name)
+ path = File.expand_path("../../fixtures/test/#{name}.erb", __FILE__)
+ original = File.read(path)
+ File.write(path, "#{original} Modified!")
+ ActionView::LookupContext::DetailsKey.clear
+ yield
+ ensure
+ File.write(path, original)
+ end
end
class MetalRenderTest < ActionController::TestCase
@@ -564,6 +589,13 @@ class MetalRenderTest < ActionController::TestCase
end
end
+class ActionControllerBaseRenderTest < ActionController::TestCase
+ def test_direct_render_to_string
+ ac = ActionController::Base.new()
+ assert_equal "Hello world!", ac.render_to_string(template: 'test/hello_world')
+ end
+end
+
class ImplicitRenderTest < ActionController::TestCase
tests ImplicitRenderTestController
diff --git a/actionpack/test/controller/send_file_test.rb b/actionpack/test/controller/send_file_test.rb
index 2820425c31..9df70dacbf 100644
--- a/actionpack/test/controller/send_file_test.rb
+++ b/actionpack/test/controller/send_file_test.rb
@@ -11,6 +11,8 @@ class SendFileController < ActionController::Base
include ActionController::Testing
layout "layouts/standard" # to make sure layouts don't interfere
+ before_action :file, only: :file_from_before_action
+
attr_writer :options
def options
@options ||= {}
@@ -20,6 +22,10 @@ class SendFileController < ActionController::Base
send_file(file_path, options)
end
+ def file_from_before_action
+ raise 'No file sent from before action.'
+ end
+
def test_send_file_headers_bang
options = {
:type => Mime[:png],
@@ -192,6 +198,15 @@ class SendFileTest < ActionController::TestCase
assert_nil @controller.headers['Content-Disposition']
end
+ def test_send_file_from_before_action
+ response = nil
+ assert_nothing_raised { response = process('file_from_before_action') }
+ assert_not_nil response
+
+ assert_kind_of String, response.body
+ assert_equal file_data, response.body
+ end
+
%w(file data).each do |method|
define_method "test_send_#{method}_status" do
@controller.options = { :stream => false, :status => 500 }
diff --git a/actionpack/test/dispatch/cookies_test.rb b/actionpack/test/dispatch/cookies_test.rb
index dfcef14344..c7194cde4a 100644
--- a/actionpack/test/dispatch/cookies_test.rb
+++ b/actionpack/test/dispatch/cookies_test.rb
@@ -520,7 +520,7 @@ class CookiesTest < ActionController::TestCase
def test_accessing_nonexistent_signed_cookie_should_not_raise_an_invalid_signature
get :set_signed_cookie
- assert_nil @controller.send(:cookies).signed[:non_existant_attribute]
+ assert_nil @controller.send(:cookies).signed[:non_existent_attribute]
end
def test_encrypted_cookie_using_default_serializer
@@ -638,7 +638,7 @@ class CookiesTest < ActionController::TestCase
def test_accessing_nonexistent_encrypted_cookie_should_not_raise_invalid_message
get :set_encrypted_cookie
- assert_nil @controller.send(:cookies).encrypted[:non_existant_attribute]
+ assert_nil @controller.send(:cookies).encrypted[:non_existent_attribute]
end
def test_setting_invalid_encrypted_cookie_should_return_nil_when_accessing_it
diff --git a/actionpack/test/dispatch/debug_exceptions_test.rb b/actionpack/test/dispatch/debug_exceptions_test.rb
index 5a39db145e..6f3d30ebf9 100644
--- a/actionpack/test/dispatch/debug_exceptions_test.rb
+++ b/actionpack/test/dispatch/debug_exceptions_test.rb
@@ -362,6 +362,29 @@ class DebugExceptionsTest < ActionDispatch::IntegrationTest
assert_match(/puke/, output.rewind && output.read)
end
+ test 'logs only what is necessary' do
+ @app = DevelopmentApp
+ io = StringIO.new
+ logger = ActiveSupport::Logger.new(io)
+
+ _old, ActionView::Base.logger = ActionView::Base.logger, logger
+ begin
+ get "/", headers: { 'action_dispatch.show_exceptions' => true, 'action_dispatch.logger' => logger }
+ ensure
+ ActionView::Base.logger = _old
+ end
+
+ output = io.rewind && io.read
+ lines = output.lines
+
+ # Other than the first three...
+ assert_equal([" \n", "RuntimeError (puke!):\n", " \n"], lines.slice!(0, 3))
+ lines.each do |line|
+ # .. all the remaining lines should be from the backtrace
+ assert_match(/:\d+:in /, line)
+ end
+ end
+
test 'uses backtrace cleaner from env' do
@app = DevelopmentApp
backtrace_cleaner = ActiveSupport::BacktraceCleaner.new
diff --git a/actionpack/test/dispatch/mapper_test.rb b/actionpack/test/dispatch/mapper_test.rb
index 69098326b9..f6dd9272a6 100644
--- a/actionpack/test/dispatch/mapper_test.rb
+++ b/actionpack/test/dispatch/mapper_test.rb
@@ -102,6 +102,18 @@ module ActionDispatch
assert_equal("PUT", fakeset.routes.first.verb)
end
+ def test_to_scope
+ fakeset = FakeSet.new
+ mapper = Mapper.new fakeset
+ mapper.scope(to: "posts#index") do
+ mapper.get :all
+ mapper.post :most
+ end
+
+ assert_equal "posts#index", fakeset.routes.to_a[0].defaults[:to]
+ assert_equal "posts#index", fakeset.routes.to_a[1].defaults[:to]
+ end
+
def test_map_slash
fakeset = FakeSet.new
mapper = Mapper.new fakeset
diff --git a/actionpack/test/dispatch/request/json_params_parsing_test.rb b/actionpack/test/dispatch/request/json_params_parsing_test.rb
index a07138b55e..6ab71ebc81 100644
--- a/actionpack/test/dispatch/request/json_params_parsing_test.rb
+++ b/actionpack/test/dispatch/request/json_params_parsing_test.rb
@@ -155,7 +155,7 @@ class RootLessJSONParamsParsingTest < ActionDispatch::IntegrationTest
test "parses json params after custom json mime type registered" do
begin
Mime::Type.unregister :json
- Mime::Type.register "application/json", :json, %w(application/vnd.api+json)
+ Mime::Type.register "application/json", :json, %w(application/vnd.rails+json)
assert_parses(
{"user" => {"username" => "meinac"}, "username" => "meinac"},
"{\"username\": \"meinac\"}", { 'CONTENT_TYPE' => 'application/json' }
@@ -169,10 +169,10 @@ class RootLessJSONParamsParsingTest < ActionDispatch::IntegrationTest
test "parses json params after custom json mime type registered with synonym" do
begin
Mime::Type.unregister :json
- Mime::Type.register "application/json", :json, %w(application/vnd.api+json)
+ Mime::Type.register "application/json", :json, %w(application/vnd.rails+json)
assert_parses(
{"user" => {"username" => "meinac"}, "username" => "meinac"},
- "{\"username\": \"meinac\"}", { 'CONTENT_TYPE' => 'application/vnd.api+json' }
+ "{\"username\": \"meinac\"}", { 'CONTENT_TYPE' => 'application/vnd.rails+json' }
)
ensure
Mime::Type.unregister :json
diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb
index ade4b0c381..75fdc9469f 100644
--- a/actionpack/test/dispatch/routing_test.rb
+++ b/actionpack/test/dispatch/routing_test.rb
@@ -4795,3 +4795,33 @@ class TestPathParameters < ActionDispatch::IntegrationTest
assert_equal "/ar | /ar/about", @response.body
end
end
+
+class TestInternalRoutingParams < ActionDispatch::IntegrationTest
+ Routes = ActionDispatch::Routing::RouteSet.new.tap do |app|
+ app.draw do
+ get '/test_internal/:internal' => 'internal#internal'
+ end
+ end
+
+ class ::InternalController < ActionController::Base
+ def internal
+ head :ok
+ end
+ end
+
+ APP = build_app Routes
+
+ def app
+ APP
+ end
+
+ def test_paths_with_partial_dynamic_segments_are_recognised
+ get '/test_internal/123'
+ assert_equal 200, response.status
+
+ assert_equal(
+ { controller: 'internal', action: 'internal', internal: '123' },
+ request.path_parameters
+ )
+ end
+end
diff --git a/actionpack/test/fixtures/test/with_implicit_template.erb b/actionpack/test/fixtures/test/with_implicit_template.erb
new file mode 100644
index 0000000000..474488cd13
--- /dev/null
+++ b/actionpack/test/fixtures/test/with_implicit_template.erb
@@ -0,0 +1 @@
+Hello explicitly!
diff --git a/actionview/CHANGELOG.md b/actionview/CHANGELOG.md
index 9d669c7cd8..ab4b46c56e 100644
--- a/actionview/CHANGELOG.md
+++ b/actionview/CHANGELOG.md
@@ -1,5 +1,49 @@
+* New syntax for tag helpers. Avoid positional parameters and support HTML5 by default.
+ Example usage of tag helpers before:
+
+ ```ruby
+ tag(:br, nil, true)
+ content_tag(:div, content_tag(:p, "Hello world!"), class: "strong")
+
+ <%= content_tag :div, class: "strong" do -%>
+ Hello world!
+ <% end -%>
+ ```
+
+ Example usage of tag helpers after:
+
+ ```ruby
+ tag.br
+ tag.div tag.p("Hello world!"), class: "strong"
+
+ <%= tag.div class: "strong" do %>
+ Hello world!
+ <% end %>
+ ```
+
+ *Marek Kirejczyk*, *Kasper Timm Hansen*
+
+* Change `datetime_field` and `datetime_field_tag` to generate `datetime-local` fields.
+
+ As a new specification of the HTML 5 the text field type `datetime` will no longer exist
+ and it is recomended to use `datetime-local`.
+ Ref: https://html.spec.whatwg.org/multipage/forms.html#local-date-and-time-state-(type=datetime-local)
+
+ *Herminio Torres*
+
+* Raw template handler (which is also the default template handler in Rails 5) now outputs
+ HTML-safe strings.
+
+ In Rails 5 the default template handler was changed to the raw template handler. Because
+ the ERB template handler escaped strings by default this broke some applications that
+ expected plain JS or HTML files to be rendered unescaped. This fixes the issue caused
+ by changing the default handler by changing the Raw template handler to output HTML-safe
+ strings.
+
+ *Eileen M. Uchitelle*
+
* `select_tag`'s `include_blank` option for generation for blank option tag, now adds an empty space label,
- when the value as well as content for option tag are empty, so that we confirm with html specification.
+ when the value as well as content for option tag are empty, so that we conform with html specification.
Ref: https://www.w3.org/TR/html5/forms.html#the-option-element.
Generation of option before:
diff --git a/actionview/lib/action_view/base.rb b/actionview/lib/action_view/base.rb
index ad1cb1a4be..0ede884c94 100644
--- a/actionview/lib/action_view/base.rb
+++ b/actionview/lib/action_view/base.rb
@@ -17,7 +17,7 @@ module ActionView #:nodoc:
#
# == ERB
#
- # You trigger ERB by using embeddings such as <% %>, <% -%>, and <%= %>. The <%= %> tag set is used when you want output. Consider the
+ # You trigger ERB by using embeddings such as <tt><% %></tt>, <tt><% -%></tt>, and <tt><%= %></tt>. The <tt><%= %></tt> tag set is used when you want output. Consider the
# following loop for names:
#
# <b>Names of all the people</b>
@@ -25,7 +25,7 @@ module ActionView #:nodoc:
# Name: <%= person.name %><br/>
# <% end %>
#
- # The loop is setup in regular embedding tags <% %> and the name is written using the output embedding tag <%= %>. Note that this
+ # The loop is setup in regular embedding tags <tt><% %></tt>, and the name is written using the output embedding tag <tt><%= %></tt>. Note that this
# is not just a usage suggestion. Regular output functions like print or puts won't work with ERB templates. So this would be wrong:
#
# <%# WRONG %>
@@ -33,9 +33,9 @@ module ActionView #:nodoc:
#
# If you absolutely must write from within a function use +concat+.
#
- # When on a line that only contains whitespaces except for the tag, <% %> suppress leading and trailing whitespace,
- # including the trailing newline. <% %> and <%- -%> are the same.
- # Note however that <%= %> and <%= -%> are different: only the latter removes trailing whitespaces.
+ # When on a line that only contains whitespaces except for the tag, <tt><% %></tt> suppresses leading and trailing whitespace,
+ # including the trailing newline. <tt><% %></tt> and <tt><%- -%></tt> are the same.
+ # Note however that <tt><%= %></tt> and <tt><%= -%></tt> are different: only the latter removes trailing whitespaces.
#
# === Using sub templates
#
@@ -110,7 +110,7 @@ module ActionView #:nodoc:
# <p>A product of Danish Design during the Winter of '79...</p>
# </div>
#
- # A full-length RSS example actually used on Basecamp:
+ # Here is a full-length RSS example actually used on Basecamp:
#
# xml.rss("version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/") do
# xml.channel do
diff --git a/actionview/lib/action_view/digestor.rb b/actionview/lib/action_view/digestor.rb
index b91e61da18..9c18ec56ca 100644
--- a/actionview/lib/action_view/digestor.rb
+++ b/actionview/lib/action_view/digestor.rb
@@ -12,10 +12,9 @@ module ActionView
# * <tt>name</tt> - Template name
# * <tt>finder</tt> - An instance of <tt>ActionView::LookupContext</tt>
# * <tt>dependencies</tt> - An array of dependent views
- # * <tt>partial</tt> - Specifies whether the template is a partial
def digest(name:, finder:, dependencies: [])
dependencies ||= []
- cache_key = ([ name ].compact + dependencies).join('.')
+ cache_key = [ name, finder.rendered_format, dependencies ].flatten.compact.join('.')
# this is a correctly done double-checked locking idiom
# (Concurrent::Map's lookups have volatile semantics)
@@ -39,8 +38,12 @@ module ActionView
def tree(name, finder, partial = false, seen = {})
logical_name = name.gsub(%r|/_|, "/")
- if finder.disable_cache { finder.exists?(logical_name, [], partial) }
- template = finder.disable_cache { finder.find(logical_name, [], partial) }
+ options = {}
+ options[:formats] = [finder.rendered_format] if finder.rendered_format
+
+ if finder.disable_cache { finder.exists?(logical_name, [], partial, [], options) }
+ template = finder.disable_cache { finder.find(logical_name, [], partial, [], options) }
+ finder.rendered_format ||= template.formats.first
if node = seen[template.identifier] # handle cycles in the tree
node
diff --git a/actionview/lib/action_view/helpers/asset_tag_helper.rb b/actionview/lib/action_view/helpers/asset_tag_helper.rb
index 413c35954c..bcbb3db6a9 100644
--- a/actionview/lib/action_view/helpers/asset_tag_helper.rb
+++ b/actionview/lib/action_view/helpers/asset_tag_helper.rb
@@ -264,8 +264,8 @@ module ActionView
# # => <video src="/videos/trailer"></video>
# video_tag("trailer.ogg")
# # => <video src="/videos/trailer.ogg"></video>
- # video_tag("trailer.ogg", controls: true, autobuffer: true)
- # # => <video autobuffer="autobuffer" controls="controls" src="/videos/trailer.ogg" ></video>
+ # video_tag("trailer.ogg", controls: true, preload: 'none')
+ # # => <video preload="none" controls="controls" src="/videos/trailer.ogg" ></video>
# video_tag("trailer.m4v", size: "16x10", poster: "screenshot.png")
# # => <video src="/videos/trailer.m4v" width="16" height="10" poster="/assets/screenshot.png"></video>
# video_tag("/trailers/hd.avi", size: "16x16")
diff --git a/actionview/lib/action_view/helpers/date_helper.rb b/actionview/lib/action_view/helpers/date_helper.rb
index 9042b9cffd..a02702bf7a 100644
--- a/actionview/lib/action_view/helpers/date_helper.rb
+++ b/actionview/lib/action_view/helpers/date_helper.rb
@@ -3,6 +3,7 @@ require 'action_view/helpers/tag_helper'
require 'active_support/core_ext/array/extract_options'
require 'active_support/core_ext/date/conversions'
require 'active_support/core_ext/hash/slice'
+require 'active_support/core_ext/object/acts_like'
require 'active_support/core_ext/object/with_options'
module ActionView
@@ -1058,7 +1059,7 @@ module ActionView
prefix = @options[:prefix] || ActionView::Helpers::DateTimeSelector::DEFAULT_PREFIX
prefix += "[#{@options[:index]}]" if @options.has_key?(:index)
- field_name = @options[:field_name] || type
+ field_name = @options[:field_name] || type.to_s
if @options[:include_position]
field_name += "(#{ActionView::Helpers::DateTimeSelector::POSITION[type]}i)"
end
diff --git a/actionview/lib/action_view/helpers/form_helper.rb b/actionview/lib/action_view/helpers/form_helper.rb
index 7ced37572e..3d2ae0cfe0 100644
--- a/actionview/lib/action_view/helpers/form_helper.rb
+++ b/actionview/lib/action_view/helpers/form_helper.rb
@@ -860,24 +860,6 @@ module ActionView
#
# file_field(:attachment, :file, class: 'file_input')
# # => <input type="file" id="attachment_file" name="attachment[file]" class="file_input" />
- #
- # ==== Gotcha
- #
- # The HTML specification says that when a file field is empty, web browsers
- # do not send any value to the server. Unfortunately this introduces a
- # gotcha: if a +User+ model has an +avatar+ field, and no file is selected,
- # then the +avatar+ parameter is empty. Thus, any mass-assignment idiom like
- #
- # @user.update(params[:user])
- #
- # wouldn't update the +avatar+ field.
- #
- # To prevent this, the helper generates an auxiliary hidden field before
- # every file field. The hidden field has the same name as the file one and
- # a blank value.
- #
- # In case you don't want the helper to generate this hidden field you can
- # specify the <tt>include_hidden: false</tt> option.
def file_field(object_name, method, options = {})
Tags::FileField.new(object_name, method, self, options).render
end
@@ -1066,7 +1048,7 @@ module ActionView
# Returns a text_field of type "time".
#
# The default value is generated by trying to call +strftime+ with "%T.%L"
- # on the objects's value. It is still possible to override that
+ # on the object's value. It is still possible to override that
# by passing the "value" option.
#
# === Options
@@ -1092,42 +1074,9 @@ module ActionView
Tags::TimeField.new(object_name, method, self, options).render
end
- # Returns a text_field of type "datetime".
- #
- # datetime_field("user", "born_on")
- # # => <input id="user_born_on" name="user[born_on]" type="datetime" />
- #
- # The default value is generated by trying to call +strftime+ with "%Y-%m-%dT%T.%L%z"
- # on the object's value, which makes it behave as expected for instances
- # of DateTime and ActiveSupport::TimeWithZone.
- #
- # @user.born_on = Date.new(1984, 1, 12)
- # datetime_field("user", "born_on")
- # # => <input id="user_born_on" name="user[born_on]" type="datetime" value="1984-01-12T00:00:00.000+0000" />
- #
- # You can create values for the "min" and "max" attributes by passing
- # instances of Date or Time to the options hash.
- #
- # datetime_field("user", "born_on", min: Date.today)
- # # => <input id="user_born_on" name="user[born_on]" type="datetime" min="2014-05-20T00:00:00.000+0000" />
- #
- # Alternatively, you can pass a String formatted as an ISO8601 datetime
- # with UTC offset as the values for "min" and "max."
- #
- # datetime_field("user", "born_on", min: "2014-05-20T00:00:00+0000")
- # # => <input id="user_born_on" name="user[born_on]" type="datetime" min="2014-05-20T00:00:00.000+0000" />
- #
- def datetime_field(object_name, method, options = {})
- ActiveSupport::Deprecation.warn(<<-MESSAGE.squish)
- datetime_field is deprecated and will be removed in Rails 5.1.
- Use datetime_local_field instead.
- MESSAGE
- Tags::DatetimeField.new(object_name, method, self, options).render
- end
-
# Returns a text_field of type "datetime-local".
#
- # datetime_local_field("user", "born_on")
+ # datetime_field("user", "born_on")
# # => <input id="user_born_on" name="user[born_on]" type="datetime-local" />
#
# The default value is generated by trying to call +strftime+ with "%Y-%m-%dT%T"
@@ -1135,25 +1084,27 @@ module ActionView
# of DateTime and ActiveSupport::TimeWithZone.
#
# @user.born_on = Date.new(1984, 1, 12)
- # datetime_local_field("user", "born_on")
+ # datetime_field("user", "born_on")
# # => <input id="user_born_on" name="user[born_on]" type="datetime-local" value="1984-01-12T00:00:00" />
#
# You can create values for the "min" and "max" attributes by passing
# instances of Date or Time to the options hash.
#
- # datetime_local_field("user", "born_on", min: Date.today)
+ # datetime_field("user", "born_on", min: Date.today)
# # => <input id="user_born_on" name="user[born_on]" type="datetime-local" min="2014-05-20T00:00:00.000" />
#
# Alternatively, you can pass a String formatted as an ISO8601 datetime as
# the values for "min" and "max."
#
- # datetime_local_field("user", "born_on", min: "2014-05-20T00:00:00")
+ # datetime_field("user", "born_on", min: "2014-05-20T00:00:00")
# # => <input id="user_born_on" name="user[born_on]" type="datetime-local" min="2014-05-20T00:00:00.000" />
#
- def datetime_local_field(object_name, method, options = {})
+ def datetime_field(object_name, method, options = {})
Tags::DatetimeLocalField.new(object_name, method, self, options).render
end
+ alias datetime_local_field datetime_field
+
# Returns a text_field of type "month".
#
# month_field("user", "born_on")
diff --git a/actionview/lib/action_view/helpers/form_options_helper.rb b/actionview/lib/action_view/helpers/form_options_helper.rb
index b277efd7b6..06b696f281 100644
--- a/actionview/lib/action_view/helpers/form_options_helper.rb
+++ b/actionview/lib/action_view/helpers/form_options_helper.rb
@@ -363,7 +363,7 @@ module ActionView
html_attributes[:disabled] ||= disabled && option_value_selected?(value, disabled)
html_attributes[:value] = value
- content_tag_string(:option, text, html_attributes)
+ tag_builder.content_tag_string(:option, text, html_attributes)
end.join("\n").html_safe
end
diff --git a/actionview/lib/action_view/helpers/form_tag_helper.rb b/actionview/lib/action_view/helpers/form_tag_helper.rb
index 82f2fd30c7..f1375570f2 100644
--- a/actionview/lib/action_view/helpers/form_tag_helper.rb
+++ b/actionview/lib/action_view/helpers/form_tag_helper.rb
@@ -685,21 +685,6 @@ module ActionView
text_field_tag(name, value, options.merge(type: :time))
end
- # Creates a text field of type "datetime".
- #
- # === Options
- # * <tt>:min</tt> - The minimum acceptable value.
- # * <tt>:max</tt> - The maximum acceptable value.
- # * <tt>:step</tt> - The acceptable value granularity.
- # * Otherwise accepts the same options as text_field_tag.
- def datetime_field_tag(name, value = nil, options = {})
- ActiveSupport::Deprecation.warn(<<-MESSAGE.squish)
- datetime_field_tag is deprecated and will be removed in Rails 5.1.
- Use datetime_local_field_tag instead.
- MESSAGE
- text_field_tag(name, value, options.merge(type: :datetime))
- end
-
# Creates a text field of type "datetime-local".
#
# === Options
@@ -707,10 +692,12 @@ module ActionView
# * <tt>:max</tt> - The maximum acceptable value.
# * <tt>:step</tt> - The acceptable value granularity.
# * Otherwise accepts the same options as text_field_tag.
- def datetime_local_field_tag(name, value = nil, options = {})
+ def datetime_field_tag(name, value = nil, options = {})
text_field_tag(name, value, options.merge(type: 'datetime-local'))
end
+ alias datetime_local_field_tag datetime_field_tag
+
# Creates a text field of type "month".
#
# === Options
diff --git a/actionview/lib/action_view/helpers/number_helper.rb b/actionview/lib/action_view/helpers/number_helper.rb
index f0222582c7..23081c5f07 100644
--- a/actionview/lib/action_view/helpers/number_helper.rb
+++ b/actionview/lib/action_view/helpers/number_helper.rb
@@ -263,8 +263,6 @@ module ActionView
# * <tt>:strip_insignificant_zeros</tt> - If +true+ removes
# insignificant zeros after the decimal separator (defaults to
# +true+)
- # * <tt>:prefix</tt> - If +:si+ formats the number using the SI
- # prefix (defaults to :binary)
# * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when
# the argument is invalid.
#
diff --git a/actionview/lib/action_view/helpers/tag_helper.rb b/actionview/lib/action_view/helpers/tag_helper.rb
index 42e7358a1d..4ba37fd5e5 100644
--- a/actionview/lib/action_view/helpers/tag_helper.rb
+++ b/actionview/lib/action_view/helpers/tag_helper.rb
@@ -1,39 +1,208 @@
+# frozen-string-literal: true
+
require 'active_support/core_ext/string/output_safety'
require 'set'
module ActionView
# = Action View Tag Helpers
module Helpers #:nodoc:
- # Provides methods to generate HTML tags programmatically when you can't use
- # a Builder. By default, they output XHTML compliant tags.
+ # Provides methods to generate HTML tags programmatically both as a modern
+ # HTML5 compliant builder style and legacy XHTML compliant tags.
module TagHelper
extend ActiveSupport::Concern
include CaptureHelper
include OutputSafetyHelper
- BOOLEAN_ATTRIBUTES = %w(disabled readonly multiple checked autobuffer
- autoplay controls loop selected hidden scoped async
- defer reversed ismap seamless muted required
- autofocus novalidate formnovalidate open pubdate
- itemscope allowfullscreen default inert sortable
- truespeed typemustmatch).to_set
+ BOOLEAN_ATTRIBUTES = %w(allowfullscreen async autofocus autoplay checked
+ compact controls declare default defaultchecked
+ defaultmuted defaultselected defer disabled
+ enabled formnovalidate hidden indeterminate inert
+ ismap itemscope loop multiple muted nohref
+ noresize noshade novalidate nowrap open
+ pauseonexit readonly required reversed scoped
+ seamless selected sortable truespeed typemustmatch
+ visible).to_set
BOOLEAN_ATTRIBUTES.merge(BOOLEAN_ATTRIBUTES.map(&:to_sym))
TAG_PREFIXES = ['aria', 'data', :aria, :data].to_set
- PRE_CONTENT_STRINGS = Hash.new { "".freeze }
+ PRE_CONTENT_STRINGS = Hash.new { "" }
PRE_CONTENT_STRINGS[:textarea] = "\n"
PRE_CONTENT_STRINGS["textarea"] = "\n"
+ class TagBuilder #:nodoc:
+ include CaptureHelper
+ include OutputSafetyHelper
+
+ VOID_ELEMENTS = %i(area base br col embed hr img input keygen link meta param source track wbr).to_set
+
+ def initialize(view_context)
+ @view_context = view_context
+ end
+
+ def tag_string(name, content = nil, escape_attributes: true, **options, &block)
+ content = @view_context.capture(self, &block) if block_given?
+ if VOID_ELEMENTS.include?(name) && content.nil?
+ "<#{name.to_s.dasherize}#{tag_options(options, escape_attributes)}>".html_safe
+ else
+ content_tag_string(name.to_s.dasherize, content || '', options, escape_attributes)
+ end
+ end
- # Returns an empty HTML tag of type +name+ which by default is XHTML
+ def content_tag_string(name, content, options, escape = true)
+ tag_options = tag_options(options, escape) if options
+ content = ERB::Util.unwrapped_html_escape(content) if escape
+ "<#{name}#{tag_options}>#{PRE_CONTENT_STRINGS[name]}#{content}</#{name}>".html_safe
+ end
+
+ def tag_options(options, escape = true)
+ return if options.blank?
+ output = "".dup
+ sep = " "
+ options.each_pair do |key, value|
+ if TAG_PREFIXES.include?(key) && value.is_a?(Hash)
+ value.each_pair do |k, v|
+ next if v.nil?
+ output << sep
+ output << prefix_tag_option(key, k, v, escape)
+ end
+ elsif BOOLEAN_ATTRIBUTES.include?(key)
+ if value
+ output << sep
+ output << boolean_tag_option(key)
+ end
+ elsif !value.nil?
+ output << sep
+ output << tag_option(key, value, escape)
+ end
+ end
+ output unless output.empty?
+ end
+
+ def boolean_tag_option(key)
+ %(#{key}="#{key}")
+ end
+
+ def tag_option(key, value, escape)
+ if value.is_a?(Array)
+ value = escape ? safe_join(value, " ") : value.join(" ")
+ else
+ value = escape ? ERB::Util.unwrapped_html_escape(value) : value
+ end
+ %(#{key}="#{value}")
+ end
+
+ private
+ def prefix_tag_option(prefix, key, value, escape)
+ key = "#{prefix}-#{key.to_s.dasherize}"
+ unless value.is_a?(String) || value.is_a?(Symbol) || value.is_a?(BigDecimal)
+ value = value.to_json
+ end
+ tag_option(key, value, escape)
+ end
+
+ def respond_to_missing?(*args)
+ true
+ end
+
+ def method_missing(called, *args, &block)
+ tag_string(called, *args, &block)
+ end
+
+ end
+
+ # Returns an HTML tag.
+ #
+ # === Building HTML tags
+ #
+ # Builds HTML5 compliant tags with a tag proxy. Every tag can be built with:
+ #
+ # tag.<tag name>(optional content, options)
+ #
+ # where tag name can be e.g. br, div, section, article, or any tag really.
+ #
+ # ==== Passing content
+ #
+ # Tags can pass content to embed within it:
+ #
+ # tag.h1 'All titles fit to print' # => <h1>All titles fit to print</h1>
+ #
+ # tag.div tag.p('Hello world!') # => <div><p>Hello world!</p></div>
+ #
+ # Content can also be captured with a block, which is useful in templates:
+ #
+ # <%= tag.p do %>
+ # The next great American novel starts here.
+ # <% end %>
+ # # => <p>The next great American novel starts here.</p>
+ #
+ # ==== Options
+ #
+ # Any passed options become attributes on the generated tag.
+ #
+ # tag.section class: %w( kitties puppies )
+ # # => <section class="kitties puppies"></section>
+ #
+ # tag.section id: dom_id(@post)
+ # # => <section id="<generated dom id>"></section>
+ #
+ # Pass +true+ for any attributes that can render with no values, like +disabled+ and +readonly+.
+ #
+ # tag.input type: 'text', disabled: true
+ # # => <input type="text" disabled="disabled">
+ #
+ # HTML5 <tt>data-*</tt> attributes can be set with a single +data+ key
+ # pointing to a hash of sub-attributes.
+ #
+ # To play nicely with JavaScript conventions, sub-attributes are dasherized.
+ #
+ # tag.article data: { user_id: 123 }
+ # # => <article data-user-id="123"></article>
+ #
+ # Thus <tt>data-user-id</tt> can be accessed as <tt>dataset.userId</tt>.
+ #
+ # Data attribute values are encoded to JSON, with the exception of strings, symbols and
+ # BigDecimals.
+ # This may come in handy when using jQuery's HTML5-aware <tt>.data()</tt>
+ # from 1.4.3.
+ #
+ # tag.div data: { city_state: %w( Chigaco IL ) }
+ # # => <div data-city-state="[&quot;Chicago&quot;,&quot;IL&quot;]"></div>
+ #
+ # The generated attributes are escaped by default. This can be disabled using
+ # +escape_attributes+.
+ #
+ # tag.img src: 'open & shut.png'
+ # # => <img src="open &amp; shut.png">
+ #
+ # tag.img src: 'open & shut.png', escape_attributes: false
+ # # => <img src="open & shut.png">
+ #
+ # The tag builder respects
+ # {HTML5 void elements}[https://www.w3.org/TR/html5/syntax.html#void-elements]
+ # if no content is passed, and omits closing tags for those elements.
+ #
+ # # A standard element:
+ # tag.div # => <div></div>
+ #
+ # # A void element:
+ # tag.br # => <br>
+ #
+ # === Legacy syntax
+ #
+ # The following format is for legacy syntax support. It will be deprecated in future versions of Rails.
+ #
+ # tag(name, options = nil, open = false, escape = true)
+ #
+ # It returns an empty HTML tag of type +name+ which by default is XHTML
# compliant. Set +open+ to true to create an open tag compatible
# with HTML 4.0 and below. Add HTML attributes by passing an attributes
# hash to +options+. Set +escape+ to false to disable attribute value
# escaping.
#
# ==== Options
+ #
# You can use symbols or strings for the attribute names.
#
# Use +true+ with boolean attributes that can render with no value, like
@@ -42,16 +211,8 @@ module ActionView
# HTML5 <tt>data-*</tt> attributes can be set with a single +data+ key
# pointing to a hash of sub-attributes.
#
- # To play nicely with JavaScript conventions sub-attributes are dasherized.
- # For example, a key +user_id+ would render as <tt>data-user-id</tt> and
- # thus accessed as <tt>dataset.userId</tt>.
- #
- # Values are encoded to JSON, with the exception of strings, symbols and
- # BigDecimals.
- # This may come in handy when using jQuery's HTML5-aware <tt>.data()</tt>
- # from 1.4.3.
- #
# ==== Examples
+ #
# tag("br")
# # => <br />
#
@@ -72,8 +233,12 @@ module ActionView
#
# tag("div", data: {name: 'Stephen', city_state: %w(Chicago IL)})
# # => <div data-name="Stephen" data-city-state="[&quot;Chicago&quot;,&quot;IL&quot;]" />
- def tag(name, options = nil, open = false, escape = true)
- "<#{name}#{tag_options(options, escape) if options}#{open ? ">" : " />"}".html_safe
+ def tag(name = nil, options = nil, open = false, escape = true)
+ if name.nil?
+ tag_builder
+ else
+ "<#{name}#{tag_builder.tag_options(options, escape) if options}#{open ? ">" : " />"}".html_safe
+ end
end
# Returns an HTML block tag of type +name+ surrounding the +content+. Add
@@ -81,6 +246,7 @@ module ActionView
# Instead of passing the content as an argument, you can also use a block
# in which case, you pass your +options+ as the second parameter.
# Set escape to false to disable attribute value escaping.
+ # Note: this is legacy syntax, see +tag+ method description for details.
#
# ==== Options
# The +options+ hash can be used with attributes with no value like (<tt>disabled</tt> and
@@ -104,9 +270,9 @@ module ActionView
def content_tag(name, content_or_options_with_block = nil, options = nil, escape = true, &block)
if block_given?
options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash)
- content_tag_string(name, capture(&block), options, escape)
+ tag_builder.content_tag_string(name, capture(&block), options, escape)
else
- content_tag_string(name, content_or_options_with_block, options, escape)
+ tag_builder.content_tag_string(name, content_or_options_with_block, options, escape)
end
end
@@ -140,56 +306,8 @@ module ActionView
end
private
-
- def content_tag_string(name, content, options, escape = true)
- tag_options = tag_options(options, escape) if options
- content = ERB::Util.unwrapped_html_escape(content) if escape
- "<#{name}#{tag_options}>#{PRE_CONTENT_STRINGS[name]}#{content}</#{name}>".html_safe
- end
-
- def tag_options(options, escape = true)
- return if options.blank?
- output = ""
- sep = " ".freeze
- options.each_pair do |key, value|
- if TAG_PREFIXES.include?(key) && value.is_a?(Hash)
- value.each_pair do |k, v|
- next if v.nil?
- output << sep
- output << prefix_tag_option(key, k, v, escape)
- end
- elsif BOOLEAN_ATTRIBUTES.include?(key)
- if value
- output << sep
- output << boolean_tag_option(key)
- end
- elsif !value.nil?
- output << sep
- output << tag_option(key, value, escape)
- end
- end
- output unless output.empty?
- end
-
- def prefix_tag_option(prefix, key, value, escape)
- key = "#{prefix}-#{key.to_s.dasherize}"
- unless value.is_a?(String) || value.is_a?(Symbol) || value.is_a?(BigDecimal)
- value = value.to_json
- end
- tag_option(key, value, escape)
- end
-
- def boolean_tag_option(key)
- %(#{key}="#{key}")
- end
-
- def tag_option(key, value, escape)
- if value.is_a?(Array)
- value = escape ? safe_join(value, " ".freeze) : value.join(" ".freeze)
- else
- value = escape ? ERB::Util.unwrapped_html_escape(value) : value
- end
- %(#{key}="#{value}")
+ def tag_builder
+ @tag_builder ||= TagBuilder.new(self)
end
end
end
diff --git a/actionview/lib/action_view/helpers/tags/base.rb b/actionview/lib/action_view/helpers/tags/base.rb
index d57f26ba4f..086eaa4aab 100644
--- a/actionview/lib/action_view/helpers/tags/base.rb
+++ b/actionview/lib/action_view/helpers/tags/base.rb
@@ -143,10 +143,10 @@ module ActionView
def add_options(option_tags, options, value = nil)
if options[:include_blank]
- option_tags = content_tag_string('option', options[:include_blank].kind_of?(String) ? options[:include_blank] : nil, :value => '') + "\n" + option_tags
+ option_tags = tag_builder.content_tag_string('option', options[:include_blank].kind_of?(String) ? options[:include_blank] : nil, :value => '') + "\n" + option_tags
end
if value.blank? && options[:prompt]
- option_tags = content_tag_string('option', prompt_text(options[:prompt]), :value => '') + "\n" + option_tags
+ option_tags = tag_builder.content_tag_string('option', prompt_text(options[:prompt]), :value => '') + "\n" + option_tags
end
option_tags
end
diff --git a/actionview/lib/action_view/helpers/tags/datetime_field.rb b/actionview/lib/action_view/helpers/tags/datetime_field.rb
index b2cee9d198..b3940c7e44 100644
--- a/actionview/lib/action_view/helpers/tags/datetime_field.rb
+++ b/actionview/lib/action_view/helpers/tags/datetime_field.rb
@@ -14,7 +14,7 @@ module ActionView
private
def format_date(value)
- value.try(:strftime, "%Y-%m-%dT%T.%L%z")
+ raise NotImplementedError
end
def datetime_value(value)
diff --git a/actionview/lib/action_view/helpers/tags/file_field.rb b/actionview/lib/action_view/helpers/tags/file_field.rb
index e6a1d9c62d..476b820d84 100644
--- a/actionview/lib/action_view/helpers/tags/file_field.rb
+++ b/actionview/lib/action_view/helpers/tags/file_field.rb
@@ -2,21 +2,6 @@ module ActionView
module Helpers
module Tags # :nodoc:
class FileField < TextField # :nodoc:
-
- def render
- options = @options.stringify_keys
-
- if options.fetch("include_hidden", true)
- add_default_name_and_id(options)
- options[:type] = "file"
- tag("input", name: options["name"], type: "hidden", value: "") + tag("input", options)
- else
- options.delete("include_hidden")
- @options = options
-
- super
- end
- end
end
end
end
diff --git a/actionview/lib/action_view/helpers/text_helper.rb b/actionview/lib/action_view/helpers/text_helper.rb
index 58ce042f12..fe365fafe1 100644
--- a/actionview/lib/action_view/helpers/text_helper.rb
+++ b/actionview/lib/action_view/helpers/text_helper.rb
@@ -269,10 +269,11 @@ module ActionView
end
# Returns +text+ transformed into HTML using simple formatting rules.
- # Two or more consecutive newlines(<tt>\n\n</tt>) are considered as a
- # paragraph and wrapped in <tt><p></tt> tags. One newline (<tt>\n</tt>) is
- # considered as a linebreak and a <tt><br /></tt> tag is appended. This
- # method does not remove the newlines from the +text+.
+ # Two or more consecutive newlines(<tt>\n\n</tt> or <tt>\r\n\r\n</tt>) are
+ # considered a paragraph and wrapped in <tt><p></tt> tags. One newline
+ # (<tt>\n</tt> or <tt>\r\n</tt>) is considered a linebreak and a
+ # <tt><br /></tt> tag is appended. This method does not remove the
+ # newlines from the +text+.
#
# You can pass any HTML attributes into <tt>html_options</tt>. These
# will be added to all created paragraphs.
diff --git a/actionview/lib/action_view/template/handlers/raw.rb b/actionview/lib/action_view/template/handlers/raw.rb
index 760f517431..e7519e94f9 100644
--- a/actionview/lib/action_view/template/handlers/raw.rb
+++ b/actionview/lib/action_view/template/handlers/raw.rb
@@ -2,7 +2,7 @@ module ActionView
module Template::Handlers
class Raw
def call(template)
- "#{template.source.inspect};"
+ "#{template.source.inspect}.html_safe;"
end
end
end
diff --git a/actionview/test/actionpack/controller/render_test.rb b/actionview/test/actionpack/controller/render_test.rb
index bdb9e0397b..7b69ffc628 100644
--- a/actionview/test/actionpack/controller/render_test.rb
+++ b/actionview/test/actionpack/controller/render_test.rb
@@ -726,11 +726,6 @@ class RenderTest < ActionController::TestCase
assert_equal "Elastica", @response.body
end
- def test_render_process
- get :render_action_hello_world_as_string
- assert_equal "Hello world!", @controller.process(:render_action_hello_world_as_string)
- end
-
# :ported:
def test_render_from_variable
get :render_hello_world_from_variable
diff --git a/actionview/test/activerecord/debug_helper_test.rb b/actionview/test/activerecord/debug_helper_test.rb
index 03cb1d5a91..ed1c08e134 100644
--- a/actionview/test/activerecord/debug_helper_test.rb
+++ b/actionview/test/activerecord/debug_helper_test.rb
@@ -4,7 +4,10 @@ require 'nokogiri'
class DebugHelperTest < ActionView::TestCase
def test_debug
company = Company.new(name: "firebase")
- assert_match "name: firebase", debug(company)
+ output = debug(company)
+ assert_match "name: name", output
+ assert_match "value_before_type_cast: firebase", output
+ assert_match "active_record_yaml_version: 2", output
end
def test_debug_with_marshal_error
diff --git a/actionview/test/fixtures/digestor/api/comments/_comment.json.erb b/actionview/test/fixtures/digestor/api/comments/_comment.json.erb
new file mode 100644
index 0000000000..696eb13917
--- /dev/null
+++ b/actionview/test/fixtures/digestor/api/comments/_comment.json.erb
@@ -0,0 +1 @@
+{"content": "Great story!"}
diff --git a/actionview/test/fixtures/digestor/api/comments/_comments.json.erb b/actionview/test/fixtures/digestor/api/comments/_comments.json.erb
new file mode 100644
index 0000000000..c28646a283
--- /dev/null
+++ b/actionview/test/fixtures/digestor/api/comments/_comments.json.erb
@@ -0,0 +1 @@
+<%= render partial: "comments/comment", collection: commentable.comments %>
diff --git a/actionview/test/fixtures/digestor/messages/thread.json.erb b/actionview/test/fixtures/digestor/messages/thread.json.erb
new file mode 100644
index 0000000000..e4c1ba97cd
--- /dev/null
+++ b/actionview/test/fixtures/digestor/messages/thread.json.erb
@@ -0,0 +1 @@
+<%= render "comments/comments" %>
diff --git a/actionview/test/fixtures/test/_builder_tag_nested_in_content_tag.erb b/actionview/test/fixtures/test/_builder_tag_nested_in_content_tag.erb
new file mode 100644
index 0000000000..ddad7ec3ac
--- /dev/null
+++ b/actionview/test/fixtures/test/_builder_tag_nested_in_content_tag.erb
@@ -0,0 +1,3 @@
+<%= tag.p do %>
+ <%= tag.b 'Hello' %>
+<% end %>
diff --git a/actionview/test/template/asset_tag_helper_test.rb b/actionview/test/template/asset_tag_helper_test.rb
index 8bfd19eb26..1a1b6f5e2d 100644
--- a/actionview/test/template/asset_tag_helper_test.rb
+++ b/actionview/test/template/asset_tag_helper_test.rb
@@ -238,7 +238,7 @@ class AssetTagHelperTest < ActionView::TestCase
VideoLinkToTag = {
%(video_tag("xml.ogg")) => %(<video src="/videos/xml.ogg"></video>),
%(video_tag("rss.m4v", :autoplay => true, :controls => true)) => %(<video autoplay="autoplay" controls="controls" src="/videos/rss.m4v"></video>),
- %(video_tag("rss.m4v", :autobuffer => true)) => %(<video autobuffer="autobuffer" src="/videos/rss.m4v"></video>),
+ %(video_tag("rss.m4v", :preload => 'none')) => %(<video preload="none" src="/videos/rss.m4v"></video>),
%(video_tag("gold.m4v", :size => "160x120")) => %(<video height="120" src="/videos/gold.m4v" width="160"></video>),
%(video_tag("gold.m4v", "size" => "320x240")) => %(<video height="240" src="/videos/gold.m4v" width="320"></video>),
%(video_tag("trailer.ogg", :poster => "screenshot.png")) => %(<video poster="/images/screenshot.png" src="/videos/trailer.ogg"></video>),
@@ -288,7 +288,7 @@ class AssetTagHelperTest < ActionView::TestCase
%(audio_tag("//media.rubyonrails.org/audio/rails_blog_2.mov")) => %(<audio src="//media.rubyonrails.org/audio/rails_blog_2.mov"></audio>),
%(audio_tag("audio.mp3", "audio.ogg")) => %(<audio><source src="/audios/audio.mp3" /><source src="/audios/audio.ogg" /></audio>),
%(audio_tag(["audio.mp3", "audio.ogg"])) => %(<audio><source src="/audios/audio.mp3" /><source src="/audios/audio.ogg" /></audio>),
- %(audio_tag(["audio.mp3", "audio.ogg"], :autobuffer => true, :controls => true)) => %(<audio autobuffer="autobuffer" controls="controls"><source src="/audios/audio.mp3" /><source src="/audios/audio.ogg" /></audio>)
+ %(audio_tag(["audio.mp3", "audio.ogg"], :preload => 'none', :controls => true)) => %(<audio preload="none" controls="controls"><source src="/audios/audio.mp3" /><source src="/audios/audio.ogg" /></audio>)
}
FontPathToTag = {
diff --git a/actionview/test/template/date_helper_test.rb b/actionview/test/template/date_helper_test.rb
index e67d5d0e8c..3b4d4f42e5 100644
--- a/actionview/test/template/date_helper_test.rb
+++ b/actionview/test/template/date_helper_test.rb
@@ -534,6 +534,13 @@ class DateHelperTest < ActionView::TestCase
assert_dom_equal expected, select_year(nil, start_year: 2003, end_year: 2005, with_css_classes: { year: 'my-year' })
end
+
+ def test_select_year_with_position
+ expected = %(<select id="date_year_1i" name="date[year(1i)]">\n)
+ expected << %(<option value="2003">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n)
+ expected << "</select>\n"
+ assert_dom_equal expected, select_year(Date.current, include_position: true, start_year: 2003, end_year: 2005)
+ end
def test_select_hour
expected = %(<select id="date_hour" name="date[hour]">\n)
@@ -3602,10 +3609,6 @@ class DateHelperTest < ActionView::TestCase
assert_equal expected, time_tag(time)
end
- def test_time_tag_pubdate_option
- assert_match(/<time.*pubdate="pubdate">.*<\/time>/, time_tag(Time.now, :pubdate => true))
- end
-
def test_time_tag_with_given_text
assert_match(/<time.*>Right now<\/time>/, time_tag(Time.now, 'Right now'))
end
diff --git a/actionview/test/template/digestor_test.rb b/actionview/test/template/digestor_test.rb
index 4750d2a5a3..410f562f07 100644
--- a/actionview/test/template/digestor_test.rb
+++ b/actionview/test/template/digestor_test.rb
@@ -17,7 +17,14 @@ class FixtureFinder < ActionView::LookupContext
FIXTURES_DIR = "#{File.dirname(__FILE__)}/../fixtures/digestor"
def initialize(details = {})
- super(ActionView::PathSet.new(['digestor']), details, [])
+ super(ActionView::PathSet.new(['digestor', 'digestor/api']), details, [])
+ @rendered_format = :html
+ end
+end
+
+class ActionView::Digestor::Node
+ def flatten
+ [self] + children.flat_map(&:flatten)
end
end
@@ -147,6 +154,21 @@ class TemplateDigestorTest < ActionView::TestCase
assert_equal nested_deps, nested_dependencies("messages/show")
end
+ def test_nested_template_deps_with_non_default_rendered_format
+ finder.rendered_format = nil
+ nested_deps = [{"comments/comments"=>["comments/comment"]}]
+ assert_equal nested_deps, nested_dependencies("messages/thread")
+ end
+
+ def test_template_formats_of_nested_deps_with_non_default_rendered_format
+ finder.rendered_format = nil
+ assert_equal [:json], tree_template_formats("messages/thread").uniq
+ end
+
+ def test_template_formats_of_dependencies_with_same_logical_name_and_different_rendered_format
+ assert_equal [:html], tree_template_formats("messages/show").uniq
+ end
+
def test_recursion_in_renders
assert digest("level/recursion") # assert recursion is possible
assert_not_nil digest("level/recursion") # assert digest is stored
@@ -258,6 +280,13 @@ class TemplateDigestorTest < ActionView::TestCase
assert_not_equal digest_phone, digest_fridge_phone
end
+ def test_different_formats_with_same_logical_template_names_results_in_different_digests
+ html_digest = digest("comments/_comment", format: :html)
+ json_digest = digest("comments/_comment", format: :json)
+
+ assert_not_equal html_digest, json_digest
+ end
+
def test_digest_cache_cleanup_with_recursion
first_digest = digest("level/_recursion")
second_digest = digest("level/_recursion")
@@ -280,7 +309,6 @@ class TemplateDigestorTest < ActionView::TestCase
end
end
-
private
def assert_logged(message)
old_logger = ActionView::Base.logger
@@ -309,8 +337,11 @@ class TemplateDigestorTest < ActionView::TestCase
def digest(template_name, options = {})
options = options.dup
+ finder_options = options.extract!(:variants, :format)
+
+ finder.variants = finder_options[:variants] || []
+ finder.rendered_format = finder_options[:format] if finder_options[:format]
- finder.variants = options.delete(:variants) || []
ActionView::Digestor.digest(name: template_name, finder: finder, dependencies: (options[:dependencies] || []))
end
@@ -324,6 +355,11 @@ class TemplateDigestorTest < ActionView::TestCase
tree.children.map(&:to_dep_map)
end
+ def tree_template_formats(template_name)
+ tree = ActionView::Digestor.tree(template_name, finder)
+ tree.flatten.map(&:template).compact.flat_map(&:formats)
+ end
+
def disable_resolver_caching
old_caching, ActionView::Resolver.caching = ActionView::Resolver.caching, false
yield
diff --git a/actionview/test/template/form_helper_test.rb b/actionview/test/template/form_helper_test.rb
index 310d0ce514..54da2b0c9c 100644
--- a/actionview/test/template/form_helper_test.rb
+++ b/actionview/test/template/form_helper_test.rb
@@ -528,33 +528,18 @@ class FormHelperTest < ActionView::TestCase
assert_dom_equal expected, text_field(object_name, "title")
end
- def test_file_field_does_generate_a_hidden_field
- expected = '<input name="user[avatar]" type="hidden" value="" /><input id="user_avatar" name="user[avatar]" type="file" />'
- assert_dom_equal expected, file_field("user", "avatar")
- end
-
- def test_file_field_does_not_generate_a_hidden_field_if_included_hidden_option_is_false
- expected = '<input id="user_avatar" name="user[avatar]" type="file" />'
- assert_dom_equal expected, file_field("user", "avatar", include_hidden: false)
- end
-
- def test_file_field_does_not_generate_a_hidden_field_if_included_hidden_option_is_false_with_key_as_string
- expected = '<input id="user_avatar" name="user[avatar]" type="file" />'
- assert_dom_equal expected, file_field("user", "avatar", "include_hidden" => false)
- end
-
def test_file_field_has_no_size
- expected = '<input name="user[avatar]" type="hidden" value="" /><input id="user_avatar" name="user[avatar]" type="file" />'
+ expected = '<input id="user_avatar" name="user[avatar]" type="file" />'
assert_dom_equal expected, file_field("user", "avatar")
end
def test_file_field_with_multiple_behavior
- expected = '<input name="import[file][]" type="hidden" value="" /><input id="import_file" multiple="multiple" name="import[file][]" type="file" />'
+ expected = '<input id="import_file" multiple="multiple" name="import[file][]" type="file" />'
assert_dom_equal expected, file_field("import", "file", :multiple => true)
end
def test_file_field_with_multiple_behavior_and_explicit_name
- expected = '<input name="custom" type="hidden" value="" /><input id="import_file" multiple="multiple" name="custom" type="file" />'
+ expected = '<input id="import_file" multiple="multiple" name="custom" type="file" />'
assert_dom_equal expected, file_field("import", "file", :multiple => true, :name => "custom")
end
@@ -1138,76 +1123,60 @@ class FormHelperTest < ActionView::TestCase
end
def test_datetime_field
- expected = %{<input id="post_written_on" name="post[written_on]" type="datetime" value="2004-06-15T00:00:00.000+0000" />}
- assert_deprecated do
- assert_dom_equal(expected, datetime_field("post", "written_on"))
- end
+ expected = %{<input id="post_written_on" name="post[written_on]" type="datetime-local" value="2004-06-15T00:00:00" />}
+ assert_dom_equal(expected, datetime_field("post", "written_on"))
end
def test_datetime_field_with_datetime_value
- expected = %{<input id="post_written_on" name="post[written_on]" type="datetime" value="2004-06-15T01:02:03.000+0000" />}
+ expected = %{<input id="post_written_on" name="post[written_on]" type="datetime-local" value="2004-06-15T01:02:03" />}
@post.written_on = DateTime.new(2004, 6, 15, 1, 2, 3)
- assert_deprecated do
- assert_dom_equal(expected, datetime_field("post", "written_on"))
- end
+ assert_dom_equal(expected, datetime_field("post", "written_on"))
end
def test_datetime_field_with_extra_attrs
- expected = %{<input id="post_written_on" step="60" max="2010-08-15T10:25:00.000+0000" min="2000-06-15T20:45:30.000+0000" name="post[written_on]" type="datetime" value="2004-06-15T01:02:03.000+0000" />}
+ expected = %{<input id="post_written_on" step="60" max="2010-08-15T10:25:00" min="2000-06-15T20:45:30" name="post[written_on]" type="datetime-local" value="2004-06-15T01:02:03" />}
@post.written_on = DateTime.new(2004, 6, 15, 1, 2, 3)
min_value = DateTime.new(2000, 6, 15, 20, 45, 30)
max_value = DateTime.new(2010, 8, 15, 10, 25, 00)
step = 60
- assert_deprecated do
- assert_dom_equal(expected, datetime_field("post", "written_on", min: min_value, max: max_value, step: step))
- end
+ assert_dom_equal(expected, datetime_field("post", "written_on", min: min_value, max: max_value, step: step))
end
def test_datetime_field_with_value_attr
- expected = %{<input id="post_written_on" name="post[written_on]" type="datetime" value="2013-06-29T13:37:00+00:00" />}
+ expected = %{<input id="post_written_on" name="post[written_on]" type="datetime-local" value="2013-06-29T13:37:00+00:00" />}
value = DateTime.new(2013,6,29,13,37)
- assert_deprecated do
- assert_dom_equal(expected, datetime_field("post", "written_on", value: value))
- end
+ assert_dom_equal(expected, datetime_field("post", "written_on", value: value))
end
def test_datetime_field_with_timewithzone_value
previous_time_zone, Time.zone = Time.zone, 'UTC'
- expected = %{<input id="post_written_on" name="post[written_on]" type="datetime" value="2004-06-15T15:30:45.000+0000" />}
+ expected = %{<input id="post_written_on" name="post[written_on]" type="datetime-local" value="2004-06-15T15:30:45" />}
@post.written_on = Time.zone.parse('2004-06-15 15:30:45')
- assert_deprecated do
- assert_dom_equal(expected, datetime_field("post", "written_on"))
- end
+ assert_dom_equal(expected, datetime_field("post", "written_on"))
ensure
Time.zone = previous_time_zone
end
def test_datetime_field_with_nil_value
- expected = %{<input id="post_written_on" name="post[written_on]" type="datetime" />}
+ expected = %{<input id="post_written_on" name="post[written_on]" type="datetime-local" />}
@post.written_on = nil
- assert_deprecated do
- assert_dom_equal(expected, datetime_field("post", "written_on"))
- end
+ assert_dom_equal(expected, datetime_field("post", "written_on"))
end
def test_datetime_field_with_string_values_for_min_and_max
- expected = %{<input id="post_written_on" max="2010-08-15T10:25:00.000+0000" min="2000-06-15T20:45:30.000+0000" name="post[written_on]" type="datetime" value="2004-06-15T01:02:03.000+0000" />}
+ expected = %{<input id="post_written_on" max="2010-08-15T10:25:00" min="2000-06-15T20:45:30" name="post[written_on]" type="datetime-local" value="2004-06-15T01:02:03" />}
@post.written_on = DateTime.new(2004, 6, 15, 1, 2, 3)
- min_value = "2000-06-15T20:45:30.000+0000"
- max_value = "2010-08-15T10:25:00.000+0000"
- assert_deprecated do
- assert_dom_equal(expected, datetime_field("post", "written_on", min: min_value, max: max_value))
- end
+ min_value = "2000-06-15T20:45:30"
+ max_value = "2010-08-15T10:25:00"
+ assert_dom_equal(expected, datetime_field("post", "written_on", min: min_value, max: max_value))
end
def test_datetime_field_with_invalid_string_values_for_min_and_max
- expected = %{<input id="post_written_on" name="post[written_on]" type="datetime" value="2004-06-15T01:02:03.000+0000" />}
+ expected = %{<input id="post_written_on" name="post[written_on]" type="datetime-local" value="2004-06-15T01:02:03" />}
@post.written_on = DateTime.new(2004, 6, 15, 1, 2, 3)
min_value = "foo"
max_value = "bar"
- assert_deprecated do
- assert_dom_equal(expected, datetime_field("post", "written_on", min: min_value, max: max_value))
- end
+ assert_dom_equal(expected, datetime_field("post", "written_on", min: min_value, max: max_value))
end
def test_datetime_local_field
@@ -1215,52 +1184,6 @@ class FormHelperTest < ActionView::TestCase
assert_dom_equal(expected, datetime_local_field("post", "written_on"))
end
- def test_datetime_local_field_with_datetime_value
- expected = %{<input id="post_written_on" name="post[written_on]" type="datetime-local" value="2004-06-15T01:02:03" />}
- @post.written_on = DateTime.new(2004, 6, 15, 1, 2, 3)
- assert_dom_equal(expected, datetime_local_field("post", "written_on"))
- end
-
- def test_datetime_local_field_with_extra_attrs
- expected = %{<input id="post_written_on" step="60" max="2010-08-15T10:25:00" min="2000-06-15T20:45:30" name="post[written_on]" type="datetime-local" value="2004-06-15T01:02:03" />}
- @post.written_on = DateTime.new(2004, 6, 15, 1, 2, 3)
- min_value = DateTime.new(2000, 6, 15, 20, 45, 30)
- max_value = DateTime.new(2010, 8, 15, 10, 25, 00)
- step = 60
- assert_dom_equal(expected, datetime_local_field("post", "written_on", min: min_value, max: max_value, step: step))
- end
-
- def test_datetime_local_field_with_timewithzone_value
- previous_time_zone, Time.zone = Time.zone, 'UTC'
- expected = %{<input id="post_written_on" name="post[written_on]" type="datetime-local" value="2004-06-15T15:30:45" />}
- @post.written_on = Time.zone.parse('2004-06-15 15:30:45')
- assert_dom_equal(expected, datetime_local_field("post", "written_on"))
- ensure
- Time.zone = previous_time_zone
- end
-
- def test_datetime_local_field_with_nil_value
- expected = %{<input id="post_written_on" name="post[written_on]" type="datetime-local" />}
- @post.written_on = nil
- assert_dom_equal(expected, datetime_local_field("post", "written_on"))
- end
-
- def test_datetime_local_field_with_string_values_for_min_and_max
- expected = %{<input id="post_written_on" max="2010-08-15T10:25:00" min="2000-06-15T20:45:30" name="post[written_on]" type="datetime-local" value="2004-06-15T01:02:03" />}
- @post.written_on = DateTime.new(2004, 6, 15, 1, 2, 3)
- min_value = "2000-06-15T20:45:30"
- max_value = "2010-08-15T10:25:00"
- assert_dom_equal(expected, datetime_local_field("post", "written_on", min: min_value, max: max_value))
- end
-
- def test_datetime_local_field_with_invalid_string_values_for_min_and_max
- expected = %{<input id="post_written_on" name="post[written_on]" type="datetime-local" value="2004-06-15T01:02:03" />}
- @post.written_on = DateTime.new(2004, 6, 15, 1, 2, 3)
- min_value = "foo"
- max_value = "bar"
- assert_dom_equal(expected, datetime_local_field("post", "written_on", min: min_value, max: max_value))
- end
-
def test_month_field
expected = %{<input id="post_written_on" name="post[written_on]" type="month" value="2004-06" />}
assert_dom_equal(expected, month_field("post", "written_on"))
@@ -1838,7 +1761,7 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form("/posts/123", "create-post", "edit_post", method: "patch", multipart: true) do
- "<input name='post[file]' type='hidden' value='' /><input name='post[file]' type='file' id='post_file' />"
+ "<input name='post[file]' type='file' id='post_file' />"
end
assert_dom_equal expected, output_buffer
@@ -1854,7 +1777,7 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form("/posts/123", "edit_post_123", "edit_post", method: "patch", multipart: true) do
- "<input name='post[comment][file]' type='hidden' value='' /><input name='post[comment][file]' type='file' id='post_comment_file' />"
+ "<input name='post[comment][file]' type='file' id='post_comment_file' />"
end
assert_dom_equal expected, output_buffer
diff --git a/actionview/test/template/form_options_helper_test.rb b/actionview/test/template/form_options_helper_test.rb
index 7a5904f151..a85f2da264 100644
--- a/actionview/test/template/form_options_helper_test.rb
+++ b/actionview/test/template/form_options_helper_test.rb
@@ -738,7 +738,7 @@ class FormOptionsHelperTest < ActionView::TestCase
)
end
- def test_empty
+ def test_select_with_empty
@post = Post.new
@post.category = ""
assert_dom_equal(
@@ -747,6 +747,15 @@ class FormOptionsHelperTest < ActionView::TestCase
)
end
+ def test_select_with_html_options
+ @post = Post.new
+ @post.category = ""
+ assert_dom_equal(
+ "<select class=\"disabled\" disabled=\"disabled\" name=\"post[category]\" id=\"post_category\"><option value=\"\">Please select</option>\n<option value=\"\"></option>\n</select>",
+ select("post", "category", [], { prompt: true, include_blank: true }, { class: 'disabled', disabled: true })
+ )
+ end
+
def test_select_with_nil
@post = Post.new
@post.category = "othervalue"
diff --git a/actionview/test/template/form_tag_helper_test.rb b/actionview/test/template/form_tag_helper_test.rb
index 5b0b708618..4fdca4976f 100644
--- a/actionview/test/template/form_tag_helper_test.rb
+++ b/actionview/test/template/form_tag_helper_test.rb
@@ -621,10 +621,8 @@ class FormTagHelperTest < ActionView::TestCase
end
def test_datetime_field_tag
- expected = %{<input id="appointment" name="appointment" type="datetime" />}
- assert_deprecated do
- assert_dom_equal(expected, datetime_field_tag("appointment"))
- end
+ expected = %{<input id="appointment" name="appointment" type="datetime-local" />}
+ assert_dom_equal(expected, datetime_field_tag("appointment"))
end
def test_datetime_local_field_tag
diff --git a/actionview/test/template/render_test.rb b/actionview/test/template/render_test.rb
index ad93236d32..25b21850b1 100644
--- a/actionview/test/template/render_test.rb
+++ b/actionview/test/template/render_test.rb
@@ -100,6 +100,13 @@ module RenderTestCases
assert_equal %q;Here are some characters: !@#$%^&*()-="'}{`; + "\n", @view.render(:template => "plain_text_with_characters")
end
+ def test_render_raw_is_html_safe_and_does_not_escape_output
+ buffer = ActiveSupport::SafeBuffer.new
+ buffer << @view.render(file: "plain_text")
+ assert_equal true, buffer.html_safe?
+ assert_equal buffer, "<%= hello_world %>\n"
+ end
+
def test_render_ruby_template_with_handlers
assert_equal "Hello from Ruby code", @view.render(:template => "ruby_template")
end
diff --git a/actionview/test/template/tag_helper_test.rb b/actionview/test/template/tag_helper_test.rb
index f3956a31f6..4ed3252c63 100644
--- a/actionview/test/template/tag_helper_test.rb
+++ b/actionview/test/template/tag_helper_test.rb
@@ -11,6 +11,24 @@ class TagHelperTest < ActionView::TestCase
assert_equal "<br>", tag("br", nil, true)
end
+ def test_tag_builder
+ assert_equal "<span></span>", tag.span
+ assert_equal "<span class=\"bookmark\"></span>", tag.span(class: "bookmark")
+ end
+
+ def test_tag_builder_void_tag
+ assert_equal "<br>", tag.br
+ assert_equal "<br class=\"some_class\">", tag.br(class: 'some_class')
+ end
+
+ def test_tag_builder_void_tag_with_forced_content
+ assert_equal "<br>some content</br>", tag.br("some content")
+ end
+
+ def test_tag_builder_is_singleton
+ assert_equal tag, tag
+ end
+
def test_tag_options
str = tag("p", "class" => "show", :class => "elsewhere")
assert_match(/class="show"/, str)
@@ -21,19 +39,36 @@ class TagHelperTest < ActionView::TestCase
assert_equal "<p />", tag("p", :ignored => nil)
end
+ def test_tag_builder_options_rejects_nil_option
+ assert_equal "<p></p>", tag.p(ignored: nil)
+ end
+
def test_tag_options_accepts_false_option
assert_equal "<p value=\"false\" />", tag("p", :value => false)
end
+ def test_tag_builder_options_accepts_false_option
+ assert_equal "<p value=\"false\"></p>", tag.p(value: false)
+ end
+
def test_tag_options_accepts_blank_option
assert_equal "<p included=\"\" />", tag("p", :included => '')
end
+ def test_tag_builder_options_accepts_blank_option
+ assert_equal "<p included=\"\"></p>", tag.p(included: '')
+ end
+
def test_tag_options_converts_boolean_option
assert_dom_equal '<p disabled="disabled" itemscope="itemscope" multiple="multiple" readonly="readonly" allowfullscreen="allowfullscreen" seamless="seamless" typemustmatch="typemustmatch" sortable="sortable" default="default" inert="inert" truespeed="truespeed" />',
tag("p", :disabled => true, :itemscope => true, :multiple => true, :readonly => true, :allowfullscreen => true, :seamless => true, :typemustmatch => true, :sortable => true, :default => true, :inert => true, :truespeed => true)
end
+ def test_tag_builder_options_converts_boolean_option
+ assert_dom_equal '<p disabled="disabled" itemscope="itemscope" multiple="multiple" readonly="readonly" allowfullscreen="allowfullscreen" seamless="seamless" typemustmatch="typemustmatch" sortable="sortable" default="default" inert="inert" truespeed="truespeed" />',
+ tag.p(disabled: true, itemscope: true, multiple: true, readonly: true, allowfullscreen: true, seamless: true, typemustmatch: true, sortable: true, default: true, inert: true, truespeed: true)
+ end
+
def test_content_tag
assert_equal "<a href=\"create\">Create</a>", content_tag("a", "Create", "href" => "create")
assert content_tag("a", "Create", "href" => "create").html_safe?
@@ -45,43 +80,96 @@ class TagHelperTest < ActionView::TestCase
content_tag(:p, '<script>evil_js</script>', nil, false)
end
+ def test_tag_builder_with_content
+ assert_equal "<div id=\"post_1\">Content</div>", tag.div("Content", id: "post_1")
+ assert tag.div("Content", id: "post_1").html_safe?
+ assert_equal tag.div("Content", id: "post_1"),
+ tag.div("Content", "id": "post_1")
+ assert_equal "<p>&lt;script&gt;evil_js&lt;/script&gt;</p>",
+ tag.p("<script>evil_js</script>")
+ assert_equal "<p><script>evil_js</script></p>",
+ tag.p('<script>evil_js</script>', escape_attributes: false)
+ end
+
+ def test_tag_builder_nested
+ assert_equal "<div>content</div>",
+ tag.div { "content" }
+ assert_equal "<div id=\"header\"><span>hello</span></div>",
+ tag.div(id: 'header') { |tag| tag.span 'hello' }
+ assert_equal "<div id=\"header\"><div class=\"world\"><span>hello</span></div></div>",
+ tag.div(id: 'header') { |tag| tag.div(class: 'world') { tag.span 'hello' } }
+ end
+
def test_content_tag_with_block_in_erb
buffer = render_erb("<%= content_tag(:div) do %>Hello world!<% end %>")
assert_dom_equal "<div>Hello world!</div>", buffer
end
+ def test_tag_builder_with_block_in_erb
+ buffer = render_erb("<%= tag.div do %>Hello world!<% end %>")
+ assert_dom_equal "<div>Hello world!</div>", buffer
+ end
+
def test_content_tag_with_block_in_erb_containing_non_displayed_erb
buffer = render_erb("<%= content_tag(:p) do %><% 1 %><% end %>")
assert_dom_equal "<p></p>", buffer
end
+ def test_tag_builder_with_block_in_erb_containing_non_displayed_erb
+ buffer = render_erb("<%= tag.p do %><% 1 %><% end %>")
+ assert_dom_equal "<p></p>", buffer
+ end
+
def test_content_tag_with_block_and_options_in_erb
buffer = render_erb("<%= content_tag(:div, :class => 'green') do %>Hello world!<% end %>")
assert_dom_equal %(<div class="green">Hello world!</div>), buffer
end
+ def test_tag_builder_with_block_and_options_in_erb
+ buffer = render_erb("<%= tag.div(class: 'green') do %>Hello world!<% end %>")
+ assert_dom_equal %(<div class="green">Hello world!</div>), buffer
+ end
+
def test_content_tag_with_block_and_options_out_of_erb
assert_dom_equal %(<div class="green">Hello world!</div>), content_tag(:div, :class => "green") { "Hello world!" }
end
+ def test_tag_builder_with_block_and_options_out_of_erb
+ assert_dom_equal %(<div class="green">Hello world!</div>), tag.div(class: "green") { "Hello world!" }
+ end
+
def test_content_tag_with_block_and_options_outside_out_of_erb
assert_equal content_tag("a", "Create", :href => "create"),
content_tag("a", "href" => "create") { "Create" }
end
+ def test_tag_builder_with_block_and_options_outside_out_of_erb
+ assert_equal tag.a("Create", href: "create"),
+ tag.a("href": "create") { "Create" }
+ end
+
def test_content_tag_with_block_and_non_string_outside_out_of_erb
assert_equal content_tag("p"),
content_tag("p") { 3.times { "do_something" } }
end
+ def test_tag_builder_with_block_and_non_string_outside_out_of_erb
+ assert_equal tag.p,
+ tag.p { 3.times { "do_something" } }
+ end
+
def test_content_tag_nested_in_content_tag_out_of_erb
assert_equal content_tag("p", content_tag("b", "Hello")),
content_tag("p") { content_tag("b", "Hello") },
output_buffer
+ assert_equal tag.p(tag.b("Hello")),
+ tag.p {tag.b("Hello") },
+ output_buffer
end
def test_content_tag_nested_in_content_tag_in_erb
assert_equal "<p>\n <b>Hello</b>\n</p>", view.render("test/content_tag_nested_in_content_tag")
+ assert_equal "<p>\n <b>Hello</b>\n</p>", view.render("test/builder_tag_nested_in_content_tag")
end
def test_content_tag_with_escaped_array_class
@@ -95,6 +183,17 @@ class TagHelperTest < ActionView::TestCase
assert_equal "<p class=\"song play\">limelight</p>", str
end
+ def test_tag_builder_with_escaped_array_class
+ str = tag.p "limelight", class: ["song", "play>"]
+ assert_equal "<p class=\"song play&gt;\">limelight</p>", str
+
+ str = tag.p "limelight", class: ["song", "play"]
+ assert_equal "<p class=\"song play\">limelight</p>", str
+
+ str = tag.p "limelight", class: ["song", ["play"]]
+ assert_equal "<p class=\"song play\">limelight</p>", str
+ end
+
def test_content_tag_with_unescaped_array_class
str = content_tag('p', "limelight", {:class => ["song", "play>"]}, false)
assert_equal "<p class=\"song play>\">limelight</p>", str
@@ -103,21 +202,43 @@ class TagHelperTest < ActionView::TestCase
assert_equal "<p class=\"song play>\">limelight</p>", str
end
+ def test_tag_builder_with_unescaped_array_class
+ str = tag.p "limelight", class: ["song", "play>"], escape_attributes: false
+ assert_equal "<p class=\"song play>\">limelight</p>", str
+
+ str = tag.p "limelight", class: ["song", ["play>"]], escape_attributes: false
+ assert_equal "<p class=\"song play>\">limelight</p>", str
+ end
+
def test_content_tag_with_empty_array_class
str = content_tag('p', 'limelight', {:class => []})
assert_equal '<p class="">limelight</p>', str
end
+ def test_tag_builder_with_empty_array_class
+ assert_equal '<p class="">limelight</p>', tag.p('limelight', class: [])
+ end
+
def test_content_tag_with_unescaped_empty_array_class
str = content_tag('p', 'limelight', {:class => []}, false)
assert_equal '<p class="">limelight</p>', str
end
+ def test_tag_builder_with_unescaped_empty_array_class
+ str = tag.p 'limelight', class: [], escape_attributes: false
+ assert_equal '<p class="">limelight</p>', str
+ end
+
def test_content_tag_with_data_attributes
assert_dom_equal '<p data-number="1" data-string="hello" data-string-with-quotes="double&quot;quote&quot;party&quot;">limelight</p>',
content_tag('p', "limelight", data: { number: 1, string: 'hello', string_with_quotes: 'double"quote"party"' })
end
+ def test_tag_builder_with_data_attributes
+ assert_dom_equal '<p data-number="1" data-string="hello" data-string-with-quotes="double&quot;quote&quot;party&quot;">limelight</p>',
+ tag.p("limelight", data: { number: 1, string: 'hello', string_with_quotes: 'double"quote"party"' })
+ end
+
def test_cdata_section
assert_equal "<![CDATA[<hello world>]]>", cdata_section("<hello world>")
end
@@ -139,20 +260,24 @@ class TagHelperTest < ActionView::TestCase
def test_tag_honors_html_safe_for_param_values
['1&amp;2', '1 &lt; 2', '&#8220;test&#8220;'].each do |escaped|
assert_equal %(<a href="#{escaped}" />), tag('a', :href => escaped.html_safe)
+ assert_equal %(<a href="#{escaped}"></a>), tag.a(href: escaped.html_safe)
end
end
def test_tag_honors_html_safe_with_escaped_array_class
- str = tag('p', :class => ['song>', raw('play>')])
- assert_equal '<p class="song&gt; play>" />', str
+ assert_equal '<p class="song&gt; play>" />', tag('p', :class => ['song>', raw('play>')])
+ assert_equal '<p class="song> play&gt;" />', tag('p', :class => [raw('song>'), 'play>'])
+ end
- str = tag('p', :class => [raw('song>'), 'play>'])
- assert_equal '<p class="song> play&gt;" />', str
+ def test_tag_builder_honors_html_safe_with_escaped_array_class
+ assert_equal '<p class="song&gt; play>"></p>', tag.p(class: ['song>', raw('play>')])
+ assert_equal '<p class="song> play&gt;"></p>', tag.p(class: [raw('song>'), 'play>'])
end
def test_skip_invalid_escaped_attributes
['&1;', '&#1dfa3;', '& #123;'].each do |escaped|
assert_equal %(<a href="#{escaped.gsub(/&/, '&amp;')}" />), tag('a', :href => escaped)
+ assert_equal %(<a href="#{escaped.gsub(/&/, '&amp;')}"></a>), tag.a(href: escaped)
end
end
@@ -160,10 +285,20 @@ class TagHelperTest < ActionView::TestCase
assert_equal '<a href="&amp;" />', tag('a', { :href => '&amp;' }, false, false)
end
+ def test_tag_builder_disable_escaping
+ assert_equal '<a href="&amp;"></a>', tag.a(href: '&amp;', escape_attributes: false)
+ assert_equal '<a href="&amp;">cnt</a>', tag.a(href: '&amp;' , escape_attributes: false) { "cnt"}
+ assert_equal '<br data-hidden="&amp;">', tag.br("data-hidden": '&amp;' , escape_attributes: false)
+ assert_equal '<a href="&amp;">content</a>', tag.a("content", href: '&amp;', escape_attributes: false)
+ assert_equal '<a href="&amp;">content</a>', tag.a(href: '&amp;', escape_attributes: false) { "content"}
+ end
+
def test_data_attributes
['data', :data].each { |data|
assert_dom_equal '<a data-a-float="3.14" data-a-big-decimal="-123.456" data-a-number="1" data-array="[1,2,3]" data-hash="{&quot;key&quot;:&quot;value&quot;}" data-string-with-quotes="double&quot;quote&quot;party&quot;" data-string="hello" data-symbol="foo" />',
tag('a', { data => { a_float: 3.14, a_big_decimal: BigDecimal.new("-123.456"), a_number: 1, string: 'hello', symbol: :foo, array: [1, 2, 3], hash: { key: 'value'}, string_with_quotes: 'double"quote"party"' } })
+ assert_dom_equal '<a data-a-float="3.14" data-a-big-decimal="-123.456" data-a-number="1" data-array="[1,2,3]" data-hash="{&quot;key&quot;:&quot;value&quot;}" data-string-with-quotes="double&quot;quote&quot;party&quot;" data-string="hello" data-symbol="foo" />',
+ tag.a(data: { a_float: 3.14, a_big_decimal: BigDecimal.new("-123.456"), a_number: 1, string: 'hello', symbol: :foo, array: [1, 2, 3], hash: { key: 'value'}, string_with_quotes: 'double"quote"party"' })
}
end
@@ -171,6 +306,8 @@ class TagHelperTest < ActionView::TestCase
['aria', :aria].each { |aria|
assert_dom_equal '<a aria-a-float="3.14" aria-a-big-decimal="-123.456" aria-a-number="1" aria-array="[1,2,3]" aria-hash="{&quot;key&quot;:&quot;value&quot;}" aria-string-with-quotes="double&quot;quote&quot;party&quot;" aria-string="hello" aria-symbol="foo" />',
tag('a', { aria => { a_float: 3.14, a_big_decimal: BigDecimal.new("-123.456"), a_number: 1, string: 'hello', symbol: :foo, array: [1, 2, 3], hash: { key: 'value'}, string_with_quotes: 'double"quote"party"' } })
+ assert_dom_equal '<a aria-a-float="3.14" aria-a-big-decimal="-123.456" aria-a-number="1" aria-array="[1,2,3]" aria-hash="{&quot;key&quot;:&quot;value&quot;}" aria-string-with-quotes="double&quot;quote&quot;party&quot;" aria-string="hello" aria-symbol="foo" />',
+ tag.a(aria: { a_float: 3.14, a_big_decimal: BigDecimal.new("-123.456"), a_number: 1, string: 'hello', symbol: :foo, array: [1, 2, 3], hash: { key: 'value'}, string_with_quotes: 'double"quote"party"' })
}
end
@@ -179,4 +316,23 @@ class TagHelperTest < ActionView::TestCase
div_type2 = content_tag(:div, 'test', { data: {tooltip: nil} })
assert_dom_equal div_type1, div_type2
end
+
+ def test_tag_builder_link_to_data_nil_equal
+ div_type1 = tag.div 'test', { 'data-tooltip': nil }
+ div_type2 = tag.div 'test', { data: {tooltip: nil} }
+ assert_dom_equal div_type1, div_type2
+ end
+
+ def test_tag_builder_allow_call_via_method_object
+ assert_equal "<foo></foo>", tag.method(:foo).call
+ end
+
+ def test_tag_builder_dasherize_names
+ assert_equal "<img-slider></img-slider>", tag.img_slider
+ end
+
+ def test_respond_to
+ assert_respond_to tag, :any_tag
+ end
+
end
diff --git a/activejob/lib/active_job/logging.rb b/activejob/lib/active_job/logging.rb
index 605057d1e8..d5c7920131 100644
--- a/activejob/lib/active_job/logging.rb
+++ b/activejob/lib/active_job/logging.rb
@@ -41,7 +41,7 @@ module ActiveJob
def tag_logger(*tags)
if logger.respond_to?(:tagged)
tags.unshift "ActiveJob" unless logger_tagged_by_active_job?
- ActiveJob::Base.logger.tagged(*tags){ yield }
+ logger.tagged(*tags){ yield }
else
yield
end
diff --git a/activejob/lib/active_job/queue_adapters/sucker_punch_adapter.rb b/activejob/lib/active_job/queue_adapters/sucker_punch_adapter.rb
index 311109e958..163c8eb212 100644
--- a/activejob/lib/active_job/queue_adapters/sucker_punch_adapter.rb
+++ b/activejob/lib/active_job/queue_adapters/sucker_punch_adapter.rb
@@ -5,7 +5,7 @@ module ActiveJob
# == Sucker Punch adapter for Active Job
#
# Sucker Punch is a single-process Ruby asynchronous processing library.
- # This reduces the cost of of hosting on a service like Heroku along
+ # This reduces the cost of hosting on a service like Heroku along
# with the memory footprint of having to maintain additional jobs if
# hosting on a dedicated server. All queues can run within a
# single application (eg. Rails, Sinatra, etc.) process.
diff --git a/activejob/lib/active_job/test_helper.rb b/activejob/lib/active_job/test_helper.rb
index 3feb82d432..e16af1947f 100644
--- a/activejob/lib/active_job/test_helper.rb
+++ b/activejob/lib/active_job/test_helper.rb
@@ -9,7 +9,7 @@ module ActiveJob
to: :queue_adapter
def before_setup # :nodoc:
- test_adapter = ActiveJob::QueueAdapters::TestAdapter.new
+ test_adapter = queue_adapter_for_test
@old_queue_adapters = (ActiveJob::Base.subclasses << ActiveJob::Base).select do |klass|
# only override explicitly set adapters, a quirk of `class_attribute`
@@ -32,6 +32,19 @@ module ActiveJob
end
end
+ # Specifies the queue adapter to use with all active job test helpers.
+ #
+ # Returns an instance of the queue adapter and defaults to
+ # <tt>ActiveJob::QueueAdapters::TestAdapter</tt>.
+ #
+ # Note: The adapter provided by this method must provide some additional
+ # methods from those expected of a standard <tt>ActiveJob::QueueAdapter</tt>
+ # in order to be used with the active job test helpers. Refer to
+ # <tt>ActiveJob::QueueAdapters::TestAdapter</tt>.
+ def queue_adapter_for_test
+ ActiveJob::QueueAdapters::TestAdapter.new
+ end
+
# Asserts that the number of enqueued jobs matches the given number.
#
# def test_jobs
diff --git a/activejob/test/cases/logging_test.rb b/activejob/test/cases/logging_test.rb
index 820e9112de..bf8a66432a 100644
--- a/activejob/test/cases/logging_test.rb
+++ b/activejob/test/cases/logging_test.rb
@@ -3,6 +3,7 @@ require "active_support/log_subscriber/test_helper"
require 'active_support/core_ext/numeric/time'
require 'jobs/hello_job'
require 'jobs/logging_job'
+require 'jobs/overridden_logging_job'
require 'jobs/nested_job'
require 'models/person'
@@ -41,7 +42,6 @@ class LoggingTest < ActiveSupport::TestCase
ActiveJob::Base.logger = logger
end
-
def test_uses_active_job_as_tag
HelloJob.perform_later "Cristian"
assert_match(/\[ActiveJob\]/, @logger.messages)
@@ -119,4 +119,9 @@ class LoggingTest < ActiveSupport::TestCase
rescue NotImplementedError
skip
end
+
+ def test_for_tagged_logger_support_is_consistent
+ set_logger ::Logger.new(nil)
+ OverriddenLoggingJob.perform_later "Dummy"
+ end
end
diff --git a/activejob/test/cases/test_helper_test.rb b/activejob/test/cases/test_helper_test.rb
index f7ee763e8a..3d863f5e65 100644
--- a/activejob/test/cases/test_helper_test.rb
+++ b/activejob/test/cases/test_helper_test.rb
@@ -509,3 +509,15 @@ class PerformedJobsTest < ActiveJob::TestCase
assert_equal 2, ActiveJob::Base.queue_adapter.performed_jobs.count
end
end
+
+class OverrideQueueAdapterTest < ActiveJob::TestCase
+ class CustomQueueAdapter < ActiveJob::QueueAdapters::TestAdapter; end
+
+ def queue_adapter_for_test
+ CustomQueueAdapter.new
+ end
+
+ def test_assert_job_has_custom_queue_adapter_set
+ assert_instance_of CustomQueueAdapter, HelloJob.queue_adapter
+ end
+end
diff --git a/activejob/test/jobs/overridden_logging_job.rb b/activejob/test/jobs/overridden_logging_job.rb
new file mode 100644
index 0000000000..2b17a65142
--- /dev/null
+++ b/activejob/test/jobs/overridden_logging_job.rb
@@ -0,0 +1,9 @@
+class OverriddenLoggingJob < ActiveJob::Base
+ def perform(dummy)
+ logger.info "Dummy, here is it: #{dummy}"
+ end
+
+ def logger
+ @logger ||= ActiveSupport::TaggedLogging.new(ActiveSupport::Logger.new(nil))
+ end
+end
diff --git a/activemodel/lib/active_model/errors.rb b/activemodel/lib/active_model/errors.rb
index 6f2c8c1c53..2f883917b0 100644
--- a/activemodel/lib/active_model/errors.rb
+++ b/activemodel/lib/active_model/errors.rb
@@ -147,9 +147,9 @@ module ActiveModel
# Delete messages for +key+. Returns the deleted messages.
#
- # person.errors[:name] # => ["cannot be nil"]
+ # person.errors[:name] # => ["cannot be nil"]
# person.errors.delete(:name) # => ["cannot be nil"]
- # person.errors[:name] # => []
+ # person.errors[:name] # => []
def delete(key)
details.delete(key)
messages.delete(key)
@@ -382,10 +382,21 @@ module ActiveModel
end
# Returns +true+ if an error on the attribute with the given message is
- # present, +false+ otherwise. +message+ is treated the same as for +add+.
+ # present, or +false+ otherwise. +message+ is treated the same as for +add+.
#
# person.errors.add :name, :blank
- # person.errors.added? :name, :blank # => true
+ # person.errors.added? :name, :blank # => true
+ # person.errors.added? :name, "can't be blank" # => true
+ #
+ # If the error message requires an option, then it returns +true+ with
+ # the correct option, or +false+ with an incorrect or missing option.
+ #
+ # person.errors.add :name, :too_long, { count: 25 }
+ # person.errors.added? :name, :too_long, count: 25 # => true
+ # person.errors.added? :name, "is too long (maximum is 25 characters)" # => true
+ # person.errors.added? :name, :too_long, count: 24 # => false
+ # person.errors.added? :name, :too_long # => false
+ # person.errors.added? :name, "is too long" # => false
def added?(attribute, message = :invalid, options = {})
message = message.call if message.respond_to?(:call)
message = normalize_message(attribute, message, options)
diff --git a/activemodel/lib/active_model/type/date.rb b/activemodel/lib/active_model/type/date.rb
index f74243a22c..edd07ac38c 100644
--- a/activemodel/lib/active_model/type/date.rb
+++ b/activemodel/lib/active_model/type/date.rb
@@ -7,6 +7,10 @@ module ActiveModel
:date
end
+ def serialize(value)
+ cast(value)
+ end
+
def type_cast_for_schema(value)
"'#{value.to_s(:db)}'"
end
diff --git a/activemodel/lib/active_model/validations.rb b/activemodel/lib/active_model/validations.rb
index 8159b9b1d3..a10d2285a2 100644
--- a/activemodel/lib/active_model/validations.rb
+++ b/activemodel/lib/active_model/validations.rb
@@ -304,8 +304,6 @@ module ActiveModel
# Runs all the specified validations and returns +true+ if no errors were
# added otherwise +false+.
#
- # Aliased as validate.
- #
# class Person
# include ActiveModel::Validations
#
diff --git a/activemodel/test/cases/errors_test.rb b/activemodel/test/cases/errors_test.rb
index c90ee7021c..13fa5c76bc 100644
--- a/activemodel/test/cases/errors_test.rb
+++ b/activemodel/test/cases/errors_test.rb
@@ -219,6 +219,12 @@ class ErrorsTest < ActiveModel::TestCase
assert !person.errors.added?(:name, "cannot be blank")
end
+ test "added? returns false when checking for an error, but not providing message arguments" do
+ person = Person.new
+ person.errors.add(:name, "cannot be blank")
+ assert !person.errors.added?(:name)
+ end
+
test "size calculates the number of error messages" do
person = Person.new
person.errors.add(:name, "cannot be blank")
diff --git a/activerecord/CHANGELOG.md b/activerecord/CHANGELOG.md
index a1a4d2646f..8521d3b07b 100644
--- a/activerecord/CHANGELOG.md
+++ b/activerecord/CHANGELOG.md
@@ -1,3 +1,14 @@
+* Inspecting an object with an associated array of over 10 elements no longer
+ truncates the array, preventing `inspect` from looping infinitely in some
+ cases.
+
+ *Kevin McPhillips*
+
+* Removed the unused methods `ActiveRecord::Base.connection_id` and
+ `ActiveRecord::Base.connection_id=`
+
+ *Sean Griffin*
+
* Ensure hashes can be assigned to attributes created using `composed_of`.
Fixes #25210.
@@ -18,4 +29,18 @@
*Erol Fornoles*
+* PostgreSQL: Fix db:structure:load silent failure on SQL error
+
+ The command line flag "-v ON_ERROR_STOP=1" should be used
+ when invoking psql to make sure errors are not suppressed.
+
+ Example:
+
+ psql -v ON_ERROR_STOP=1 -q -f awesome-file.sql my-app-db
+
+ Fixes #23818.
+
+ *Ralin Chimev*
+
+
Please check [5-0-stable](https://github.com/rails/rails/blob/5-0-stable/activerecord/CHANGELOG.md) for previous changes.
diff --git a/activerecord/lib/active_record/associations/has_many_association.rb b/activerecord/lib/active_record/associations/has_many_association.rb
index a9f6aaafef..4daafedcfb 100644
--- a/activerecord/lib/active_record/associations/has_many_association.rb
+++ b/activerecord/lib/active_record/associations/has_many_association.rb
@@ -27,14 +27,12 @@ module ActiveRecord
throw(:abort)
end
+ when :destroy
+ # No point in executing the counter update since we're going to destroy the parent anyway
+ load_target.each { |t| t.destroyed_by_association = reflection }
+ destroy_all
else
- if options[:dependent] == :destroy
- # No point in executing the counter update since we're going to destroy the parent anyway
- load_target.each { |t| t.destroyed_by_association = reflection }
- destroy_all
- else
- delete_all
- end
+ delete_all
end
end
diff --git a/activerecord/lib/active_record/attribute.rb b/activerecord/lib/active_record/attribute.rb
index 701d24da88..9530f134d0 100644
--- a/activerecord/lib/active_record/attribute.rb
+++ b/activerecord/lib/active_record/attribute.rb
@@ -77,7 +77,11 @@ module ActiveRecord
end
def with_type(type)
- self.class.new(name, value_before_type_cast, type, original_attribute)
+ if changed_in_place?
+ with_value_from_user(value).with_type(type)
+ else
+ self.class.new(name, value_before_type_cast, type, original_attribute)
+ end
end
def type_cast(*)
@@ -201,6 +205,8 @@ module ActiveRecord
end
class Uninitialized < Attribute # :nodoc:
+ UNINITIALIZED_ORIGINAL_VALUE = Object.new
+
def initialize(name, type)
super(name, nil, type)
end
@@ -211,6 +217,10 @@ module ActiveRecord
end
end
+ def original_value
+ UNINITIALIZED_ORIGINAL_VALUE
+ end
+
def value_for_database
end
diff --git a/activerecord/lib/active_record/attribute_methods.rb b/activerecord/lib/active_record/attribute_methods.rb
index 1fb5eb28cd..eadd73aab0 100644
--- a/activerecord/lib/active_record/attribute_methods.rb
+++ b/activerecord/lib/active_record/attribute_methods.rb
@@ -209,13 +209,13 @@ module ActiveRecord
# end
#
# person = Person.new
- # person.respond_to(:name) # => true
- # person.respond_to(:name=) # => true
- # person.respond_to(:name?) # => true
- # person.respond_to('age') # => true
- # person.respond_to('age=') # => true
- # person.respond_to('age?') # => true
- # person.respond_to(:nothing) # => false
+ # person.respond_to?(:name) # => true
+ # person.respond_to?(:name=) # => true
+ # person.respond_to?(:name?) # => true
+ # person.respond_to?('age') # => true
+ # person.respond_to?('age=') # => true
+ # person.respond_to?('age?') # => true
+ # person.respond_to?(:nothing) # => false
def respond_to?(name, include_private = false)
return false unless super
@@ -279,9 +279,8 @@ module ActiveRecord
# Returns an <tt>#inspect</tt>-like string for the value of the
# attribute +attr_name+. String attributes are truncated up to 50
# characters, Date and Time attributes are returned in the
- # <tt>:db</tt> format, Array attributes are truncated up to 10 values.
- # Other attributes return the value of <tt>#inspect</tt> without
- # modification.
+ # <tt>:db</tt> format. Other attributes return the value of
+ # <tt>#inspect</tt> without modification.
#
# person = Person.create!(name: 'David Heinemeier Hansson ' * 3)
#
@@ -292,7 +291,7 @@ module ActiveRecord
# # => "\"2012-10-22 00:15:07\""
#
# person.attribute_for_inspect(:tag_ids)
- # # => "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...]"
+ # # => "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]"
def attribute_for_inspect(attr_name)
value = read_attribute(attr_name)
@@ -300,9 +299,6 @@ module ActiveRecord
"#{value[0, 50]}...".inspect
elsif value.is_a?(Date) || value.is_a?(Time)
%("#{value.to_s(:db)}")
- elsif value.is_a?(Array) && value.size > 10
- inspected = value.first(10).inspect
- %(#{inspected[0...-1]}, ...])
else
value.inspect
end
diff --git a/activerecord/lib/active_record/attribute_set/yaml_encoder.rb b/activerecord/lib/active_record/attribute_set/yaml_encoder.rb
index 6208048231..f9d527a5a3 100644
--- a/activerecord/lib/active_record/attribute_set/yaml_encoder.rb
+++ b/activerecord/lib/active_record/attribute_set/yaml_encoder.rb
@@ -2,7 +2,7 @@ module ActiveRecord
class AttributeSet
# Attempts to do more intelligent YAML dumping of an
# ActiveRecord::AttributeSet to reduce the size of the resulting string
- class YAMLEncoder
+ class YAMLEncoder # :nodoc:
def initialize(default_types)
@default_types = default_types
end
diff --git a/activerecord/lib/active_record/attributes.rb b/activerecord/lib/active_record/attributes.rb
index 519de271c3..3211b6eaeb 100644
--- a/activerecord/lib/active_record/attributes.rb
+++ b/activerecord/lib/active_record/attributes.rb
@@ -34,10 +34,10 @@ module ActiveRecord
# is not passed, the previous default value (if any) will be used.
# Otherwise, the default will be +nil+.
#
- # +array+ (PG only) specifies that the type should be an array (see the
+ # +array+ (PostgreSQL only) specifies that the type should be an array (see the
# examples below).
#
- # +range+ (PG only) specifies that the type should be a range (see the
+ # +range+ (PostgreSQL only) specifies that the type should be a range (see the
# examples below).
#
# ==== Examples
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
index bbb0e9249d..8dbafc5a4b 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
@@ -51,11 +51,12 @@ module ActiveRecord
options[:primary_key] != default_primary_key
end
- def defined_for?(options_or_to_table = {})
- if options_or_to_table.is_a?(Hash)
- options_or_to_table.all? {|key, value| options[key].to_s == value.to_s }
+ def defined_for?(to_table_ord = nil, to_table: nil, **options)
+ if to_table_ord
+ self.to_table == to_table_ord.to_s
else
- to_table == options_or_to_table.to_s
+ (to_table.nil? || to_table.to_s == self.to_table) &&
+ options.all? { |k, v| self.options[k].to_s == v.to_s }
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
index 5939ee9956..eec0bc8518 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
@@ -790,7 +790,7 @@ module ActiveRecord
# [<tt>:type</tt>]
# The reference column type. Defaults to +:integer+.
# [<tt>:index</tt>]
- # Add an appropriate index. Defaults to false.
+ # Add an appropriate index. Defaults to false.
# See #add_index for usage of this option.
# [<tt>:foreign_key</tt>]
# Add an appropriate foreign key constraint. Defaults to false.
@@ -1128,7 +1128,6 @@ module ActiveRecord
index_type ||= options[:unique] ? "UNIQUE" : ""
index_name = options[:name].to_s if options.key?(:name)
index_name ||= index_name(table_name, index_name_options(column_names))
- max_index_length = options.fetch(:internal, false) ? index_name_length : allowed_index_name_length
if options.key?(:algorithm)
algorithm = index_algorithms.fetch(options[:algorithm]) {
@@ -1142,9 +1141,8 @@ module ActiveRecord
index_options = options[:where] ? " WHERE #{options[:where]}" : ""
end
- if index_name.length > max_index_length
- raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' is too long; the limit is #{max_index_length} characters"
- end
+ validate_index_length!(table_name, index_name, options.fetch(:internal, false))
+
if data_source_exists?(table_name) && index_name_exists?(table_name, index_name, false)
raise ArgumentError, "Index name '#{index_name}' on table '#{table_name}' already exists"
end
@@ -1276,8 +1274,10 @@ module ActiveRecord
end
end
- def validate_index_length!(table_name, new_name) # :nodoc:
- if new_name.length > allowed_index_name_length
+ def validate_index_length!(table_name, new_name, internal = false) # :nodoc:
+ max_index_length = internal ? index_name_length : allowed_index_name_length
+
+ if new_name.length > max_index_length
raise ArgumentError, "Index name '#{new_name}' on table '#{table_name}' is too long; the limit is #{allowed_index_name_length} characters"
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
index 718a6c5b91..3e77b92141 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
@@ -460,7 +460,6 @@ module ActiveRecord
# it can be helpful to provide these in a migration's +change+ method so it can be reverted.
# In that case, +options+ and the block will be used by create_table.
def drop_table(table_name, options = {})
- create_table_info_cache.delete(table_name) if create_table_info_cache.key?(table_name)
execute "DROP#{' TEMPORARY' if options[:temporary]} TABLE#{' IF EXISTS' if options[:if_exists]} #{quote_table_name(table_name)}#{' CASCADE' if options[:force] == :cascade}"
end
@@ -515,19 +514,21 @@ module ActiveRecord
schema, name = extract_schema_qualified_name(table_name)
- fk_info = select_all <<-SQL.strip_heredoc
- SELECT fk.referenced_table_name as 'to_table'
- ,fk.referenced_column_name as 'primary_key'
- ,fk.column_name as 'column'
- ,fk.constraint_name as 'name'
+ fk_info = select_all(<<-SQL.strip_heredoc, 'SCHEMA')
+ SELECT fk.referenced_table_name AS 'to_table',
+ fk.referenced_column_name AS 'primary_key',
+ fk.column_name AS 'column',
+ fk.constraint_name AS 'name',
+ rc.update_rule AS 'on_update',
+ rc.delete_rule AS 'on_delete'
FROM information_schema.key_column_usage fk
- WHERE fk.referenced_column_name is not null
+ JOIN information_schema.referential_constraints rc
+ USING (constraint_schema, constraint_name)
+ WHERE fk.referenced_column_name IS NOT NULL
AND fk.table_schema = #{quote(schema)}
AND fk.table_name = #{quote(name)}
SQL
- create_table_info = create_table_info(table_name)
-
fk_info.map do |row|
options = {
column: row['column'],
@@ -535,8 +536,8 @@ module ActiveRecord
primary_key: row['primary_key']
}
- options[:on_update] = extract_foreign_key_action(create_table_info, row['name'], "UPDATE")
- options[:on_delete] = extract_foreign_key_action(create_table_info, row['name'], "DELETE")
+ options[:on_update] = extract_foreign_key_action(row['on_update'])
+ options[:on_delete] = extract_foreign_key_action(row['on_delete'])
ForeignKeyDefinition.new(table_name, row['to_table'], options)
end
@@ -891,21 +892,15 @@ module ActiveRecord
end
end
- def extract_foreign_key_action(structure, name, action) # :nodoc:
- if structure =~ /CONSTRAINT #{quote_column_name(name)} FOREIGN KEY .* REFERENCES .* ON #{action} (CASCADE|SET NULL|RESTRICT)/
- case $1
- when 'CASCADE'; :cascade
- when 'SET NULL'; :nullify
- end
+ def extract_foreign_key_action(specifier) # :nodoc:
+ case specifier
+ when 'CASCADE'; :cascade
+ when 'SET NULL'; :nullify
end
end
- def create_table_info_cache # :nodoc:
- @create_table_info_cache ||= {}
- end
-
def create_table_info(table_name) # :nodoc:
- create_table_info_cache[table_name] ||= select_one("SHOW CREATE TABLE #{quote_table_name(table_name)}")["Create Table"]
+ select_one("SHOW CREATE TABLE #{quote_table_name(table_name)}")["Create Table"]
end
def create_table_definition(*args) # :nodoc:
diff --git a/activerecord/lib/active_record/connection_adapters/mysql/column.rb b/activerecord/lib/active_record/connection_adapters/mysql/column.rb
index 9c45fdd44a..ea554b188c 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql/column.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql/column.rb
@@ -6,7 +6,6 @@ module ActiveRecord
def initialize(*)
super
- assert_valid_default
extract_default
end
@@ -38,12 +37,6 @@ module ActiveRecord
@default = null || strict ? nil : ''
end
end
-
- def assert_valid_default
- if blob_or_text_column? && default.present?
- raise ArgumentError, "#{type} columns cannot have a default value: #{default.inspect}"
- end
- end
end
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/mysql/database_statements.rb b/activerecord/lib/active_record/connection_adapters/mysql/database_statements.rb
index 13c9b6cbd9..87f0ff7d85 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql/database_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql/database_statements.rb
@@ -13,19 +13,6 @@ module ActiveRecord
result
end
- # Returns a record hash with the column names as keys and column values
- # as values.
- def select_one(arel, name = nil, binds = [])
- arel, binds = binds_from_relation(arel, binds)
- @connection.query_options.merge!(as: :hash)
- select_result(to_sql(arel, binds), name, binds) do |result|
- @connection.next_result while @connection.more_results?
- result.first
- end
- ensure
- @connection.query_options.merge!(as: :array)
- end
-
# Returns an array of arrays containing the field values.
# Order is the same as that returned by +columns+.
def select_rows(sql, name = nil, binds = [])
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb
index 6318b1c65a..45507e206a 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb
@@ -579,7 +579,7 @@ module ActiveRecord
end
def foreign_keys(table_name)
- fk_info = select_all <<-SQL.strip_heredoc
+ fk_info = select_all(<<-SQL.strip_heredoc, 'SCHEMA')
SELECT t2.oid::regclass::text AS to_table, a1.attname AS column, a2.attname AS primary_key, c.conname AS name, c.confupdtype AS on_update, c.confdeltype AS on_delete
FROM pg_constraint c
JOIN pg_class t1 ON c.conrelid = t1.oid
@@ -641,7 +641,7 @@ module ActiveRecord
when 1, 2; 'smallint'
when nil, 3, 4; 'integer'
when 5..8; 'bigint'
- else raise(ActiveRecordError, "No integer type has byte size #{limit}. Use a numeric with precision 0 instead.")
+ else raise(ActiveRecordError, "No integer type has byte size #{limit}. Use a numeric with scale 0 instead.")
end
else
super(type, limit, precision, scale)
diff --git a/activerecord/lib/active_record/connection_handling.rb b/activerecord/lib/active_record/connection_handling.rb
index 086c678af5..f735bc697b 100644
--- a/activerecord/lib/active_record/connection_handling.rb
+++ b/activerecord/lib/active_record/connection_handling.rb
@@ -98,14 +98,6 @@ module ActiveRecord
@connection_specification_name
end
- def connection_id
- ActiveRecord::RuntimeRegistry.connection_id ||= Thread.current.object_id
- end
-
- def connection_id=(connection_id)
- ActiveRecord::RuntimeRegistry.connection_id = connection_id
- end
-
# Returns the configuration of the associated connection as a hash:
#
# ActiveRecord::Base.connection_config
@@ -131,7 +123,7 @@ module ActiveRecord
def remove_connection(name = nil)
name ||= @connection_specification_name if defined?(@connection_specification_name)
- # if removing a connection that have a pool, we reset the
+ # if removing a connection that has a pool, we reset the
# connection_specification_name so it will use the parent
# pool.
if connection_handler.retrieve_connection_pool(name)
diff --git a/activerecord/lib/active_record/enum.rb b/activerecord/lib/active_record/enum.rb
index 7be332fb97..b884edf920 100644
--- a/activerecord/lib/active_record/enum.rb
+++ b/activerecord/lib/active_record/enum.rb
@@ -105,6 +105,8 @@ module ActiveRecord
end
class EnumType < Type::Value # :nodoc:
+ delegate :type, to: :subtype
+
def initialize(name, mapping, subtype)
@name = name
@mapping = mapping
diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb
index ed1bbf5dcd..51bf12d0bf 100644
--- a/activerecord/lib/active_record/fixtures.rb
+++ b/activerecord/lib/active_record/fixtures.rb
@@ -66,7 +66,7 @@ module ActiveRecord
# By default, +test_helper.rb+ will load all of your fixtures into your test
# database, so this test will succeed.
#
- # The testing environment will automatically load the all fixtures into the database before each
+ # The testing environment will automatically load all the fixtures into the database before each
# test. To ensure consistent data, the environment deletes the fixtures before running the load.
#
# In addition to being available in the database, the fixture's data may also be accessed by
diff --git a/activerecord/lib/active_record/inheritance.rb b/activerecord/lib/active_record/inheritance.rb
index 899683ee4f..b5fec57c8c 100644
--- a/activerecord/lib/active_record/inheritance.rb
+++ b/activerecord/lib/active_record/inheritance.rb
@@ -19,7 +19,7 @@ module ActiveRecord
# Be aware that because the type column is an attribute on the record every new
# subclass will instantly be marked as dirty and the type column will be included
# in the list of changed attributes on the record. This is different from non
- # STI classes:
+ # Single Table Inheritance(STI) classes:
#
# Company.new.changed? # => false
# Firm.new.changed? # => true
@@ -37,6 +37,7 @@ module ActiveRecord
included do
# Determines whether to store the full constant name including namespace when using STI.
+ # This is true, by default.
class_attribute :store_full_sti_class, instance_writer: false
self.store_full_sti_class = true
end
diff --git a/activerecord/lib/active_record/internal_metadata.rb b/activerecord/lib/active_record/internal_metadata.rb
index 17a5dc1d1b..8b649eab0f 100644
--- a/activerecord/lib/active_record/internal_metadata.rb
+++ b/activerecord/lib/active_record/internal_metadata.rb
@@ -14,10 +14,6 @@ module ActiveRecord
"#{table_name_prefix}#{ActiveRecord::Base.internal_metadata_table_name}#{table_name_suffix}"
end
- def original_table_name
- "#{table_name_prefix}active_record_internal_metadatas#{table_name_suffix}"
- end
-
def []=(key, value)
find_or_initialize_by(key: key).update_attributes!(value: value)
end
@@ -30,17 +26,8 @@ module ActiveRecord
ActiveSupport::Deprecation.silence { connection.table_exists?(table_name) }
end
- def original_table_exists?
- # This method will be removed in Rails 5.1
- # Since it is only necessary when `active_record_internal_metadatas` could exist
- ActiveSupport::Deprecation.silence { connection.table_exists?(original_table_name) }
- end
-
# Creates an internal metadata table with columns +key+ and +value+
def create_table
- if original_table_exists?
- connection.rename_table(original_table_name, table_name)
- end
unless table_exists?
key_options = connection.internal_string_options_for_primary_key
diff --git a/activerecord/lib/active_record/persistence.rb b/activerecord/lib/active_record/persistence.rb
index afed5e5e85..ebdb9efba2 100644
--- a/activerecord/lib/active_record/persistence.rb
+++ b/activerecord/lib/active_record/persistence.rb
@@ -479,7 +479,12 @@ module ActiveRecord
# ball.touch(:updated_at) # => raises ActiveRecordError
#
def touch(*names, time: nil)
- raise ActiveRecordError, "cannot touch on a new record object" unless persisted?
+ unless persisted?
+ raise ActiveRecordError, <<-end_error.strip_heredoc
+ cannot touch on a new or destroyed record object. Consider using
+ persisted?, new_record?, or destroyed? before touching
+ end_error
+ end
time ||= current_time_from_proper_timezone
attributes = timestamp_attributes_for_update_in_model
diff --git a/activerecord/lib/active_record/query_cache.rb b/activerecord/lib/active_record/query_cache.rb
index ca12a603da..387dd8e9bd 100644
--- a/activerecord/lib/active_record/query_cache.rb
+++ b/activerecord/lib/active_record/query_cache.rb
@@ -5,7 +5,7 @@ module ActiveRecord
# Enable the query cache within the block if Active Record is configured.
# If it's not, it will execute the given block.
def cache(&block)
- if ActiveRecord::Base.connected?
+ if connected?
connection.cache(&block)
else
yield
@@ -15,7 +15,7 @@ module ActiveRecord
# Disable the query cache within the block if Active Record is configured.
# If it's not, it will execute the given block.
def uncached(&block)
- if ActiveRecord::Base.connected?
+ if connected?
connection.uncached(&block)
else
yield
@@ -26,16 +26,12 @@ module ActiveRecord
def self.run
connection = ActiveRecord::Base.connection
enabled = connection.query_cache_enabled
- connection_id = ActiveRecord::Base.connection_id
connection.enable_query_cache!
- [enabled, connection_id]
+ enabled
end
- def self.complete(state)
- enabled, connection_id = state
-
- ActiveRecord::Base.connection_id = connection_id
+ def self.complete(enabled)
ActiveRecord::Base.connection.clear_query_cache
ActiveRecord::Base.connection.disable_query_cache! unless enabled
end
@@ -44,7 +40,7 @@ module ActiveRecord
executor.register_hook(self)
executor.to_complete do
- unless ActiveRecord::Base.connection.transaction_open?
+ unless ActiveRecord::Base.connected? && ActiveRecord::Base.connection.transaction_open?
ActiveRecord::Base.clear_active_connections!
end
end
diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb
index 7a1552856b..93baa882ad 100644
--- a/activerecord/lib/active_record/relation.rb
+++ b/activerecord/lib/active_record/relation.rb
@@ -65,7 +65,7 @@ module ActiveRecord
@klass.connection.insert(
im,
'SQL',
- primary_key,
+ primary_key || false,
primary_key_value,
nil,
binds)
diff --git a/activerecord/lib/active_record/relation/finder_methods.rb b/activerecord/lib/active_record/relation/finder_methods.rb
index 87eea8277a..d255cad91b 100644
--- a/activerecord/lib/active_record/relation/finder_methods.rb
+++ b/activerecord/lib/active_record/relation/finder_methods.rb
@@ -333,6 +333,8 @@ module ActiveRecord
end
connection.select_value(relation, "#{name} Exists", relation.bound_attributes) ? true : false
+ rescue RangeError
+ false
end
# This method is called whenever no records are found with either a single
@@ -398,15 +400,7 @@ module ActiveRecord
end
def construct_relation_for_association_calculations
- from = arel.froms.first
- if Arel::Table === from
- apply_join_dependency(self, construct_join_dependency(joins_values))
- else
- # FIXME: as far as I can tell, `from` will always be an Arel::Table.
- # There are no tests that test this branch, but presumably it's
- # possible for `from` to be a list?
- apply_join_dependency(self, construct_join_dependency(from))
- end
+ apply_join_dependency(self, construct_join_dependency(joins_values))
end
def apply_join_dependency(relation, join_dependency)
@@ -579,7 +573,7 @@ module ActiveRecord
# e.g., reverse_order.offset(index-1).first
end
end
-
+
private
def find_nth_with_limit_and_offset(index, limit, offset:) # :nodoc:
diff --git a/activerecord/lib/active_record/relation/predicate_builder.rb b/activerecord/lib/active_record/relation/predicate_builder.rb
index ecce949370..e5496c02b2 100644
--- a/activerecord/lib/active_record/relation/predicate_builder.rb
+++ b/activerecord/lib/active_record/relation/predicate_builder.rb
@@ -15,11 +15,11 @@ module ActiveRecord
@table = table
@handlers = []
- register_handler(BasicObject, BasicObjectHandler.new(self))
+ register_handler(BasicObject, BasicObjectHandler.new)
register_handler(Class, ClassHandler.new(self))
register_handler(Base, BaseHandler.new(self))
- register_handler(Range, RangeHandler.new(self))
- register_handler(RangeHandler::RangeWithBinds, RangeHandler.new(self))
+ register_handler(Range, RangeHandler.new)
+ register_handler(RangeHandler::RangeWithBinds, RangeHandler.new)
register_handler(Relation, RelationHandler.new)
register_handler(Array, ArrayHandler.new(self))
register_handler(AssociationQueryValue, AssociationQueryHandler.new(self))
diff --git a/activerecord/lib/active_record/relation/predicate_builder/basic_object_handler.rb b/activerecord/lib/active_record/relation/predicate_builder/basic_object_handler.rb
index 6cec75dc0a..79cde00303 100644
--- a/activerecord/lib/active_record/relation/predicate_builder/basic_object_handler.rb
+++ b/activerecord/lib/active_record/relation/predicate_builder/basic_object_handler.rb
@@ -1,17 +1,9 @@
module ActiveRecord
class PredicateBuilder
class BasicObjectHandler # :nodoc:
- def initialize(predicate_builder)
- @predicate_builder = predicate_builder
- end
-
def call(attribute, value)
attribute.eq(value)
end
-
- protected
-
- attr_reader :predicate_builder
end
end
end
diff --git a/activerecord/lib/active_record/relation/predicate_builder/range_handler.rb b/activerecord/lib/active_record/relation/predicate_builder/range_handler.rb
index 306d4694ae..5db778e19c 100644
--- a/activerecord/lib/active_record/relation/predicate_builder/range_handler.rb
+++ b/activerecord/lib/active_record/relation/predicate_builder/range_handler.rb
@@ -3,10 +3,6 @@ module ActiveRecord
class RangeHandler # :nodoc:
RangeWithBinds = Struct.new(:begin, :end, :exclude_end?)
- def initialize(predicate_builder)
- @predicate_builder = predicate_builder
- end
-
def call(attribute, value)
if value.begin.respond_to?(:infinite?) && value.begin.infinite?
if value.end.respond_to?(:infinite?) && value.end.infinite?
@@ -24,10 +20,6 @@ module ActiveRecord
attribute.between(value)
end
end
-
- protected
-
- attr_reader :predicate_builder
end
end
end
diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb
index 2a831c2017..8a87015e44 100644
--- a/activerecord/lib/active_record/relation/query_methods.rb
+++ b/activerecord/lib/active_record/relation/query_methods.rb
@@ -658,7 +658,7 @@ module ActiveRecord
# present). Neither relation may have a #limit, #offset, or #distinct set.
#
# Post.where("id = 1").or(Post.where("author_id = 3"))
- # # SELECT `posts`.* FROM `posts` WHERE (('id = 1' OR 'author_id = 3'))
+ # # SELECT `posts`.* FROM `posts` WHERE ((id = 1) OR (author_id = 3))
#
def or(other)
unless other.is_a? Relation
diff --git a/activerecord/lib/active_record/result.rb b/activerecord/lib/active_record/result.rb
index 8e6cd6c82f..b9fd0f5326 100644
--- a/activerecord/lib/active_record/result.rb
+++ b/activerecord/lib/active_record/result.rb
@@ -75,8 +75,14 @@ module ActiveRecord
hash_rows[idx]
end
+ def first
+ return nil if @rows.empty?
+ Hash[@columns.zip(@rows.first)]
+ end
+
def last
- hash_rows.last
+ return nil if @rows.empty?
+ Hash[@columns.zip(@rows.last)]
end
def cast_values(type_overrides = {}) # :nodoc:
diff --git a/activerecord/lib/active_record/runtime_registry.rb b/activerecord/lib/active_record/runtime_registry.rb
index 56e88bc661..9e86999c1b 100644
--- a/activerecord/lib/active_record/runtime_registry.rb
+++ b/activerecord/lib/active_record/runtime_registry.rb
@@ -12,9 +12,9 @@ module ActiveRecord
class RuntimeRegistry # :nodoc:
extend ActiveSupport::PerThreadRegistry
- attr_accessor :connection_handler, :sql_runtime, :connection_id
+ attr_accessor :connection_handler, :sql_runtime
- [:connection_handler, :sql_runtime, :connection_id].each do |val|
+ [:connection_handler, :sql_runtime].each do |val|
class_eval %{ def self.#{val}; instance.#{val}; end }, __FILE__, __LINE__
class_eval %{ def self.#{val}=(x); instance.#{val}=x; end }, __FILE__, __LINE__
end
diff --git a/activerecord/lib/active_record/tasks/mysql_database_tasks.rb b/activerecord/lib/active_record/tasks/mysql_database_tasks.rb
index af0c935342..b1a0ad0115 100644
--- a/activerecord/lib/active_record/tasks/mysql_database_tasks.rb
+++ b/activerecord/lib/active_record/tasks/mysql_database_tasks.rb
@@ -58,6 +58,7 @@ module ActiveRecord
args.concat(["--result-file", "#{filename}"])
args.concat(["--no-data"])
args.concat(["--routines"])
+ args.concat(["--skip-comments"])
args.concat(["#{configuration['database']}"])
run_cmd('mysqldump', args, 'dumping')
diff --git a/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb b/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb
index 8b4874044c..b19ab57ee4 100644
--- a/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb
+++ b/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb
@@ -2,6 +2,7 @@ module ActiveRecord
module Tasks # :nodoc:
class PostgreSQLDatabaseTasks # :nodoc:
DEFAULT_ENCODING = ENV['CHARSET'] || 'utf8'
+ ON_ERROR_STOP_1 = 'ON_ERROR_STOP=1'.freeze
delegate :connection, :establish_connection, :clear_active_connections!,
to: ActiveRecord::Base
@@ -67,7 +68,7 @@ module ActiveRecord
def structure_load(filename)
set_psql_env
- args = [ '-q', '-f', filename, configuration['database'] ]
+ args = [ '-v', ON_ERROR_STOP_1, '-q', '-f', filename, configuration['database'] ]
run_cmd('psql', args, 'loading' )
end
diff --git a/activerecord/lib/active_record/touch_later.rb b/activerecord/lib/active_record/touch_later.rb
index 9a80a63e28..5c41ab6e39 100644
--- a/activerecord/lib/active_record/touch_later.rb
+++ b/activerecord/lib/active_record/touch_later.rb
@@ -8,7 +8,12 @@ module ActiveRecord
end
def touch_later(*names) # :nodoc:
- raise ActiveRecordError, "cannot touch on a new record object" unless persisted?
+ unless persisted?
+ raise ActiveRecordError, <<-end_error.strip_heredoc
+ cannot touch on a new or destroyed record object. Consider using
+ persisted?, new_record?, or destroyed? before touching
+ end_error
+ end
@_defer_touch_attrs ||= timestamp_attributes_for_update_in_model
@_defer_touch_attrs |= names
diff --git a/activerecord/lib/active_record/transactions.rb b/activerecord/lib/active_record/transactions.rb
index 77c2845d88..0ee1ebcfbe 100644
--- a/activerecord/lib/active_record/transactions.rb
+++ b/activerecord/lib/active_record/transactions.rb
@@ -189,8 +189,8 @@ module ActiveRecord
#
# === Caveats
#
- # If you're on MySQL, then do not use DDL operations in nested transactions
- # blocks that are emulated with savepoints. That is, do not execute statements
+ # If you're on MySQL, then do not use Data Definition Language(DDL) operations in nested
+ # transactions blocks that are emulated with savepoints. That is, do not execute statements
# like 'CREATE TABLE' inside such blocks. This is because MySQL automatically
# releases all savepoints upon executing a DDL operation. When +transaction+
# is finished and tries to release the savepoint it created earlier, a
@@ -480,11 +480,11 @@ module ActiveRecord
# Updates the attributes on this particular Active Record object so that
# if it's associated with a transaction, then the state of the Active Record
- # object will be updated to reflect the current state of the transaction
+ # object will be updated to reflect the current state of the transaction.
#
# The +@transaction_state+ variable stores the states of the associated
# transaction. This relies on the fact that a transaction can only be in
- # one rollback or commit (otherwise a list of states would be required)
+ # one rollback or commit (otherwise a list of states would be required).
# Each Active Record object inside of a transaction carries that transaction's
# TransactionState.
#
diff --git a/activerecord/lib/active_record/validations/uniqueness.rb b/activerecord/lib/active_record/validations/uniqueness.rb
index 1f59276137..ec9f498c40 100644
--- a/activerecord/lib/active_record/validations/uniqueness.rb
+++ b/activerecord/lib/active_record/validations/uniqueness.rb
@@ -65,8 +65,6 @@ module ActiveRecord
column = klass.columns_hash[attribute_name]
cast_type = klass.type_for_attribute(attribute_name)
- value = cast_type.serialize(value)
- value = klass.connection.type_cast(value)
comparison = if !options[:case_sensitive] && !value.nil?
# will use SQL LOWER function before comparison, unless it detects a case insensitive collation
@@ -77,11 +75,9 @@ module ActiveRecord
if value.nil?
klass.unscoped.where(comparison)
else
- bind = Relation::QueryAttribute.new(attribute_name, value, Type::Value.new)
+ bind = Relation::QueryAttribute.new(attribute_name, value, cast_type)
klass.unscoped.where(comparison, bind)
end
- rescue RangeError
- klass.none
end
def scope_relation(record, table, relation)
diff --git a/activerecord/lib/rails/generators/active_record/model/model_generator.rb b/activerecord/lib/rails/generators/active_record/model/model_generator.rb
index f191eff5bf..0d72913258 100644
--- a/activerecord/lib/rails/generators/active_record/model/model_generator.rb
+++ b/activerecord/lib/rails/generators/active_record/model/model_generator.rb
@@ -21,14 +21,14 @@ module ActiveRecord
end
def create_model_file
- template 'model.rb', File.join('app/models', class_path, "#{file_name}.rb")
generate_application_record
+ template 'model.rb', File.join('app/models', class_path, "#{file_name}.rb")
end
def create_module_file
return if regular_class_path.empty?
- template 'module.rb', File.join('app/models', "#{class_path.join('/')}.rb") if behavior == :invoke
generate_application_record
+ template 'module.rb', File.join('app/models', "#{class_path.join('/')}.rb") if behavior == :invoke
end
hook_for :test_framework
@@ -48,7 +48,7 @@ module ActiveRecord
# Used by the migration template to determine the parent name of the model
def parent_class_name
- options[:parent] || determine_default_parent_class
+ options[:parent] || 'ApplicationRecord'
end
def application_record_exist?
@@ -64,14 +64,6 @@ module ActiveRecord
'app/models/application_record.rb'
end
end
-
- def determine_default_parent_class
- if application_record_exist?
- "ApplicationRecord"
- else
- "ActiveRecord::Base"
- end
- end
end
end
end
diff --git a/activerecord/test/cases/adapters/mysql2/schema_test.rb b/activerecord/test/cases/adapters/mysql2/schema_test.rb
index 43957791b1..57ea8258d1 100644
--- a/activerecord/test/cases/adapters/mysql2/schema_test.rb
+++ b/activerecord/test/cases/adapters/mysql2/schema_test.rb
@@ -103,3 +103,24 @@ module ActiveRecord
end
end
end
+
+class Mysql2AnsiQuotesTest < ActiveRecord::Mysql2TestCase
+ def setup
+ @connection = ActiveRecord::Base.connection
+ @connection.execute("SET SESSION sql_mode='ANSI_QUOTES'")
+ end
+
+ def teardown
+ @connection.reconnect!
+ end
+
+ def test_primary_key_method_with_ansi_quotes
+ assert_equal "id", @connection.primary_key("topics")
+ end
+
+ def test_foreign_keys_method_with_ansi_quotes
+ fks = @connection.foreign_keys("lessons_students")
+ assert_equal([["lessons_students", "students", :cascade]],
+ fks.map {|fk| [fk.from_table, fk.to_table, fk.on_delete] })
+ end
+end
diff --git a/activerecord/test/cases/adapters/postgresql/array_test.rb b/activerecord/test/cases/adapters/postgresql/array_test.rb
index 380a90d765..70792e937c 100644
--- a/activerecord/test/cases/adapters/postgresql/array_test.rb
+++ b/activerecord/test/cases/adapters/postgresql/array_test.rb
@@ -189,8 +189,13 @@ class PostgresqlArrayTest < ActiveRecord::PostgreSQLTestCase
end
def test_attribute_for_inspect_for_array_field
+ record = PgArray.new { |a| a.ratings = (1..10).to_a }
+ assert_equal("[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]", record.attribute_for_inspect(:ratings))
+ end
+
+ def test_attribute_for_inspect_for_array_field_for_large_array
record = PgArray.new { |a| a.ratings = (1..11).to_a }
- assert_equal("[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...]", record.attribute_for_inspect(:ratings))
+ assert_equal("[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]", record.attribute_for_inspect(:ratings))
end
def test_escaping
diff --git a/activerecord/test/cases/adapters/sqlite3/quoting_test.rb b/activerecord/test/cases/adapters/sqlite3/quoting_test.rb
index f3ec2b98d3..fe2425b845 100644
--- a/activerecord/test/cases/adapters/sqlite3/quoting_test.rb
+++ b/activerecord/test/cases/adapters/sqlite3/quoting_test.rb
@@ -3,98 +3,92 @@ require 'bigdecimal'
require 'yaml'
require 'securerandom'
-module ActiveRecord
- module ConnectionAdapters
- class SQLite3Adapter
- class QuotingTest < ActiveRecord::SQLite3TestCase
- def setup
- @conn = ActiveRecord::Base.connection
- end
-
- def test_type_cast_binary_encoding_without_logger
- @conn.extend(Module.new { def logger; end })
- binary = SecureRandom.hex
- expected = binary.dup.encode!(Encoding::UTF_8)
- assert_equal expected, @conn.type_cast(binary)
- end
-
- def test_type_cast_symbol
- assert_equal 'foo', @conn.type_cast(:foo)
- end
-
- def test_type_cast_date
- date = Date.today
- expected = @conn.quoted_date(date)
- assert_equal expected, @conn.type_cast(date)
- end
-
- def test_type_cast_time
- time = Time.now
- expected = @conn.quoted_date(time)
- assert_equal expected, @conn.type_cast(time)
- end
-
- def test_type_cast_numeric
- assert_equal 10, @conn.type_cast(10)
- assert_equal 2.2, @conn.type_cast(2.2)
- end
-
- def test_type_cast_nil
- assert_equal nil, @conn.type_cast(nil)
- end
-
- def test_type_cast_true
- assert_equal 't', @conn.type_cast(true)
- end
-
- def test_type_cast_false
- assert_equal 'f', @conn.type_cast(false)
- end
-
- def test_type_cast_bigdecimal
- bd = BigDecimal.new '10.0'
- assert_equal bd.to_f, @conn.type_cast(bd)
- end
-
- def test_type_cast_unknown_should_raise_error
- obj = Class.new.new
- assert_raise(TypeError) { @conn.type_cast(obj) }
- end
-
- def test_type_cast_object_which_responds_to_quoted_id
- quoted_id_obj = Class.new {
- def quoted_id
- "'zomg'"
- end
-
- def id
- 10
- end
- }.new
- assert_equal 10, @conn.type_cast(quoted_id_obj)
-
- quoted_id_obj = Class.new {
- def quoted_id
- "'zomg'"
- end
- }.new
- assert_raise(TypeError) { @conn.type_cast(quoted_id_obj) }
- end
-
- def test_quoting_binary_strings
- value = "hello".encode('ascii-8bit')
- type = Type::String.new
-
- assert_equal "'hello'", @conn.quote(type.serialize(value))
- end
-
- def test_quoted_time_returns_date_qualified_time
- value = ::Time.utc(2000, 1, 1, 12, 30, 0, 999999)
- type = Type::Time.new
-
- assert_equal "'2000-01-01 12:30:00.999999'", @conn.quote(type.serialize(value))
- end
+class SQLite3QuotingTest < ActiveRecord::SQLite3TestCase
+ def setup
+ @conn = ActiveRecord::Base.connection
+ end
+
+ def test_type_cast_binary_encoding_without_logger
+ @conn.extend(Module.new { def logger; end })
+ binary = SecureRandom.hex
+ expected = binary.dup.encode!(Encoding::UTF_8)
+ assert_equal expected, @conn.type_cast(binary)
+ end
+
+ def test_type_cast_symbol
+ assert_equal 'foo', @conn.type_cast(:foo)
+ end
+
+ def test_type_cast_date
+ date = Date.today
+ expected = @conn.quoted_date(date)
+ assert_equal expected, @conn.type_cast(date)
+ end
+
+ def test_type_cast_time
+ time = Time.now
+ expected = @conn.quoted_date(time)
+ assert_equal expected, @conn.type_cast(time)
+ end
+
+ def test_type_cast_numeric
+ assert_equal 10, @conn.type_cast(10)
+ assert_equal 2.2, @conn.type_cast(2.2)
+ end
+
+ def test_type_cast_nil
+ assert_equal nil, @conn.type_cast(nil)
+ end
+
+ def test_type_cast_true
+ assert_equal 't', @conn.type_cast(true)
+ end
+
+ def test_type_cast_false
+ assert_equal 'f', @conn.type_cast(false)
+ end
+
+ def test_type_cast_bigdecimal
+ bd = BigDecimal.new '10.0'
+ assert_equal bd.to_f, @conn.type_cast(bd)
+ end
+
+ def test_type_cast_unknown_should_raise_error
+ obj = Class.new.new
+ assert_raise(TypeError) { @conn.type_cast(obj) }
+ end
+
+ def test_type_cast_object_which_responds_to_quoted_id
+ quoted_id_obj = Class.new {
+ def quoted_id
+ "'zomg'"
+ end
+
+ def id
+ 10
end
- end
+ }.new
+ assert_equal 10, @conn.type_cast(quoted_id_obj)
+
+ quoted_id_obj = Class.new {
+ def quoted_id
+ "'zomg'"
+ end
+ }.new
+ assert_raise(TypeError) { @conn.type_cast(quoted_id_obj) }
+ end
+
+ def test_quoting_binary_strings
+ value = "hello".encode('ascii-8bit')
+ type = ActiveRecord::Type::String.new
+
+ assert_equal "'hello'", @conn.quote(type.serialize(value))
+ end
+
+ def test_quoted_time_returns_date_qualified_time
+ value = ::Time.utc(2000, 1, 1, 12, 30, 0, 999999)
+ type = ActiveRecord::Type::Time.new
+
+ assert_equal "'2000-01-01 12:30:00.999999'", @conn.quote(type.serialize(value))
end
end
diff --git a/activerecord/test/cases/adapters/sqlite3/statement_pool_test.rb b/activerecord/test/cases/adapters/sqlite3/statement_pool_test.rb
index 559b951109..24cc6875ab 100644
--- a/activerecord/test/cases/adapters/sqlite3/statement_pool_test.rb
+++ b/activerecord/test/cases/adapters/sqlite3/statement_pool_test.rb
@@ -1,24 +1,20 @@
require 'cases/helper'
-module ActiveRecord::ConnectionAdapters
- class SQLite3Adapter
- class StatementPoolTest < ActiveRecord::SQLite3TestCase
- if Process.respond_to?(:fork)
- def test_cache_is_per_pid
+class SQLite3StatementPoolTest < ActiveRecord::SQLite3TestCase
+ if Process.respond_to?(:fork)
+ def test_cache_is_per_pid
- cache = StatementPool.new(10)
- cache['foo'] = 'bar'
- assert_equal 'bar', cache['foo']
+ cache = ActiveRecord::ConnectionAdapters::SQLite3Adapter::StatementPool.new(10)
+ cache['foo'] = 'bar'
+ assert_equal 'bar', cache['foo']
- pid = fork {
- lookup = cache['foo'];
- exit!(!lookup)
- }
+ pid = fork {
+ lookup = cache['foo'];
+ exit!(!lookup)
+ }
- Process.waitpid pid
- assert $?.success?, 'process should exit successfully'
- end
- end
+ Process.waitpid pid
+ assert $?.success?, 'process should exit successfully'
end
end
end
diff --git a/activerecord/test/cases/associations/eager_test.rb b/activerecord/test/cases/associations/eager_test.rb
index f7bb3e54d5..80d9a6083b 100644
--- a/activerecord/test/cases/associations/eager_test.rb
+++ b/activerecord/test/cases/associations/eager_test.rb
@@ -90,6 +90,10 @@ class EagerAssociationTest < ActiveRecord::TestCase
assert_no_queries { authors.map(&:post) }
end
+ def test_calculate_with_string_in_from_and_eager_loading
+ assert_equal 10, Post.from("authors, posts").eager_load(:comments).where("posts.author_id = authors.id").count
+ end
+
def test_with_two_tables_in_from_without_getting_double_quoted
posts = Post.select("posts.*").from("authors, posts").eager_load(:comments).where("posts.author_id = authors.id").order("posts.id").to_a
assert_equal 2, posts.first.comments.size
diff --git a/activerecord/test/cases/associations/left_outer_join_association_test.rb b/activerecord/test/cases/associations/left_outer_join_association_test.rb
index 4af791b758..eee135cfb8 100644
--- a/activerecord/test/cases/associations/left_outer_join_association_test.rb
+++ b/activerecord/test/cases/associations/left_outer_join_association_test.rb
@@ -50,7 +50,7 @@ class LeftOuterJoinAssociationTest < ActiveRecord::TestCase
def test_join_conditions_added_to_join_clause
queries = capture_sql { Author.left_outer_joins(:essays).to_a }
- assert queries.any? { |sql| /writer_type.*?=.*?(Author|\?|\$1)/i =~ sql }
+ assert queries.any? { |sql| /writer_type.*?=.*?(Author|\?|\$1|\:a1)/i =~ sql }
assert queries.none? { |sql| /WHERE/i =~ sql }
end
diff --git a/activerecord/test/cases/attribute_methods_test.rb b/activerecord/test/cases/attribute_methods_test.rb
index 1db52af59b..04126e87e4 100644
--- a/activerecord/test/cases/attribute_methods_test.rb
+++ b/activerecord/test/cases/attribute_methods_test.rb
@@ -27,14 +27,33 @@ class AttributeMethodsTest < ActiveRecord::TestCase
ActiveRecord::Base.send(:attribute_method_matchers).concat(@old_matchers)
end
- def test_attribute_for_inspect
+ def test_attribute_for_inspect_string
t = topics(:first)
t.title = "The First Topic Now Has A Title With\nNewlines And More Than 50 Characters"
- assert_equal %("#{t.written_on.to_s(:db)}"), t.attribute_for_inspect(:written_on)
assert_equal '"The First Topic Now Has A Title With\nNewlines And ..."', t.attribute_for_inspect(:title)
end
+ def test_attribute_for_inspect_date
+ t = topics(:first)
+
+ assert_equal %("#{t.written_on.to_s(:db)}"), t.attribute_for_inspect(:written_on)
+ end
+
+ def test_attribute_for_inspect_array
+ t = topics(:first)
+ t.content = [Object.new]
+
+ assert_match %r(\[#<Object:0x[0-9a-f]+>\]), t.attribute_for_inspect(:content)
+ end
+
+ def test_attribute_for_inspect_long_array
+ t = topics(:first)
+ t.content = (1..11).to_a
+
+ assert_equal "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]", t.attribute_for_inspect(:content)
+ end
+
def test_attribute_present
t = Topic.new
t.title = "hello there!"
diff --git a/activerecord/test/cases/attribute_test.rb b/activerecord/test/cases/attribute_test.rb
index a24a4fc6a4..b1b8639696 100644
--- a/activerecord/test/cases/attribute_test.rb
+++ b/activerecord/test/cases/attribute_test.rb
@@ -242,5 +242,12 @@ module ActiveRecord
attribute.with_value_from_user(1)
end
end
+
+ test "with_type preserves mutations" do
+ attribute = Attribute.from_database(:foo, "", Type::Value.new)
+ attribute.value << "1"
+
+ assert_equal 1, attribute.with_type(Type::Integer.new).value
+ end
end
end
diff --git a/activerecord/test/cases/base_test.rb b/activerecord/test/cases/base_test.rb
index 80dcba1cf4..7b1ce40c0d 100644
--- a/activerecord/test/cases/base_test.rb
+++ b/activerecord/test/cases/base_test.rb
@@ -14,7 +14,6 @@ require 'models/auto_id'
require 'models/boolean'
require 'models/column_name'
require 'models/subscriber'
-require 'models/keyboard'
require 'models/comment'
require 'models/minimalistic'
require 'models/warehouse_thing'
@@ -25,7 +24,6 @@ require 'models/joke'
require 'models/bird'
require 'models/car'
require 'models/bulb'
-require 'rexml/document'
require 'concurrent/atomic/count_down_latch'
class FirstAbstractClass < ActiveRecord::Base
@@ -1034,12 +1032,6 @@ class BasicsTest < ActiveRecord::TestCase
assert_equal t1.title, t2.title
end
- def test_reload_with_exclusive_scope
- dev = DeveloperCalledDavid.first
- dev.update!(name: "NotDavid" )
- assert_equal dev, dev.reload
- end
-
def test_switching_between_table_name
k = Class.new(Joke)
diff --git a/activerecord/test/cases/batches_test.rb b/activerecord/test/cases/batches_test.rb
index 91ff5146fd..db71840658 100644
--- a/activerecord/test/cases/batches_test.rb
+++ b/activerecord/test/cases/batches_test.rb
@@ -170,8 +170,8 @@ class EachTest < ActiveRecord::TestCase
end
end
- def test_find_in_batches_should_not_error_if_config_overriden
- # Set the config option which will be overriden
+ def test_find_in_batches_should_not_error_if_config_overridden
+ # Set the config option which will be overridden
prev = ActiveRecord::Base.error_on_ignored_order_or_limit
ActiveRecord::Base.error_on_ignored_order_or_limit = true
assert_nothing_raised do
diff --git a/activerecord/test/cases/column_definition_test.rb b/activerecord/test/cases/column_definition_test.rb
index 81162b7e98..78c0853992 100644
--- a/activerecord/test/cases/column_definition_test.rb
+++ b/activerecord/test/cases/column_definition_test.rb
@@ -60,15 +60,8 @@ module ActiveRecord
end
def test_should_not_set_default_for_blob_and_text_data_types
- assert_raise ArgumentError do
- MySQL::Column.new("title", "a", SqlTypeMetadata.new(sql_type: "blob"))
- end
-
text_type = MySQL::TypeMetadata.new(
SqlTypeMetadata.new(type: :text))
- assert_raise ArgumentError do
- MySQL::Column.new("title", "Hello", text_type)
- end
text_column = MySQL::Column.new("title", nil, text_type)
assert_equal nil, text_column.default
diff --git a/activerecord/test/cases/invalid_date_test.rb b/activerecord/test/cases/date_test.rb
index 426a350379..f112081c14 100644
--- a/activerecord/test/cases/invalid_date_test.rb
+++ b/activerecord/test/cases/date_test.rb
@@ -1,7 +1,19 @@
require 'cases/helper'
require 'models/topic'
-class InvalidDateTest < ActiveRecord::TestCase
+class DateTest < ActiveRecord::TestCase
+ def test_date_with_time_value
+ time_value = Time.new(2016, 05, 11, 19, 0, 0)
+ topic = Topic.create(last_read: time_value)
+ assert_equal topic, Topic.find_by(last_read: time_value)
+ end
+
+ def test_date_with_string_value
+ string_value = '2016-05-11 19:00:00'
+ topic = Topic.create(last_read: string_value)
+ assert_equal topic, Topic.find_by(last_read: string_value)
+ end
+
def test_assign_valid_dates
valid_dates = [[2007, 11, 30], [1993, 2, 28], [2008, 2, 29]]
diff --git a/activerecord/test/cases/dirty_test.rb b/activerecord/test/cases/dirty_test.rb
index a3f8d26100..f9794518c7 100644
--- a/activerecord/test/cases/dirty_test.rb
+++ b/activerecord/test/cases/dirty_test.rb
@@ -5,23 +5,6 @@ require 'models/parrot'
require 'models/person' # For optimistic locking
require 'models/aircraft'
-class Pirate # Just reopening it, not defining it
- attr_accessor :detected_changes_in_after_update # Boolean for if changes are detected
- attr_accessor :changes_detected_in_after_update # Actual changes
-
- after_update :check_changes
-
-private
- # after_save/update and the model itself
- # can end up checking dirty status and acting on the results
- def check_changes
- if self.changed?
- self.detected_changes_in_after_update = true
- self.changes_detected_in_after_update = self.changes
- end
- end
-end
-
class NumericData < ActiveRecord::Base
self.table_name = 'numeric_data'
end
@@ -734,6 +717,17 @@ class DirtyTest < ActiveRecord::TestCase
assert_equal "arr", pirate.catchphrase
end
+ test "attributes assigned but not selected are dirty" do
+ person = Person.select(:id).first
+ refute person.changed?
+
+ person.first_name = "Sean"
+ assert person.changed?
+
+ person.first_name = nil
+ assert person.changed?
+ end
+
private
def with_partial_writes(klass, on = true)
old = klass.partial_writes?
diff --git a/activerecord/test/cases/enum_test.rb b/activerecord/test/cases/enum_test.rb
index babacd1ee9..e781b60464 100644
--- a/activerecord/test/cases/enum_test.rb
+++ b/activerecord/test/cases/enum_test.rb
@@ -421,4 +421,8 @@ class EnumTest < ActiveRecord::TestCase
book = Book.new
assert book.hard?
end
+
+ test "data type of Enum type" do
+ assert_equal :integer, Book.type_for_attribute('status').type
+ end
end
diff --git a/activerecord/test/cases/finder_test.rb b/activerecord/test/cases/finder_test.rb
index 374a8ba199..6eaaa30cd0 100644
--- a/activerecord/test/cases/finder_test.rb
+++ b/activerecord/test/cases/finder_test.rb
@@ -173,11 +173,9 @@ class FinderTest < ActiveRecord::TestCase
end
end
- def test_exists_fails_when_parameter_has_invalid_type
- assert_raises(ActiveModel::RangeError) do
- assert_equal false, Topic.exists?(("9"*53).to_i) # number that's bigger than int
- end
+ def test_exists_returns_false_when_parameter_has_invalid_type
assert_equal false, Topic.exists?("foo")
+ assert_equal false, Topic.exists?(("9"*53).to_i) # number that's bigger than int
end
def test_exists_does_not_select_columns_without_alias
diff --git a/activerecord/test/cases/migration/foreign_key_test.rb b/activerecord/test/cases/migration/foreign_key_test.rb
index 01162dcefe..4237e89731 100644
--- a/activerecord/test/cases/migration/foreign_key_test.rb
+++ b/activerecord/test/cases/migration/foreign_key_test.rb
@@ -232,6 +232,10 @@ module ActiveRecord
t.column :city_id, :integer
end
add_foreign_key :houses, :cities, column: "city_id"
+
+ # remove and re-add to test that schema is updated and not accidentally cached
+ remove_foreign_key :houses, :cities
+ add_foreign_key :houses, :cities, column: "city_id", on_delete: :cascade
end
end
@@ -243,6 +247,15 @@ module ActiveRecord
silence_stream($stdout) { migration.migrate(:down) }
end
+ def test_foreign_key_constraint_is_not_cached_incorrectly
+ migration = CreateCitiesAndHousesMigration.new
+ silence_stream($stdout) { migration.migrate(:up) }
+ output = dump_table_schema "houses"
+ assert_match %r{\s+add_foreign_key "houses",.+on_delete: :cascade$}, output
+ ensure
+ silence_stream($stdout) { migration.migrate(:down) }
+ end
+
class CreateSchoolsAndClassesMigration < ActiveRecord::Migration::Current
def change
create_table(:schools)
diff --git a/activerecord/test/cases/migration_test.rb b/activerecord/test/cases/migration_test.rb
index 36b6662820..d499aadbae 100644
--- a/activerecord/test/cases/migration_test.rb
+++ b/activerecord/test/cases/migration_test.rb
@@ -445,21 +445,6 @@ class MigrationTest < ActiveRecord::TestCase
ActiveRecord::Migrator.migrations_paths = old_path
end
- def test_rename_internal_metadata_table
- original_internal_metadata_table_name = ActiveRecord::Base.internal_metadata_table_name
-
- ActiveRecord::Base.internal_metadata_table_name = "active_record_internal_metadatas"
- Reminder.reset_table_name
-
- ActiveRecord::Base.internal_metadata_table_name = original_internal_metadata_table_name
- Reminder.reset_table_name
-
- assert_equal "ar_internal_metadata", ActiveRecord::InternalMetadata.table_name
- ensure
- ActiveRecord::Base.internal_metadata_table_name = original_internal_metadata_table_name
- Reminder.reset_table_name
- end
-
def test_proper_table_name_on_migration
reminder_class = new_isolated_reminder_class
migration = ActiveRecord::Migration.new
diff --git a/activerecord/test/cases/multiparameter_attributes_test.rb b/activerecord/test/cases/multiparameter_attributes_test.rb
index ae18573126..d05cb22740 100644
--- a/activerecord/test/cases/multiparameter_attributes_test.rb
+++ b/activerecord/test/cases/multiparameter_attributes_test.rb
@@ -11,15 +11,13 @@ class MultiParameterAttributeTest < ActiveRecord::TestCase
topic.attributes = attributes
# note that extra #to_date call allows test to pass for Oracle, which
# treats dates/times the same
- assert_date_from_db Date.new(2004, 6, 24), topic.last_read.to_date
+ assert_equal Date.new(2004, 6, 24), topic.last_read.to_date
end
def test_multiparameter_attributes_on_date_with_empty_year
attributes = { "last_read(1i)" => "", "last_read(2i)" => "6", "last_read(3i)" => "24" }
topic = Topic.find(1)
topic.attributes = attributes
- # note that extra #to_date call allows test to pass for Oracle, which
- # treats dates/times the same
assert_nil topic.last_read
end
@@ -27,8 +25,6 @@ class MultiParameterAttributeTest < ActiveRecord::TestCase
attributes = { "last_read(1i)" => "2004", "last_read(2i)" => "", "last_read(3i)" => "24" }
topic = Topic.find(1)
topic.attributes = attributes
- # note that extra #to_date call allows test to pass for Oracle, which
- # treats dates/times the same
assert_nil topic.last_read
end
@@ -36,8 +32,6 @@ class MultiParameterAttributeTest < ActiveRecord::TestCase
attributes = { "last_read(1i)" => "2004", "last_read(2i)" => "6", "last_read(3i)" => "" }
topic = Topic.find(1)
topic.attributes = attributes
- # note that extra #to_date call allows test to pass for Oracle, which
- # treats dates/times the same
assert_nil topic.last_read
end
@@ -45,8 +39,6 @@ class MultiParameterAttributeTest < ActiveRecord::TestCase
attributes = { "last_read(1i)" => "", "last_read(2i)" => "6", "last_read(3i)" => "" }
topic = Topic.find(1)
topic.attributes = attributes
- # note that extra #to_date call allows test to pass for Oracle, which
- # treats dates/times the same
assert_nil topic.last_read
end
@@ -54,8 +46,6 @@ class MultiParameterAttributeTest < ActiveRecord::TestCase
attributes = { "last_read(1i)" => "2004", "last_read(2i)" => "", "last_read(3i)" => "" }
topic = Topic.find(1)
topic.attributes = attributes
- # note that extra #to_date call allows test to pass for Oracle, which
- # treats dates/times the same
assert_nil topic.last_read
end
@@ -63,8 +53,6 @@ class MultiParameterAttributeTest < ActiveRecord::TestCase
attributes = { "last_read(1i)" => "", "last_read(2i)" => "", "last_read(3i)" => "24" }
topic = Topic.find(1)
topic.attributes = attributes
- # note that extra #to_date call allows test to pass for Oracle, which
- # treats dates/times the same
assert_nil topic.last_read
end
diff --git a/activerecord/test/cases/primary_keys_test.rb b/activerecord/test/cases/primary_keys_test.rb
index 52eac4a124..4267ad4a24 100644
--- a/activerecord/test/cases/primary_keys_test.rb
+++ b/activerecord/test/cases/primary_keys_test.rb
@@ -174,6 +174,14 @@ class PrimaryKeysTest < ActiveRecord::TestCase
assert_equal '2', dashboard.id
end
+ def test_create_without_primary_key_no_extra_query
+ klass = Class.new(ActiveRecord::Base) do
+ self.table_name = 'dashboards'
+ end
+ klass.create! # warmup schema cache
+ assert_queries(3, ignore_none: true) { klass.create! }
+ end
+
if current_adapter?(:PostgreSQLAdapter)
def test_serial_with_quoted_sequence_name
column = MixedCaseMonkey.columns_hash[MixedCaseMonkey.primary_key]
@@ -275,18 +283,6 @@ class CompositePrimaryKeyTest < ActiveRecord::TestCase
end
if current_adapter?(:Mysql2Adapter)
- class PrimaryKeyWithAnsiQuotesTest < ActiveRecord::TestCase
- self.use_transactional_tests = false
-
- def test_primary_key_method_with_ansi_quotes
- con = ActiveRecord::Base.connection
- con.execute("SET SESSION sql_mode='ANSI_QUOTES'")
- assert_equal "id", con.primary_key("topics")
- ensure
- con.reconnect!
- end
- end
-
class PrimaryKeyBigintNilDefaultTest < ActiveRecord::TestCase
include SchemaDumpingHelper
diff --git a/activerecord/test/cases/query_cache_test.rb b/activerecord/test/cases/query_cache_test.rb
index 406643d6fb..03ec063671 100644
--- a/activerecord/test/cases/query_cache_test.rb
+++ b/activerecord/test/cases/query_cache_test.rb
@@ -39,18 +39,6 @@ class QueryCacheTest < ActiveRecord::TestCase
assert ActiveRecord::Base.connection.query_cache_enabled, 'cache on'
end
- def test_exceptional_middleware_assigns_original_connection_id_on_error
- connection_id = ActiveRecord::Base.connection_id
-
- mw = middleware { |env|
- ActiveRecord::Base.connection_id = self.object_id
- raise "lol borked"
- }
- assert_raises(RuntimeError) { mw.call({}) }
-
- assert_equal connection_id, ActiveRecord::Base.connection_id
- end
-
def test_middleware_delegates
called = false
mw = middleware { |env|
@@ -133,7 +121,6 @@ class QueryCacheTest < ActiveRecord::TestCase
def test_cache_is_flat
Task.cache do
- Topic.columns # don't count this query
assert_queries(1) { Topic.find(1); Topic.find(1); }
end
@@ -175,6 +162,22 @@ class QueryCacheTest < ActiveRecord::TestCase
ActiveRecord::Base.configurations = conf
end
+ def test_cache_is_not_available_when_using_a_not_connected_connection
+ spec_name = Task.connection_specification_name
+ conf = ActiveRecord::Base.configurations['arunit'].merge('name' => 'test2')
+ ActiveRecord::Base.connection_handler.establish_connection(conf)
+ Task.connection_specification_name = "test2"
+ refute Task.connected?
+
+ Task.cache do
+ Task.connection # warmup postgresql connection setup queries
+ assert_queries(2) { Task.find(1); Task.find(1) }
+ end
+ ensure
+ ActiveRecord::Base.connection_handler.remove_connection(Task.connection_specification_name)
+ Task.connection_specification_name = spec_name
+ end
+
def test_query_cache_doesnt_leak_cached_results_of_rolled_back_queries
ActiveRecord::Base.connection.enable_query_cache!
post = Post.first
diff --git a/activerecord/test/cases/result_test.rb b/activerecord/test/cases/result_test.rb
index dec01dfa76..83dc5347e0 100644
--- a/activerecord/test/cases/result_test.rb
+++ b/activerecord/test/cases/result_test.rb
@@ -22,6 +22,16 @@ module ActiveRecord
], result.to_hash
end
+ test "first returns first row as a hash" do
+ assert_equal(
+ {'col_1' => 'row 1 col 1', 'col_2' => 'row 1 col 2'}, result.first)
+ end
+
+ test "last returns last row as a hash" do
+ assert_equal(
+ {'col_1' => 'row 3 col 1', 'col_2' => 'row 3 col 2'}, result.last)
+ end
+
test "each with block returns row hashes" do
result.each do |row|
assert_equal ['col_1', 'col_2'], row.keys
diff --git a/activerecord/test/cases/tasks/mysql_rake_test.rb b/activerecord/test/cases/tasks/mysql_rake_test.rb
index 8e480bbaee..70e406038f 100644
--- a/activerecord/test/cases/tasks/mysql_rake_test.rb
+++ b/activerecord/test/cases/tasks/mysql_rake_test.rb
@@ -289,7 +289,7 @@ module ActiveRecord
def test_structure_dump
filename = "awesome-file.sql"
- Kernel.expects(:system).with("mysqldump", "--result-file", filename, "--no-data", "--routines", "test-db").returns(true)
+ Kernel.expects(:system).with("mysqldump", "--result-file", filename, "--no-data", "--routines", "--skip-comments", "test-db").returns(true)
ActiveRecord::Tasks::DatabaseTasks.structure_dump(@configuration, filename)
end
@@ -297,7 +297,7 @@ module ActiveRecord
def test_warn_when_external_structure_dump_command_execution_fails
filename = "awesome-file.sql"
Kernel.expects(:system)
- .with("mysqldump", "--result-file", filename, "--no-data", "--routines", "test-db")
+ .with("mysqldump", "--result-file", filename, "--no-data", "--routines", "--skip-comments", "test-db")
.returns(false)
e = assert_raise(RuntimeError) {
@@ -308,7 +308,7 @@ module ActiveRecord
def test_structure_dump_with_port_number
filename = "awesome-file.sql"
- Kernel.expects(:system).with("mysqldump", "--port=10000", "--result-file", filename, "--no-data", "--routines", "test-db").returns(true)
+ Kernel.expects(:system).with("mysqldump", "--port=10000", "--result-file", filename, "--no-data", "--routines", "--skip-comments", "test-db").returns(true)
ActiveRecord::Tasks::DatabaseTasks.structure_dump(
@configuration.merge('port' => 10000),
@@ -317,7 +317,7 @@ module ActiveRecord
def test_structure_dump_with_ssl
filename = "awesome-file.sql"
- Kernel.expects(:system).with("mysqldump", "--ssl-ca=ca.crt", "--result-file", filename, "--no-data", "--routines", "test-db").returns(true)
+ Kernel.expects(:system).with("mysqldump", "--ssl-ca=ca.crt", "--result-file", filename, "--no-data", "--routines", "--skip-comments", "test-db").returns(true)
ActiveRecord::Tasks::DatabaseTasks.structure_dump(
@configuration.merge("sslca" => "ca.crt"),
diff --git a/activerecord/test/cases/tasks/postgresql_rake_test.rb b/activerecord/test/cases/tasks/postgresql_rake_test.rb
index 6a0c7fbcb5..99d73e91a4 100644
--- a/activerecord/test/cases/tasks/postgresql_rake_test.rb
+++ b/activerecord/test/cases/tasks/postgresql_rake_test.rb
@@ -288,14 +288,14 @@ module ActiveRecord
def test_structure_load
filename = "awesome-file.sql"
- Kernel.expects(:system).with('psql', '-q', '-f', filename, @configuration['database']).returns(true)
+ Kernel.expects(:system).with('psql', '-v', 'ON_ERROR_STOP=1', '-q', '-f', filename, @configuration['database']).returns(true)
ActiveRecord::Tasks::DatabaseTasks.structure_load(@configuration, filename)
end
def test_structure_load_accepts_path_with_spaces
filename = "awesome file.sql"
- Kernel.expects(:system).with('psql', '-q', '-f', filename, @configuration['database']).returns(true)
+ Kernel.expects(:system).with('psql', '-v', 'ON_ERROR_STOP=1', '-q', '-f', filename, @configuration['database']).returns(true)
ActiveRecord::Tasks::DatabaseTasks.structure_load(@configuration, filename)
end
diff --git a/activerecord/test/cases/test_case.rb b/activerecord/test/cases/test_case.rb
index 87299c0dab..c8adc21bbc 100644
--- a/activerecord/test/cases/test_case.rb
+++ b/activerecord/test/cases/test_case.rb
@@ -12,10 +12,6 @@ module ActiveRecord
SQLCounter.clear_log
end
- def assert_date_from_db(expected, actual, message = nil)
- assert_equal expected.to_s, actual.to_s, message
- end
-
def capture_sql
SQLCounter.clear_log
yield
diff --git a/activerecord/test/cases/validations/i18n_validation_test.rb b/activerecord/test/cases/validations/i18n_validation_test.rb
index b8307d6665..5b5307489a 100644
--- a/activerecord/test/cases/validations/i18n_validation_test.rb
+++ b/activerecord/test/cases/validations/i18n_validation_test.rb
@@ -41,10 +41,8 @@ class I18nValidationTest < ActiveRecord::TestCase
[ "given custom message", {:message => "custom"}, {:message => "custom"}],
[ "given if condition", {:if => lambda { true }}, {}],
[ "given unless condition", {:unless => lambda { false }}, {}],
- [ "given option that is not reserved", {:format => "jpg"}, {:format => "jpg" }]
- # TODO Add :on case, but below doesn't work, because then the validation isn't run for some reason
- # even when using .save instead .valid?
- # [ "given on condition", {on: :save}, {}]
+ [ "given option that is not reserved", {:format => "jpg"}, {:format => "jpg" }],
+ [ "given on condition", {on: [:create, :update] }, {}]
]
COMMON_CASES.each do |name, validation_options, generate_message_options|
diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb
index 628a59c2e3..2f2993ce18 100644
--- a/activerecord/test/schema/schema.rb
+++ b/activerecord/test/schema/schema.rb
@@ -409,6 +409,14 @@ ActiveRecord::Schema.define do
t.references :student
end
+ create_table :students, force: true do |t|
+ t.string :name
+ t.boolean :active
+ t.integer :college_id
+ end
+
+ add_foreign_key :lessons_students, :students, on_delete: :cascade
+
create_table :lint_models, force: true
create_table :line_items, force: true do |t|
@@ -777,12 +785,6 @@ ActiveRecord::Schema.define do
t.integer :lock_version, null: false, default: 0
end
- create_table :students, force: true do |t|
- t.string :name
- t.boolean :active
- t.integer :college_id
- end
-
create_table :subscribers, force: true, id: false do |t|
t.string :nick, null: false
t.string :name
@@ -1002,7 +1004,6 @@ ActiveRecord::Schema.define do
end
add_foreign_key :fk_test_has_fk, :fk_test_has_pk, column: "fk_id", name: "fk_name", primary_key: "pk_id"
- add_foreign_key :lessons_students, :students
end
create_table :overloaded_types, force: true do |t|
diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md
index 812e18a253..db439b5732 100644
--- a/activesupport/CHANGELOG.md
+++ b/activesupport/CHANGELOG.md
@@ -1,3 +1,29 @@
+* Support parsing JSON time in ISO8601 local time strings in
+ `ActiveSupport::JSON.decode` when `parse_json_times` is enabled.
+ Strings in the format of `YYYY-MM-DD hh:mm:ss` (without a `Z` at
+ the end) will be parsed in the local timezone (`Time.zone`). In
+ addition, date strings (`YYYY-MM-DD`) are now parsed into `Date`
+ objects.
+
+ *Grzegorz Witek*
+
+* Fixed `ActiveSupport::Logger.broadcast` so that calls to `#silence` now
+ properly delegate to all loggers. Silencing now properly suppresses logging
+ to both the log and the console.
+
+ *Kevin McPhillips*
+
+* Remove deprecated arguments in `assert_nothing_raised`.
+
+ *Rafel Mendonça França*
+
+* `Date.to_s` doesn't produce too many spaces. For example, `to_s(:short)`
+ will now produce `01 Feb` instead of ` 1 Feb`.
+
+ Fixes #25251.
+
+ *Sean Griffin*
+
* Introduce Module#delegate_missing_to.
When building a decorator, a common pattern emerges:
diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb
index bc114e0785..179ca13b49 100644
--- a/activesupport/lib/active_support/cache.rb
+++ b/activesupport/lib/active_support/cache.rb
@@ -250,14 +250,14 @@ module ActiveSupport
# sleep 60
#
# Thread.new do
- # val_1 = cache.fetch('foo', race_condition_ttl: 10) do
+ # val_1 = cache.fetch('foo', race_condition_ttl: 10.seconds) do
# sleep 1
# 'new value 1'
# end
# end
#
# Thread.new do
- # val_2 = cache.fetch('foo', race_condition_ttl: 10) do
+ # val_2 = cache.fetch('foo', race_condition_ttl: 10.seconds) do
# 'new value 2'
# end
# end
diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb
index 904d3f0eb0..557a4695a6 100644
--- a/activesupport/lib/active_support/callbacks.rb
+++ b/activesupport/lib/active_support/callbacks.rb
@@ -103,7 +103,7 @@ module ActiveSupport
end
# A hook invoked every time a before callback is halted.
- # This can be overridden in AS::Callback implementors in order
+ # This can be overridden in ActiveSupport::Callbacks implementors in order
# to provide better debugging/logging.
def halted_callback_hook(filter)
end
@@ -736,8 +736,13 @@ module ActiveSupport
#
# would call <tt>Audit#save</tt>.
#
- # NOTE: +method_name+ passed to `define_model_callbacks` must not end with
+ # ===== Notes
+ #
+ # +names+ passed to `define_callbacks` must not end with
# `!`, `?` or `=`.
+ #
+ # Calling `define_callbacks` multiple times with the same +names+ will
+ # overwrite previous callbacks registered with `set_callback`.
def define_callbacks(*names)
options = names.extract_options!
diff --git a/activesupport/lib/active_support/concurrency/latch.rb b/activesupport/lib/active_support/concurrency/latch.rb
index 4abe5ece6f..35074265b8 100644
--- a/activesupport/lib/active_support/concurrency/latch.rb
+++ b/activesupport/lib/active_support/concurrency/latch.rb
@@ -2,17 +2,24 @@ require 'concurrent/atomic/count_down_latch'
module ActiveSupport
module Concurrency
- class Latch < Concurrent::CountDownLatch
+ class Latch
def initialize(count = 1)
- ActiveSupport::Deprecation.warn("ActiveSupport::Concurrency::Latch is deprecated. Please use Concurrent::CountDownLatch instead.")
- super(count)
+ if count == 1
+ ActiveSupport::Deprecation.warn("ActiveSupport::Concurrency::Latch is deprecated. Please use Concurrent::Event instead.")
+ else
+ ActiveSupport::Deprecation.warn("ActiveSupport::Concurrency::Latch is deprecated. Please use Concurrent::CountDownLatch instead.")
+ end
+
+ @inner = Concurrent::CountDownLatch.new(count)
end
- alias_method :release, :count_down
+ def release
+ @inner.count_down
+ end
def await
- wait(nil)
+ @inner.wait(nil)
end
end
end
diff --git a/activesupport/lib/active_support/concurrency/share_lock.rb b/activesupport/lib/active_support/concurrency/share_lock.rb
index 89e63aefd4..cf632ea7b0 100644
--- a/activesupport/lib/active_support/concurrency/share_lock.rb
+++ b/activesupport/lib/active_support/concurrency/share_lock.rb
@@ -14,6 +14,38 @@ module ActiveSupport
# to upgrade share locks to exclusive.
+ def raw_state # :nodoc:
+ synchronize do
+ threads = @sleeping.keys | @sharing.keys | @waiting.keys
+ threads |= [@exclusive_thread] if @exclusive_thread
+
+ data = {}
+
+ threads.each do |thread|
+ purpose, compatible = @waiting[thread]
+
+ data[thread] = {
+ thread: thread,
+ sharing: @sharing[thread],
+ exclusive: @exclusive_thread == thread,
+ purpose: purpose,
+ compatible: compatible,
+ waiting: !!@waiting[thread],
+ sleeper: @sleeping[thread],
+ }
+ end
+
+ # NB: Yields while holding our *internal* synchronize lock,
+ # which is supposed to be used only for a few instructions at
+ # a time. This allows the caller to inspect additional state
+ # without things changing out from underneath, but would have
+ # disastrous effects upon normal operation. Fortunately, this
+ # method is only intended to be called when things have
+ # already gone wrong.
+ yield data
+ end
+ end
+
def initialize
super()
@@ -21,6 +53,7 @@ module ActiveSupport
@sharing = Hash.new(0)
@waiting = {}
+ @sleeping = {}
@exclusive_thread = nil
@exclusive_depth = 0
end
@@ -46,7 +79,7 @@ module ActiveSupport
return false if no_wait
yield_shares(purpose: purpose, compatible: compatible, block_share: true) do
- @cv.wait_while { busy_for_exclusive?(purpose) }
+ wait_for(:start_exclusive) { busy_for_exclusive?(purpose) }
end
end
@exclusive_thread = Thread.current
@@ -69,7 +102,7 @@ module ActiveSupport
if eligible_waiters?(compatible)
yield_shares(compatible: compatible, block_share: true) do
- @cv.wait_while { @exclusive_thread || eligible_waiters?(compatible) }
+ wait_for(:stop_exclusive) { @exclusive_thread || eligible_waiters?(compatible) }
end
end
@cv.broadcast
@@ -84,11 +117,11 @@ module ActiveSupport
elsif @waiting[Thread.current]
# We're nested inside a +yield_shares+ call: we'll resume as
# soon as there isn't an exclusive lock in our way
- @cv.wait_while { @exclusive_thread }
+ wait_for(:start_sharing) { @exclusive_thread }
else
# This is an initial / outermost share call: any outstanding
# requests for an exclusive lock get to go first
- @cv.wait_while { busy_for_sharing?(false) }
+ wait_for(:start_sharing) { busy_for_sharing?(false) }
end
@sharing[Thread.current] += 1
end
@@ -153,7 +186,7 @@ module ActiveSupport
yield
ensure
synchronize do
- @cv.wait_while { @exclusive_thread && @exclusive_thread != Thread.current }
+ wait_for(:yield_shares) { @exclusive_thread && @exclusive_thread != Thread.current }
if previous_wait
@waiting[Thread.current] = previous_wait
@@ -181,6 +214,13 @@ module ActiveSupport
def eligible_waiters?(compatible)
@waiting.any? { |t, (p, _)| compatible.include?(p) && @waiting.all? { |t2, (_, c2)| t == t2 || c2.include?(p) } }
end
+
+ def wait_for(method)
+ @sleeping[Thread.current] = method
+ @cv.wait_while { yield }
+ ensure
+ @sleeping.delete Thread.current
+ end
end
end
end
diff --git a/activesupport/lib/active_support/core_ext/date/conversions.rb b/activesupport/lib/active_support/core_ext/date/conversions.rb
index 9a6d7bb415..6e3b4a89ce 100644
--- a/activesupport/lib/active_support/core_ext/date/conversions.rb
+++ b/activesupport/lib/active_support/core_ext/date/conversions.rb
@@ -5,15 +5,15 @@ require 'active_support/core_ext/module/remove_method'
class Date
DATE_FORMATS = {
- :short => '%e %b',
- :long => '%B %e, %Y',
+ :short => '%d %b',
+ :long => '%B %d, %Y',
:db => '%Y-%m-%d',
:number => '%Y%m%d',
:long_ordinal => lambda { |date|
day_format = ActiveSupport::Inflector.ordinalize(date.day)
date.strftime("%B #{day_format}, %Y") # => "April 25th, 2007"
},
- :rfc822 => '%e %b %Y',
+ :rfc822 => '%d %b %Y',
:iso8601 => lambda { |date| date.iso8601 }
}
diff --git a/activesupport/lib/active_support/core_ext/hash/compact.rb b/activesupport/lib/active_support/core_ext/hash/compact.rb
index 62ea579c65..f072530e04 100644
--- a/activesupport/lib/active_support/core_ext/hash/compact.rb
+++ b/activesupport/lib/active_support/core_ext/hash/compact.rb
@@ -2,18 +2,21 @@ class Hash
# Returns a hash with non +nil+ values.
#
# hash = { a: true, b: false, c: nil }
- # hash.compact # => { a: true, b: false }
- # hash # => { a: true, b: false, c: nil }
- # { c: nil }.compact # => {}
+ # hash.compact # => { a: true, b: false }
+ # hash # => { a: true, b: false, c: nil }
+ # { c: nil }.compact # => {}
+ # { c: true }.compact # => { c: true }
def compact
self.select { |_, value| !value.nil? }
end
# Replaces current hash with non +nil+ values.
+ # Returns nil if no changes were made, otherwise returns the hash.
#
# hash = { a: true, b: false, c: nil }
- # hash.compact! # => { a: true, b: false }
- # hash # => { a: true, b: false }
+ # hash.compact! # => { a: true, b: false }
+ # hash # => { a: true, b: false }
+ # { c: true }.compact! # => nil
def compact!
self.reject! { |_, value| value.nil? }
end
diff --git a/activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb b/activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb
index 0b3d18301e..045668c207 100644
--- a/activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb
+++ b/activesupport/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb
@@ -25,7 +25,7 @@ class Module
# end
# # => NameError: invalid attribute name: 1_Badname
#
- # If you want to opt out the creation on the instance reader method, pass
+ # If you want to opt out of the creation of the instance reader method, pass
# <tt>instance_reader: false</tt> or <tt>instance_accessor: false</tt>.
#
# class Current
@@ -65,7 +65,7 @@ class Module
# Current.user = "DHH"
# Thread.current[:attr_Current_user] # => "DHH"
#
- # If you want to opt out the instance writer method, pass
+ # If you want to opt out of the creation of the instance writer method, pass
# <tt>instance_writer: false</tt> or <tt>instance_accessor: false</tt>.
#
# class Current
diff --git a/activesupport/lib/active_support/core_ext/module/delegation.rb b/activesupport/lib/active_support/core_ext/module/delegation.rb
index 7f968d10b5..3f6e8bd26c 100644
--- a/activesupport/lib/active_support/core_ext/module/delegation.rb
+++ b/activesupport/lib/active_support/core_ext/module/delegation.rb
@@ -164,8 +164,8 @@ class Module
''
end
- file, line = caller(1, 1).first.split(':'.freeze, 2)
- line = line.to_i
+ location = caller_locations(1, 1).first
+ file, line = location.path, location.lineno
to = to.to_s
to = "self.#{to}" if DELEGATION_RESERVED_METHOD_NAMES.include?(to)
diff --git a/activesupport/lib/active_support/core_ext/object/json.rb b/activesupport/lib/active_support/core_ext/object/json.rb
index d49b2fbe54..363bde5a68 100644
--- a/activesupport/lib/active_support/core_ext/object/json.rb
+++ b/activesupport/lib/active_support/core_ext/object/json.rb
@@ -1,6 +1,8 @@
# Hack to load json gem first so we can overwrite its to_json.
require 'json'
require 'bigdecimal'
+require 'uri/generic'
+require 'pathname'
require 'active_support/core_ext/big_decimal/conversions' # for #to_s
require 'active_support/core_ext/hash/except'
require 'active_support/core_ext/hash/slice'
@@ -192,6 +194,18 @@ class DateTime
end
end
+class URI::Generic #:nodoc:
+ def as_json(options = nil)
+ to_s
+ end
+end
+
+class Pathname #:nodoc:
+ def as_json(options = nil)
+ to_s
+ end
+end
+
class Process::Status #:nodoc:
def as_json(options = nil)
{ :exitstatus => exitstatus, :pid => pid }
diff --git a/activesupport/lib/active_support/dependencies/interlock.rb b/activesupport/lib/active_support/dependencies/interlock.rb
index f1865ca2f8..75b769574c 100644
--- a/activesupport/lib/active_support/dependencies/interlock.rb
+++ b/activesupport/lib/active_support/dependencies/interlock.rb
@@ -46,6 +46,10 @@ module ActiveSupport #:nodoc:
yield
end
end
+
+ def raw_state(&block) # :nodoc:
+ @lock.raw_state(&block)
+ end
end
end
end
diff --git a/activesupport/lib/active_support/deprecation/behaviors.rb b/activesupport/lib/active_support/deprecation/behaviors.rb
index dc24e2d0e1..35a9e5f8b8 100644
--- a/activesupport/lib/active_support/deprecation/behaviors.rb
+++ b/activesupport/lib/active_support/deprecation/behaviors.rb
@@ -2,7 +2,7 @@ require "active_support/notifications"
module ActiveSupport
# Raised when <tt>ActiveSupport::Deprecation::Behavior#behavior</tt> is set with <tt>:raise</tt>.
- # You would set <tt>:raise</tt>, as a behaviour to raise errors and proactively report exceptions from deprecations.
+ # You would set <tt>:raise</tt>, as a behavior to raise errors and proactively report exceptions from deprecations.
class DeprecationException < StandardError
end
diff --git a/activesupport/lib/active_support/evented_file_update_checker.rb b/activesupport/lib/active_support/evented_file_update_checker.rb
index 21fdf7bb80..a2dcf31132 100644
--- a/activesupport/lib/active_support/evented_file_update_checker.rb
+++ b/activesupport/lib/active_support/evented_file_update_checker.rb
@@ -3,6 +3,33 @@ require 'pathname'
require 'concurrent/atomic/atomic_boolean'
module ActiveSupport
+ # Allows you to "listen" to changes in a file system.
+ # The evented file updater does not hit disk when checking for updates
+ # instead it uses platform specific file system events to trigger a change
+ # in state.
+ #
+ # The file checker takes an array of files to watch or a hash specifying directories
+ # and file extensions to watch. It also takes a block that is called when
+ # EventedFileUpdateChecker#execute is run or when EventedFileUpdateChecker#execute_if_updated
+ # is run and there have been changes to the file system.
+ #
+ # Note: Forking will cause the first call to `updated?` to return `true`.
+ #
+ # Example:
+ #
+ # checker = EventedFileUpdateChecker.new(["/tmp/foo"], -> { puts "changed" })
+ # checker.updated?
+ # # => false
+ # checker.execute_if_updated
+ # # => nil
+ #
+ # FileUtils.touch("/tmp/foo")
+ #
+ # checker.updated?
+ # # => true
+ # checker.execute_if_updated
+ # # => "changed"
+ #
class EventedFileUpdateChecker #:nodoc: all
def initialize(files, dirs = {}, &block)
@ph = PathHelper.new
@@ -13,11 +40,13 @@ module ActiveSupport
@dirs[@ph.xpath(dir)] = Array(exts).map { |ext| @ph.normalize_extension(ext) }
end
- @block = block
- @updated = Concurrent::AtomicBoolean.new(false)
- @lcsp = @ph.longest_common_subpath(@dirs.keys)
+ @block = block
+ @updated = Concurrent::AtomicBoolean.new(false)
+ @lcsp = @ph.longest_common_subpath(@dirs.keys)
+ @pid = Process.pid
+ @boot_mutex = Mutex.new
- if (dtw = directories_to_watch).any?
+ if (@dtw = directories_to_watch).any?
# Loading listen triggers warnings. These are originated by a legit
# usage of attr_* macros for private attributes, but adds a lot of noise
# to our test suite. Thus, we lazy load it and disable warnings locally.
@@ -28,11 +57,18 @@ module ActiveSupport
raise LoadError, "Could not load the 'listen' gem. Add `gem 'listen'` to the development group of your Gemfile", e.backtrace
end
end
- Listen.to(*dtw, &method(:changed)).start
end
+ boot!
end
def updated?
+ @boot_mutex.synchronize do
+ if @pid != Process.pid
+ boot!
+ @pid = Process.pid
+ @updated.make_true
+ end
+ end
@updated.true?
end
@@ -50,6 +86,9 @@ module ActiveSupport
end
private
+ def boot!
+ Listen.to(*@dtw, &method(:changed)).start
+ end
def changed(modified, added, removed)
unless updated?
diff --git a/activesupport/lib/active_support/inflector/methods.rb b/activesupport/lib/active_support/inflector/methods.rb
index f94e12e14f..f14b8b81b7 100644
--- a/activesupport/lib/active_support/inflector/methods.rb
+++ b/activesupport/lib/active_support/inflector/methods.rb
@@ -238,8 +238,8 @@ module ActiveSupport
# Tries to find a constant with the name specified in the argument string.
#
- # 'Module'.constantize # => Module
- # 'Foo::Bar'.constantize # => Foo::Bar
+ # constantize('Module') # => Module
+ # constantize('Foo::Bar') # => Foo::Bar
#
# The name is assumed to be the one of a top-level constant, no matter
# whether it starts with "::" or not. No lexical context is taken into
@@ -248,8 +248,8 @@ module ActiveSupport
# C = 'outside'
# module M
# C = 'inside'
- # C # => 'inside'
- # 'C'.constantize # => 'outside', same as ::C
+ # C # => 'inside'
+ # constantize('C') # => 'outside', same as ::C
# end
#
# NameError is raised when the name is not in CamelCase or the constant is
diff --git a/activesupport/lib/active_support/json/decoding.rb b/activesupport/lib/active_support/json/decoding.rb
index 2932954f03..64e4b0e7a9 100644
--- a/activesupport/lib/active_support/json/decoding.rb
+++ b/activesupport/lib/active_support/json/decoding.rb
@@ -8,7 +8,8 @@ module ActiveSupport
module JSON
# matches YAML-formatted dates
- DATE_REGEX = /^(?:\d{4}-\d{2}-\d{2}|\d{4}-\d{1,2}-\d{1,2}[T \t]+\d{1,2}:\d{2}:\d{2}(\.[0-9]*)?(([ \t]*)Z|[-+]\d{2}?(:\d{2})?))$/
+ DATE_REGEX = /^\d{4}-\d{2}-\d{2}$/
+ DATETIME_REGEX = /^(?:\d{4}-\d{2}-\d{2}|\d{4}-\d{1,2}-\d{1,2}[T \t]+\d{1,2}:\d{2}:\d{2}(\.[0-9]*)?(([ \t]*)Z|[-+]\d{2}?(:\d{2})?)?)$/
class << self
# Parses a JSON string (JavaScript Object Notation) into a hash.
@@ -48,7 +49,13 @@ module ActiveSupport
nil
when DATE_REGEX
begin
- DateTime.parse(data)
+ Date.parse(data)
+ rescue ArgumentError
+ data
+ end
+ when DATETIME_REGEX
+ begin
+ Time.zone.parse(data)
rescue ArgumentError
data
end
diff --git a/activesupport/lib/active_support/key_generator.rb b/activesupport/lib/active_support/key_generator.rb
index 7f73f9ddfc..0f0e931c06 100644
--- a/activesupport/lib/active_support/key_generator.rb
+++ b/activesupport/lib/active_support/key_generator.rb
@@ -31,11 +31,9 @@ module ActiveSupport
@cache_keys = Concurrent::Map.new
end
- # Returns a derived key suitable for use. The default key_size is chosen
- # to be compatible with the default settings of ActiveSupport::MessageVerifier.
- # i.e. OpenSSL::Digest::SHA1#block_length
- def generate_key(salt, key_size=64)
- @cache_keys["#{salt}#{key_size}"] ||= @key_generator.generate_key(salt, key_size)
+ # Returns a derived key suitable for use.
+ def generate_key(*args)
+ @cache_keys[args.join] ||= @key_generator.generate_key(*args)
end
end
diff --git a/activesupport/lib/active_support/logger.rb b/activesupport/lib/active_support/logger.rb
index de48e717b6..92b890dbb0 100644
--- a/activesupport/lib/active_support/logger.rb
+++ b/activesupport/lib/active_support/logger.rb
@@ -55,6 +55,24 @@ module ActiveSupport
logger.local_level = level if logger.respond_to?(:local_level=)
super(level) if respond_to?(:local_level=)
end
+
+ define_method(:silence) do |level = Logger::ERROR, &block|
+ if logger.respond_to?(:silence)
+ logger.silence(level) do
+ if respond_to?(:silence)
+ super(level, &block)
+ else
+ block.call(self)
+ end
+ end
+ else
+ if respond_to?(:silence)
+ super(level, &block)
+ else
+ block.call(self)
+ end
+ end
+ end
end
end
diff --git a/activesupport/lib/active_support/ordered_options.rb b/activesupport/lib/active_support/ordered_options.rb
index 53a55bd986..501ba7fc76 100644
--- a/activesupport/lib/active_support/ordered_options.rb
+++ b/activesupport/lib/active_support/ordered_options.rb
@@ -1,3 +1,5 @@
+require 'active_support/core_ext/object/blank'
+
module ActiveSupport
# Usually key value pairs are handled something like this:
#
diff --git a/activesupport/lib/active_support/per_thread_registry.rb b/activesupport/lib/active_support/per_thread_registry.rb
index 88e2b12cc7..18ca951372 100644
--- a/activesupport/lib/active_support/per_thread_registry.rb
+++ b/activesupport/lib/active_support/per_thread_registry.rb
@@ -1,7 +1,7 @@
require 'active_support/core_ext/module/delegation'
module ActiveSupport
- # NOTE: This approach has been deprecated for end-user code in favor of thread_mattr_accessor and friends.
+ # NOTE: This approach has been deprecated for end-user code in favor of {thread_mattr_accessor}[rdoc-ref:Module#thread_mattr_accessor] and friends.
# Please use that approach instead.
#
# This module is used to encapsulate access to thread local variables.
diff --git a/activesupport/lib/active_support/test_case.rb b/activesupport/lib/active_support/test_case.rb
index 1fc12d0bc1..221e1171e7 100644
--- a/activesupport/lib/active_support/test_case.rb
+++ b/activesupport/lib/active_support/test_case.rb
@@ -74,12 +74,7 @@ module ActiveSupport
# assert_nothing_raised do
# perform_service(param: 'no_exception')
# end
- def assert_nothing_raised(*args)
- if args.present?
- ActiveSupport::Deprecation.warn(
- "Passing arguments to assert_nothing_raised " \
- "is deprecated and will be removed in Rails 5.1.")
- end
+ def assert_nothing_raised
yield
end
end
diff --git a/activesupport/lib/active_support/testing/assertions.rb b/activesupport/lib/active_support/testing/assertions.rb
index 29305e0082..ad83638572 100644
--- a/activesupport/lib/active_support/testing/assertions.rb
+++ b/activesupport/lib/active_support/testing/assertions.rb
@@ -1,5 +1,3 @@
-require 'active_support/core_ext/object/blank'
-
module ActiveSupport
module Testing
module Assertions
diff --git a/activesupport/lib/active_support/testing/isolation.rb b/activesupport/lib/active_support/testing/isolation.rb
index edf8b30a0a..7dd03ce65d 100644
--- a/activesupport/lib/active_support/testing/isolation.rb
+++ b/activesupport/lib/active_support/testing/isolation.rb
@@ -13,17 +13,6 @@ module ActiveSupport
!ENV["NO_FORK"] && Process.respond_to?(:fork)
end
- @@class_setup_mutex = Mutex.new
-
- def _run_class_setup # class setup method should only happen in parent
- @@class_setup_mutex.synchronize do
- unless defined?(@@ran_class_setup) || ENV['ISOLATION_TEST']
- self.class.setup if self.class.respond_to?(:setup)
- @@ran_class_setup = true
- end
- end
- end
-
def run
serialized = run_in_isolation do
super
diff --git a/activesupport/lib/active_support/testing/time_helpers.rb b/activesupport/lib/active_support/testing/time_helpers.rb
index fca0947c5b..ef27ce8eb5 100644
--- a/activesupport/lib/active_support/testing/time_helpers.rb
+++ b/activesupport/lib/active_support/testing/time_helpers.rb
@@ -66,7 +66,7 @@ module ActiveSupport
# +Date.today+, and +DateTime.now+ to return the time or date passed into this method.
#
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
- # travel_to Time.new(2004, 11, 24, 01, 04, 44)
+ # travel_to Time.zone.local(2004, 11, 24, 01, 04, 44)
# Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
# Date.current # => Wed, 24 Nov 2004
# DateTime.current # => Wed, 24 Nov 2004 01:04:44 -0500
@@ -88,7 +88,7 @@ module ActiveSupport
# state at the end of the block:
#
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
- # travel_to Time.new(2004, 11, 24, 01, 04, 44) do
+ # travel_to Time.zone.local(2004, 11, 24, 01, 04, 44) do
# Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
# end
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
@@ -116,7 +116,7 @@ module ActiveSupport
# `travel` and `travel_to`.
#
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
- # travel_to Time.new(2004, 11, 24, 01, 04, 44)
+ # travel_to Time.zone.local(2004, 11, 24, 01, 04, 44)
# Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
# travel_back
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
diff --git a/activesupport/test/broadcast_logger_test.rb b/activesupport/test/broadcast_logger_test.rb
index 6d4e3b74f7..f95b3e5ad3 100644
--- a/activesupport/test/broadcast_logger_test.rb
+++ b/activesupport/test/broadcast_logger_test.rb
@@ -3,75 +3,147 @@ require 'abstract_unit'
module ActiveSupport
class BroadcastLoggerTest < TestCase
attr_reader :logger, :log1, :log2
- def setup
+
+ setup do
@log1 = FakeLogger.new
@log2 = FakeLogger.new
@log1.extend Logger.broadcast @log2
@logger = @log1
end
- def test_debug
- logger.debug "foo"
- assert_equal 'foo', log1.adds.first[2]
- assert_equal 'foo', log2.adds.first[2]
+ Logger::Severity.constants.each do |level_name|
+ method = level_name.downcase
+ level = Logger::Severity.const_get(level_name)
+
+ test "##{method} adds the message to all loggers" do
+ logger.send(method, "msg")
+
+ assert_equal [level, "msg", nil], log1.adds.first
+ assert_equal [level, "msg", nil], log2.adds.first
+ end
end
- def test_close
+ test "#close broadcasts to all loggers" do
logger.close
+
assert log1.closed, 'should be closed'
assert log2.closed, 'should be closed'
end
- def test_chevrons
+ test "#<< shovels the value into all loggers" do
logger << "foo"
+
assert_equal %w{ foo }, log1.chevrons
assert_equal %w{ foo }, log2.chevrons
end
- def test_level
- assert_nil logger.level
- logger.level = 10
- assert_equal 10, log1.level
- assert_equal 10, log2.level
+ test "#level= assigns the level to all loggers" do
+ assert_equal ::Logger::DEBUG, logger.level
+ logger.level = ::Logger::FATAL
+
+ assert_equal ::Logger::FATAL, log1.level
+ assert_equal ::Logger::FATAL, log2.level
end
- def test_progname
+ test "#progname= assigns to all the loggers" do
assert_nil logger.progname
- logger.progname = 10
- assert_equal 10, log1.progname
- assert_equal 10, log2.progname
+ logger.progname = ::Logger::FATAL
+
+ assert_equal ::Logger::FATAL, log1.progname
+ assert_equal ::Logger::FATAL, log2.progname
end
- def test_formatter
+ test "#formatter= assigns to all the loggers" do
assert_nil logger.formatter
- logger.formatter = 10
- assert_equal 10, log1.formatter
- assert_equal 10, log2.formatter
+ logger.formatter = ::Logger::FATAL
+
+ assert_equal ::Logger::FATAL, log1.formatter
+ assert_equal ::Logger::FATAL, log2.formatter
+ end
+
+ test "#local_level= assigns the local_level to all loggers" do
+ assert_equal ::Logger::DEBUG, logger.local_level
+ logger.local_level = ::Logger::FATAL
+
+ assert_equal ::Logger::FATAL, log1.local_level
+ assert_equal ::Logger::FATAL, log2.local_level
+ end
+
+ test "#silence silences all loggers below the default level of ERROR" do
+ logger.silence do
+ logger.debug "test"
+ end
+
+ assert_equal [], log1.adds
+ assert_equal [], log2.adds
+ end
+
+ test "#silence does not silence at or above ERROR" do
+ logger.silence do
+ logger.error "from error"
+ logger.unknown "from unknown"
+ end
+
+ assert_equal [[::Logger::ERROR, "from error", nil], [::Logger::UNKNOWN, "from unknown", nil]], log1.adds
+ assert_equal [[::Logger::ERROR, "from error", nil], [::Logger::UNKNOWN, "from unknown", nil]], log2.adds
+ end
+
+ test "#silence allows you to override the silence level" do
+ logger.silence(::Logger::FATAL) do
+ logger.error "unseen"
+ logger.fatal "seen"
+ end
+
+ assert_equal [[::Logger::FATAL, "seen", nil]], log1.adds
+ assert_equal [[::Logger::FATAL, "seen", nil]], log2.adds
end
class FakeLogger
+ include LoggerSilence
+
attr_reader :adds, :closed, :chevrons
- attr_accessor :level, :progname, :formatter
+ attr_accessor :level, :progname, :formatter, :local_level
def initialize
- @adds = []
- @closed = false
- @chevrons = []
- @level = nil
- @progname = nil
- @formatter = nil
+ @adds = []
+ @closed = false
+ @chevrons = []
+ @level = ::Logger::DEBUG
+ @local_level = ::Logger::DEBUG
+ @progname = nil
+ @formatter = nil
+ end
+
+ def debug(message, &block)
+ add(::Logger::DEBUG, message, &block)
+ end
+
+ def info(message, &block)
+ add(::Logger::INFO, message, &block)
+ end
+
+ def warn(message, &block)
+ add(::Logger::WARN, message, &block)
+ end
+
+ def error(message, &block)
+ add(::Logger::ERROR, message, &block)
+ end
+
+ def fatal(message, &block)
+ add(::Logger::FATAL, message, &block)
end
- def debug msg, &block
- add(:omg, nil, msg, &block)
+ def unknown(message, &block)
+ add(::Logger::UNKNOWN, message, &block)
end
def << x
@chevrons << x
end
- def add(*args)
- @adds << args
+ def add(message_level, message=nil, progname=nil, &block)
+ @adds << [message_level, message, progname] if message_level >= local_level
end
def close
diff --git a/activesupport/test/core_ext/date_ext_test.rb b/activesupport/test/core_ext/date_ext_test.rb
index 8052d38c33..a7219eee31 100644
--- a/activesupport/test/core_ext/date_ext_test.rb
+++ b/activesupport/test/core_ext/date_ext_test.rb
@@ -30,6 +30,17 @@ class DateExtCalculationsTest < ActiveSupport::TestCase
assert_equal "2005-02-21", date.to_s(:iso8601)
end
+ def test_to_s_with_single_digit_day
+ date = Date.new(2005, 2, 1)
+ assert_equal "2005-02-01", date.to_s
+ assert_equal "01 Feb", date.to_s(:short)
+ assert_equal "February 01, 2005", date.to_s(:long)
+ assert_equal "February 1st, 2005", date.to_s(:long_ordinal)
+ assert_equal "2005-02-01", date.to_s(:db)
+ assert_equal "01 Feb 2005", date.to_s(:rfc822)
+ assert_equal "2005-02-01", date.to_s(:iso8601)
+ end
+
def test_readable_inspect
assert_equal "Mon, 21 Feb 2005", Date.new(2005, 2, 21).readable_inspect
assert_equal Date.new(2005, 2, 21).readable_inspect, Date.new(2005, 2, 21).inspect
diff --git a/activesupport/test/core_ext/hash_ext_test.rb b/activesupport/test/core_ext/hash_ext_test.rb
index f0a4c4dddc..e8099baa35 100644
--- a/activesupport/test/core_ext/hash_ext_test.rb
+++ b/activesupport/test/core_ext/hash_ext_test.rb
@@ -999,6 +999,10 @@ class HashExtTest < ActiveSupport::TestCase
h = hash_with_only_nil_values.dup
assert_equal({}, h.compact)
assert_equal(hash_with_only_nil_values, h)
+
+ h = @symbols.dup
+ assert_equal(@symbols, h.compact)
+ assert_equal(@symbols, h)
end
def test_compact!
@@ -1012,6 +1016,10 @@ class HashExtTest < ActiveSupport::TestCase
h = hash_with_only_nil_values.dup
assert_equal({}, h.compact!)
assert_equal({}, h)
+
+ h = @symbols.dup
+ assert_equal(nil, h.compact!)
+ assert_equal(@symbols, h)
end
def test_new_with_to_hash_conversion
@@ -1034,7 +1042,7 @@ class HashExtTest < ActiveSupport::TestCase
assert_equal 3, new_hash[2]
new_hash.default = 2
- assert_equal 2, new_hash[:non_existant]
+ assert_equal 2, new_hash[:non_existent]
end
def test_to_hash_with_raising_default_proc
diff --git a/activesupport/test/deprecation_test.rb b/activesupport/test/deprecation_test.rb
index ec34bd823d..dbde3d2e15 100644
--- a/activesupport/test/deprecation_test.rb
+++ b/activesupport/test/deprecation_test.rb
@@ -143,7 +143,7 @@ class DeprecationTest < ActiveSupport::TestCase
stderr_output = capture(:stderr) {
assert_nil behavior.call('Some error!', ['call stack!'])
}
- assert stderr_output.blank?
+ assert stderr_output.empty?
end
def test_deprecated_instance_variable_proxy
diff --git a/activesupport/test/evented_file_update_checker_test.rb b/activesupport/test/evented_file_update_checker_test.rb
index bc3f77bd54..2cb2d8167f 100644
--- a/activesupport/test/evented_file_update_checker_test.rb
+++ b/activesupport/test/evented_file_update_checker_test.rb
@@ -11,7 +11,7 @@ class EventedFileUpdateCheckerTest < ActiveSupport::TestCase
end
def new_checker(files = [], dirs = {}, &block)
- ActiveSupport::EventedFileUpdateChecker.new(files, dirs, &block).tap do
+ ActiveSupport::EventedFileUpdateChecker.new(files, dirs, &block).tap do |c|
wait
end
end
@@ -34,6 +34,48 @@ class EventedFileUpdateCheckerTest < ActiveSupport::TestCase
super
wait
end
+
+ test 'notifies forked processes' do
+ FileUtils.touch(tmpfiles)
+
+ checker = new_checker(tmpfiles) { }
+ assert !checker.updated?
+
+ # Pipes used for flow controll across fork.
+ boot_reader, boot_writer = IO.pipe
+ touch_reader, touch_writer = IO.pipe
+
+ pid = fork do
+ assert checker.updated?
+
+ # Clear previous check value.
+ checker.execute
+ assert !checker.updated?
+
+ # Fork is booted, ready for file to be touched
+ # notify parent process.
+ boot_writer.write("booted")
+
+ # Wait for parent process to signal that file
+ # has been touched.
+ IO.select([touch_reader])
+
+ assert checker.updated?
+ end
+
+ assert pid
+
+ # Wait for fork to be booted before touching files.
+ IO.select([boot_reader])
+ touch(tmpfiles)
+
+ # Notify fork that files have been touched.
+ touch_writer.write("touched")
+
+ assert checker.updated?
+
+ Process.wait(pid)
+ end
end
class EventedFileUpdateCheckerPathHelperTest < ActiveSupport::TestCase
diff --git a/activesupport/test/json/decoding_test.rb b/activesupport/test/json/decoding_test.rb
index f2fc456f4b..887ef1681d 100644
--- a/activesupport/test/json/decoding_test.rb
+++ b/activesupport/test/json/decoding_test.rb
@@ -1,8 +1,11 @@
require 'abstract_unit'
require 'active_support/json'
require 'active_support/time'
+require 'time_zone_test_helpers'
class TestJSONDecoding < ActiveSupport::TestCase
+ include TimeZoneTestHelpers
+
class Foo
def self.json_create(object)
"Foo"
@@ -24,10 +27,11 @@ class TestJSONDecoding < ActiveSupport::TestCase
%(["2007-01-01 01:12:34 Z"]) => [Time.utc(2007, 1, 1, 1, 12, 34)],
%(["2007-01-01 01:12:34 Z", "2007-01-01 01:12:35 Z"]) => [Time.utc(2007, 1, 1, 1, 12, 34), Time.utc(2007, 1, 1, 1, 12, 35)],
# no time zone
- %({"a": "2007-01-01 01:12:34"}) => {'a' => "2007-01-01 01:12:34"},
+ %({"a": "2007-01-01 01:12:34"}) => {'a' => Time.new(2007, 1, 1, 1, 12, 34, "-05:00")},
# invalid date
%({"a": "1089-10-40"}) => {'a' => "1089-10-40"},
# xmlschema date notation
+ %({"a": "2009-08-10T19:01:02"}) => {'a' => Time.new(2009, 8, 10, 19, 1, 2, "-04:00")},
%({"a": "2009-08-10T19:01:02Z"}) => {'a' => Time.utc(2009, 8, 10, 19, 1, 2)},
%({"a": "2009-08-10T19:01:02+02:00"}) => {'a' => Time.utc(2009, 8, 10, 17, 1, 2)},
%({"a": "2009-08-10T19:01:02-05:00"}) => {'a' => Time.utc(2009, 8, 11, 00, 1, 2)},
@@ -72,10 +76,12 @@ class TestJSONDecoding < ActiveSupport::TestCase
TESTS.each_with_index do |(json, expected), index|
test "json decodes #{index}" do
- with_parse_json_times(true) do
- silence_warnings do
- assert_equal expected, ActiveSupport::JSON.decode(json), "JSON decoding \
- failed for #{json}"
+ with_tz_default 'Eastern Time (US & Canada)' do
+ with_parse_json_times(true) do
+ silence_warnings do
+ assert_equal expected, ActiveSupport::JSON.decode(json), "JSON decoding \
+ failed for #{json}"
+ end
end
end
end
diff --git a/activesupport/test/json/encoding_test_cases.rb b/activesupport/test/json/encoding_test_cases.rb
index 0159ba8606..e043fadf56 100644
--- a/activesupport/test/json/encoding_test_cases.rb
+++ b/activesupport/test/json/encoding_test_cases.rb
@@ -76,6 +76,10 @@ module JSONTest
RegexpTests = [[ /^a/, '"(?-mix:^a)"' ], [/^\w{1,2}[a-z]+/ix, '"(?ix-m:^\\\\w{1,2}[a-z]+)"']]
+ URITests = [[ URI.parse('http://example.com'), %("http://example.com") ]]
+
+ PathnameTests = [[ Pathname.new('lib/index.rb'), %("lib/index.rb") ]]
+
DateTests = [[ Date.new(2005,2,1), %("2005/02/01") ]]
TimeTests = [[ Time.utc(2005,2,1,15,15,10), %("2005/02/01 15:15:10 +0000") ]]
DateTimeTests = [[ DateTime.civil(2005,2,1,15,15,10), %("2005/02/01 15:15:10 +0000") ]]
diff --git a/activesupport/test/key_generator_test.rb b/activesupport/test/key_generator_test.rb
index f7e8e9a795..b60077460e 100644
--- a/activesupport/test/key_generator_test.rb
+++ b/activesupport/test/key_generator_test.rb
@@ -19,7 +19,7 @@ class KeyGeneratorTest < ActiveSupport::TestCase
test "Generating a key of the default length" do
derived_key = @generator.generate_key("some_salt")
assert_kind_of String, derived_key
- assert_equal OpenSSL::Digest::SHA1.new.block_length, derived_key.length, "Should have generated a key of the default size"
+ assert_equal 64, derived_key.length, "Should have generated a key of the default size"
end
test "Generating a key of an alternative length" do
@@ -27,6 +27,21 @@ class KeyGeneratorTest < ActiveSupport::TestCase
assert_kind_of String, derived_key
assert_equal 32, derived_key.length, "Should have generated a key of the right size"
end
+
+ test "Expected results" do
+ # For any given set of inputs, this method must continue to return
+ # the same output: if it changes, any existing values relying on a
+ # key would break.
+
+ expected = "b129376f68f1ecae788d7433310249d65ceec090ecacd4c872a3a9e9ec78e055739be5cc6956345d5ae38e7e1daa66f1de587dc8da2bf9e8b965af4b3918a122"
+ assert_equal expected, ActiveSupport::KeyGenerator.new("0" * 64).generate_key("some_salt").unpack('H*').first
+
+ expected = "b129376f68f1ecae788d7433310249d65ceec090ecacd4c872a3a9e9ec78e055"
+ assert_equal expected, ActiveSupport::KeyGenerator.new("0" * 64).generate_key("some_salt", 32).unpack('H*').first
+
+ expected = "cbea7f7f47df705967dc508f4e446fd99e7797b1d70011c6899cd39bbe62907b8508337d678505a7dc8184e037f1003ba3d19fc5d829454668e91d2518692eae"
+ assert_equal expected, ActiveSupport::KeyGenerator.new("0" * 64, iterations: 2).generate_key("some_salt").unpack('H*').first
+ end
end
class CachingKeyGeneratorTest < ActiveSupport::TestCase
diff --git a/activesupport/test/logger_test.rb b/activesupport/test/logger_test.rb
index 5a91420f1e..dfc5f3fdf4 100644
--- a/activesupport/test/logger_test.rb
+++ b/activesupport/test/logger_test.rb
@@ -143,12 +143,13 @@ class LoggerTest < ActiveSupport::TestCase
def test_logger_silencing_works_for_broadcast
another_output = StringIO.new
- another_logger = Logger.new(another_output)
+ another_logger = ActiveSupport::Logger.new(another_output)
- @logger.extend Logger.broadcast(another_logger)
+ @logger.extend ActiveSupport::Logger.broadcast(another_logger)
@logger.debug "CORRECT DEBUG"
- @logger.silence do
+ @logger.silence do |logger|
+ assert_kind_of ActiveSupport::Logger, logger
@logger.debug "FAILURE"
@logger.error "CORRECT ERROR"
end
@@ -166,10 +167,11 @@ class LoggerTest < ActiveSupport::TestCase
another_output = StringIO.new
another_logger = ::Logger.new(another_output)
- @logger.extend Logger.broadcast(another_logger)
+ @logger.extend ActiveSupport::Logger.broadcast(another_logger)
@logger.debug "CORRECT DEBUG"
- @logger.silence do
+ @logger.silence do |logger|
+ assert_kind_of ActiveSupport::Logger, logger
@logger.debug "FAILURE"
@logger.error "CORRECT ERROR"
end
diff --git a/activesupport/test/message_encryptor_test.rb b/activesupport/test/message_encryptor_test.rb
index eb71369397..a1ff4c1d3e 100644
--- a/activesupport/test/message_encryptor_test.rb
+++ b/activesupport/test/message_encryptor_test.rb
@@ -15,7 +15,7 @@ class MessageEncryptorTest < ActiveSupport::TestCase
end
def setup
- @secret = SecureRandom.hex(64)
+ @secret = SecureRandom.random_bytes(32)
@verifier = ActiveSupport::MessageVerifier.new(@secret, :serializer => ActiveSupport::MessageEncryptor::NullSerializer)
@encryptor = ActiveSupport::MessageEncryptor.new(@secret)
@data = { :some => "data", :now => Time.local(2010) }
@@ -51,7 +51,7 @@ class MessageEncryptorTest < ActiveSupport::TestCase
def test_alternative_serialization_method
prev = ActiveSupport.use_standard_json_time_format
ActiveSupport.use_standard_json_time_format = true
- encryptor = ActiveSupport::MessageEncryptor.new(SecureRandom.hex(64), SecureRandom.hex(64), :serializer => JSONSerializer.new)
+ encryptor = ActiveSupport::MessageEncryptor.new(SecureRandom.random_bytes(32), SecureRandom.random_bytes(128), :serializer => JSONSerializer.new)
message = encryptor.encrypt_and_sign({ :foo => 123, 'bar' => Time.utc(2010) })
exp = { "foo" => 123, "bar" => "2010-01-01T00:00:00.000Z" }
assert_equal exp, encryptor.decrypt_and_verify(message)
diff --git a/activesupport/test/multibyte_conformance_test.rb b/activesupport/test/multibyte_conformance_test.rb
index 9fca47a985..c10133a7a6 100644
--- a/activesupport/test/multibyte_conformance_test.rb
+++ b/activesupport/test/multibyte_conformance_test.rb
@@ -6,29 +6,9 @@ require 'open-uri'
require 'tmpdir'
class MultibyteConformanceTest < ActiveSupport::TestCase
- class Downloader
- def self.download(from, to)
- unless File.exist?(to)
- unless File.exist?(File.dirname(to))
- system "mkdir -p #{File.dirname(to)}"
- end
- open(from) do |source|
- File.open(to, 'w') do |target|
- source.each_line do |l|
- target.write l
- end
- end
- end
- end
- true
- end
- end
-
include MultibyteTestHelpers
- UNIDATA_URL = "http://www.unicode.org/Public/#{ActiveSupport::Multibyte::Unicode::UNICODE_VERSION}/ucd"
UNIDATA_FILE = '/NormalizationTest.txt'
- CACHE_DIR = "#{Dir.tmpdir}/cache/unicode_conformance"
FileUtils.mkdir_p(CACHE_DIR)
RUN_P = begin
Downloader.download(UNIDATA_URL + UNIDATA_FILE, CACHE_DIR + UNIDATA_FILE)
diff --git a/activesupport/test/multibyte_grapheme_break_conformance_test.rb b/activesupport/test/multibyte_grapheme_break_conformance_test.rb
index 6e2f02abed..61943b1ab3 100644
--- a/activesupport/test/multibyte_grapheme_break_conformance_test.rb
+++ b/activesupport/test/multibyte_grapheme_break_conformance_test.rb
@@ -1,37 +1,23 @@
# encoding: utf-8
require 'abstract_unit'
+require 'multibyte_test_helpers'
require 'fileutils'
require 'open-uri'
require 'tmpdir'
class MultibyteGraphemeBreakConformanceTest < ActiveSupport::TestCase
- class Downloader
- def self.download(from, to)
- unless File.exist?(to)
- $stderr.puts "Downloading #{from} to #{to}"
- unless File.exist?(File.dirname(to))
- system "mkdir -p #{File.dirname(to)}"
- end
- open(from) do |source|
- File.open(to, 'w') do |target|
- source.each_line do |l|
- target.write l
- end
- end
- end
- end
- end
- end
+ include MultibyteTestHelpers
- TEST_DATA_URL = "http://www.unicode.org/Public/#{ActiveSupport::Multibyte::Unicode::UNICODE_VERSION}/ucd/auxiliary"
- TEST_DATA_FILE = '/GraphemeBreakTest.txt'
- CACHE_DIR = "#{Dir.tmpdir}/cache/unicode_conformance"
+ UNIDATA_FILE = '/auxiliary/GraphemeBreakTest.txt'
+ RUN_P = begin
+ Downloader.download(UNIDATA_URL + UNIDATA_FILE, CACHE_DIR + UNIDATA_FILE)
+ rescue
+ end
def setup
- FileUtils.mkdir_p(CACHE_DIR)
- Downloader.download(TEST_DATA_URL + TEST_DATA_FILE, CACHE_DIR + TEST_DATA_FILE)
+ skip "Unable to download test data" unless RUN_P
end
def test_breaks
@@ -46,7 +32,7 @@ class MultibyteGraphemeBreakConformanceTest < ActiveSupport::TestCase
def each_line_of_break_tests(&block)
lines = 0
max_test_lines = 0 # Don't limit below 21, because that's the header of the testfile
- File.open(File.join(CACHE_DIR, TEST_DATA_FILE), 'r') do | f |
+ File.open(File.join(CACHE_DIR, UNIDATA_FILE), 'r') do | f |
until f.eof? || (max_test_lines > 21 and lines > max_test_lines)
lines += 1
line = f.gets.chomp!
diff --git a/activesupport/test/multibyte_normalization_conformance_test.rb b/activesupport/test/multibyte_normalization_conformance_test.rb
index 0d31c9520f..77ed0ce6de 100644
--- a/activesupport/test/multibyte_normalization_conformance_test.rb
+++ b/activesupport/test/multibyte_normalization_conformance_test.rb
@@ -8,34 +8,17 @@ require 'open-uri'
require 'tmpdir'
class MultibyteNormalizationConformanceTest < ActiveSupport::TestCase
- class Downloader
- def self.download(from, to)
- unless File.exist?(to)
- $stderr.puts "Downloading #{from} to #{to}"
- unless File.exist?(File.dirname(to))
- system "mkdir -p #{File.dirname(to)}"
- end
- open(from) do |source|
- File.open(to, 'w') do |target|
- source.each_line do |l|
- target.write l
- end
- end
- end
- end
- end
- end
-
include MultibyteTestHelpers
- UNIDATA_URL = "http://www.unicode.org/Public/#{ActiveSupport::Multibyte::Unicode::UNICODE_VERSION}/ucd"
UNIDATA_FILE = '/NormalizationTest.txt'
- CACHE_DIR = "#{Dir.tmpdir}/cache/unicode_conformance"
+ RUN_P = begin
+ Downloader.download(UNIDATA_URL + UNIDATA_FILE, CACHE_DIR + UNIDATA_FILE)
+ rescue
+ end
def setup
- FileUtils.mkdir_p(CACHE_DIR)
- Downloader.download(UNIDATA_URL + UNIDATA_FILE, CACHE_DIR + UNIDATA_FILE)
@proxy = ActiveSupport::Multibyte::Chars
+ skip "Unable to download test data" unless RUN_P
end
def test_normalizations_C
diff --git a/activesupport/test/multibyte_test_helpers.rb b/activesupport/test/multibyte_test_helpers.rb
index 58cf5488cd..0ada8bc032 100644
--- a/activesupport/test/multibyte_test_helpers.rb
+++ b/activesupport/test/multibyte_test_helpers.rb
@@ -1,4 +1,26 @@
module MultibyteTestHelpers
+ class Downloader
+ def self.download(from, to)
+ unless File.exist?(to)
+ unless File.exist?(File.dirname(to))
+ system "mkdir -p #{File.dirname(to)}"
+ end
+ open(from) do |source|
+ File.open(to, 'w') do |target|
+ source.each_line do |l|
+ target.write l
+ end
+ end
+ end
+ end
+ true
+ end
+ end
+
+ UNIDATA_URL = "http://www.unicode.org/Public/#{ActiveSupport::Multibyte::Unicode::UNICODE_VERSION}/ucd"
+ CACHE_DIR = "#{Dir.tmpdir}/cache/unicode_conformance"
+ FileUtils.mkdir_p(CACHE_DIR)
+
UNICODE_STRING = 'こにちわ'.freeze
ASCII_STRING = 'ohayo'.freeze
BYTE_STRING = "\270\236\010\210\245".force_encoding("ASCII-8BIT").freeze
diff --git a/activesupport/test/testing/file_fixtures_test.rb b/activesupport/test/testing/file_fixtures_test.rb
index 91b8a9071c..d98987fb8d 100644
--- a/activesupport/test/testing/file_fixtures_test.rb
+++ b/activesupport/test/testing/file_fixtures_test.rb
@@ -1,12 +1,14 @@
require 'abstract_unit'
+require 'pathname'
+
class FileFixturesTest < ActiveSupport::TestCase
self.file_fixture_path = File.expand_path("../../file_fixtures", __FILE__)
test "#file_fixture returns Pathname to file fixture" do
path = file_fixture("sample.txt")
assert_kind_of Pathname, path
- assert_match %r{activesupport/test/file_fixtures/sample.txt$}, path.to_s
+ assert_match %r{.*/test/file_fixtures/sample.txt$}, path.to_s
end
test "raises an exception when the fixture file does not exist" do
@@ -23,6 +25,6 @@ class FileFixturesPathnameDirectoryTest < ActiveSupport::TestCase
test "#file_fixture_path returns Pathname to file fixture" do
path = file_fixture("sample.txt")
assert_kind_of Pathname, path
- assert_match %r{activesupport/test/file_fixtures/sample.txt$}, path.to_s
+ assert_match %r{.*/test/file_fixtures/sample.txt$}, path.to_s
end
end
diff --git a/guides/assets/images/getting_started/template_is_missing_articles_new.png b/guides/assets/images/getting_started/template_is_missing_articles_new.png
index 4e636d09ff..f4f054f3c6 100644
--- a/guides/assets/images/getting_started/template_is_missing_articles_new.png
+++ b/guides/assets/images/getting_started/template_is_missing_articles_new.png
Binary files differ
diff --git a/guides/assets/javascripts/guides.js b/guides/assets/javascripts/guides.js
index a9c7f0d016..e4d25dfb21 100644
--- a/guides/assets/javascripts/guides.js
+++ b/guides/assets/javascripts/guides.js
@@ -51,9 +51,3 @@ var guidesIndex = {
window.location = url;
}
};
-
-// Disable autolink inside example code blocks of guides.
-$(document).ready(function() {
- SyntaxHighlighter.defaults['auto-links'] = false;
- SyntaxHighlighter.all();
-});
diff --git a/guides/assets/javascripts/syntaxhighlighter.js b/guides/assets/javascripts/syntaxhighlighter.js
new file mode 100644
index 0000000000..584aaed716
--- /dev/null
+++ b/guides/assets/javascripts/syntaxhighlighter.js
@@ -0,0 +1,20 @@
+/*!
+ * SyntaxHighlighter
+ * https://github.com/syntaxhighlighter/syntaxhighlighter
+ *
+ * SyntaxHighlighter is donationware. If you are using it, please donate.
+ * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
+ *
+ * @version
+ * 4.0.1 (Sun, 03 Jul 2016 06:45:54 GMT)
+ *
+ * @copyright
+ * Copyright (C) 2004-2016 Alex Gorbatchev.
+ *
+ * @license
+ * Dual licensed under the MIT and GPL licenses.
+ */
+
+
+!function(e){function t(r){if(n[r])return n[r].exports;var i=n[r]={exports:{},id:r,loaded:!1};return e[r].call(i.exports,i,i.exports,t),i.loaded=!0,i.exports}var n={};return t.m=e,t.c=n,t.p="",t(0)}([function(e,t,n){"use strict";function r(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t["default"]=e,t}function i(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var a=n(1);Object.keys(a).forEach(function(e){"default"!==e&&Object.defineProperty(t,e,{enumerable:!0,get:function(){return a[e]}})});var s=n(28),o=i(s),l=i(a),u=n(29),c=r(u);n(30),(0,o["default"])(function(){return l["default"].highlight(c.object(window.syntaxhighlighterConfig||{}))})},function(e,t,n){"use strict";function r(e){window.alert("SyntaxHighlighter\n\n"+e)}function i(e,t){var n=h.vars.discoveredBrushes,i=null;if(null==n){n={};for(var a in h.brushes){var s=h.brushes[a],o=s.aliases;if(null!=o){s.className=s.className||s.aliases[0],s.brushName=s.className||a.toLowerCase();for(var l=0,u=o.length;u>l;l++)n[o[l]]=a}}h.vars.discoveredBrushes=n}return i=h.brushes[n[e]],null==i&&t&&r(h.config.strings.noBrush+e),i}function a(e){var t="<![CDATA[",n="]]>",r=u.trim(e),i=!1,a=t.length,s=n.length;0==r.indexOf(t)&&(r=r.substring(a),i=!0);var o=r.length;return r.indexOf(n)==o-s&&(r=r.substring(0,o-s),i=!0),i?r:e}Object.defineProperty(t,"__esModule",{value:!0});var s=n(2),o=n(5),l=n(9)["default"],u=n(10),c=n(11),f=n(17),g=n(18),p=n(19),d=n(20),h={Match:o.Match,Highlighter:n(22),config:n(18),regexLib:n(3).commonRegExp,vars:{discoveredBrushes:null,highlighters:{}},brushes:{},findElements:function(e,t){var n=t?[t]:u.toArray(document.getElementsByTagName(h.config.tagName)),r=(h.config,[]);if(n=n.concat(f.getSyntaxHighlighterScriptTags()),0===n.length)return r;for(var i=0,a=n.length;a>i;i++){var o={target:n[i],params:s.defaults(s.parse(n[i].className),e)};null!=o.params.brush&&r.push(o)}return r},highlight:function(e,t){var n,r=h.findElements(e,t),u="innerHTML",m=null,x=h.config;if(0!==r.length)for(var v=0,y=r.length;y>v;v++){var m,w,b,t=r[v],E=t.target,S=t.params,C=S.brush;null!=C&&(m=i(C),m&&(S=s.defaults(S||{},p),S=s.defaults(S,g),1==S["html-script"]||1==p["html-script"]?(m=new d(i("xml"),m),C="htmlscript"):m=new m,b=E[u],x.useScriptTags&&(b=a(b)),""!=(E.title||"")&&(S.title=E.title),S.brush=C,b=c(b,S),w=o.applyRegexList(b,m.regexList,S),n=new l(b,w,S),t=f.create("div"),t.innerHTML=n.getHtml(),S.quickCode&&f.attachEvent(f.findElement(t,".code"),"dblclick",f.quickCodeHandler),""!=(E.id||"")&&(t.id=E.id),E.parentNode.replaceChild(t,E)))}}},m=0;t["default"]=h;var x=t.registerBrush=function(e){return h.brushes["brush"+m++]=e["default"]||e};t.clearRegisteredBrushes=function(){h.brushes={},m=0};x(n(23)),x(n(24)),x(n(25)),x(n(26)),x(n(27))},function(e,t,n){"use strict";function r(e){return e.replace(/-(\w+)/g,function(e,t){return t.charAt(0).toUpperCase()+t.substr(1)})}function i(e){var t=s[e];return null==t?e:t}var a=n(3).XRegExp,s={"true":!0,"false":!1};e.exports={defaults:function(e,t){for(var n in t||{})e.hasOwnProperty(n)||(e[n]=e[r(n)]=t[n]);return e},parse:function(e){for(var t,n={},s=a("^\\[(?<values>(.*?))\\]$"),o=0,l=a("(?<name>[\\w-]+)\\s*:\\s*(?<value>[\\w%#-]+|\\[.*?\\]|\".*?\"|'.*?')\\s*;?","g");null!=(t=a.exec(e,l,o));){var u=t.value.replace(/^['"]|['"]$/g,"");if(null!=u&&s.test(u)){var c=a.exec(u,s);u=c.values.length>0?c.values.split(/\s*,\s*/):[]}u=i(u),n[t.name]=n[r(t.name)]=u,o=t.index+t[0].length}return n}}},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0}),t.commonRegExp=t.XRegExp=void 0;var i=n(4),a=r(i);t.XRegExp=a["default"];t.commonRegExp={multiLineCComments:(0,a["default"])("/\\*.*?\\*/","gs"),singleLineCComments:/\/\/.*$/gm,singleLinePerlComments:/#.*$/gm,doubleQuotedString:/"([^\\"\n]|\\.)*"/g,singleQuotedString:/'([^\\'\n]|\\.)*'/g,multiLineDoubleQuotedString:(0,a["default"])('"([^\\\\"]|\\\\.)*"',"gs"),multiLineSingleQuotedString:(0,a["default"])("'([^\\\\']|\\\\.)*'","gs"),xmlComments:(0,a["default"])("(&lt;|<)!--.*?--(&gt;|>)","gs"),url:/\w+:\/\/[\w-.\/?%&=:@;#]*/g,phpScriptTags:{left:/(&lt;|<)\?(?:=|php)?/g,right:/\?(&gt;|>)/g,eof:!0},aspScriptTags:{left:/(&lt;|<)%=?/g,right:/%(&gt;|>)/g},scriptScriptTags:{left:/(&lt;|<)\s*script.*?(&gt;|>)/gi,right:/(&lt;|<)\/\s*script\s*(&gt;|>)/gi}}},function(e,t){"use strict";function n(e,t,n,r,i){var a;if(e[b]={captureNames:t},i)return e;if(e.__proto__)e.__proto__=w.prototype;else for(a in w.prototype)e[a]=w.prototype[a];return e[b].source=n,e[b].flags=r?r.split("").sort().join(""):r,e}function r(e){return S.replace.call(e,/([\s\S])(?=[\s\S]*\1)/g,"")}function i(e,t){if(!w.isRegExp(e))throw new TypeError("Type RegExp expected");var i=e[b]||{},a=s(e),l="",u="",c=null,f=null;return t=t||{},t.removeG&&(u+="g"),t.removeY&&(u+="y"),u&&(a=S.replace.call(a,new RegExp("["+u+"]+","g"),"")),t.addG&&(l+="g"),t.addY&&(l+="y"),l&&(a=r(a+l)),t.isInternalOnly||(void 0!==i.source&&(c=i.source),null!=i.flags&&(f=l?r(i.flags+l):i.flags)),e=n(new RegExp(e.source,a),o(e)?i.captureNames.slice(0):null,c,f,t.isInternalOnly)}function a(e){return parseInt(e,16)}function s(e){return M?e.flags:S.exec.call(/\/([a-z]*)$/i,RegExp.prototype.toString.call(e))[1]}function o(e){return!(!e[b]||!e[b].captureNames)}function l(e){return parseInt(e,10).toString(16)}function u(e,t){var n,r=e.length;for(n=0;r>n;++n)if(e[n]===t)return n;return-1}function c(e,t){return $.call(e)==="[object "+t+"]"}function f(e,t,n){return S.test.call(n.indexOf("x")>-1?/^(?:\s+|#.*|\(\?#[^)]*\))*(?:[?*+]|{\d+(?:,\d*)?})/:/^(?:\(\?#[^)]*\))*(?:[?*+]|{\d+(?:,\d*)?})/,e.slice(t))}function g(e){for(;e.length<4;)e="0"+e;return e}function p(e,t){var n;if(r(t)!==t)throw new SyntaxError("Invalid duplicate regex flag "+t);for(e=S.replace.call(e,/^\(\?([\w$]+)\)/,function(e,n){if(S.test.call(/[gy]/,n))throw new SyntaxError("Cannot use flag g or y in mode modifier "+e);return t=r(t+n),""}),n=0;n<t.length;++n)if(!H[t.charAt(n)])throw new SyntaxError("Unknown regex flag "+t.charAt(n));return{pattern:e,flags:t}}function d(e){var t={};return c(e,"String")?(w.forEach(e,/[^\s,]+/,function(e){t[e]=!0}),t):e}function h(e){if(!/^[\w$]$/.test(e))throw new Error("Flag must be a single character A-Za-z0-9_$");H[e]=!0}function m(e,t,n,r,i){for(var a,s,o=L.length,l=e.charAt(n),u=null;o--;)if(s=L[o],!(s.leadChar&&s.leadChar!==l||s.scope!==r&&"all"!==s.scope||s.flag&&-1===t.indexOf(s.flag))&&(a=w.exec(e,s.regex,n,"sticky"))){u={matchLength:a[0].length,output:s.handler.call(i,a,r,t),reparse:s.reparse};break}return u}function x(e){E.astral=e}function v(e){RegExp.prototype.exec=(e?C:S).exec,RegExp.prototype.test=(e?C:S).test,String.prototype.match=(e?C:S).match,String.prototype.replace=(e?C:S).replace,String.prototype.split=(e?C:S).split,E.natives=e}function y(e){if(null==e)throw new TypeError("Cannot convert null or undefined to object");return e}function w(e,t){var r,a,s,o,l,u={hasNamedCapture:!1,captureNames:[]},c=R,f="",g=0;if(w.isRegExp(e)){if(void 0!==t)throw new TypeError("Cannot supply flags when copying a RegExp");return i(e)}if(e=void 0===e?"":String(e),t=void 0===t?"":String(t),w.isInstalled("astral")&&-1===t.indexOf("A")&&(t+="A"),k[e]||(k[e]={}),!k[e][t]){for(r=p(e,t),o=r.pattern,l=r.flags;g<o.length;){do r=m(o,l,g,c,u),r&&r.reparse&&(o=o.slice(0,g)+r.output+o.slice(g+r.matchLength));while(r&&r.reparse);r?(f+=r.output,g+=r.matchLength||1):(a=w.exec(o,_[c],g,"sticky")[0],f+=a,g+=a.length,"["===a&&c===R?c=T:"]"===a&&c===T&&(c=R))}k[e][t]={pattern:S.replace.call(f,/\(\?:\)(?:[*+?]|\{\d+(?:,\d*)?})?\??(?=\(\?:\))|^\(\?:\)(?:[*+?]|\{\d+(?:,\d*)?})?\??|\(\?:\)(?:[*+?]|\{\d+(?:,\d*)?})?\??$/g,""),flags:S.replace.call(l,/[^gimuy]+/g,""),captures:u.hasNamedCapture?u.captureNames:null}}return s=k[e][t],n(new RegExp(s.pattern,s.flags),s.captures,e,t)}var b="xregexp",E={astral:!1,natives:!1},S={exec:RegExp.prototype.exec,test:RegExp.prototype.test,match:String.prototype.match,replace:String.prototype.replace,split:String.prototype.split},C={},N={},k={},L=[],R="default",T="class",_={"default":/\\(?:0(?:[0-3][0-7]{0,2}|[4-7][0-7]?)?|[1-9]\d*|x[\dA-Fa-f]{2}|u(?:[\dA-Fa-f]{4}|{[\dA-Fa-f]+})|c[A-Za-z]|[\s\S])|\(\?[:=!]|[?*+]\?|{\d+(?:,\d*)?}\??|[\s\S]/,"class":/\\(?:[0-3][0-7]{0,2}|[4-7][0-7]?|x[\dA-Fa-f]{2}|u(?:[\dA-Fa-f]{4}|{[\dA-Fa-f]+})|c[A-Za-z]|[\s\S])|[\s\S]/},O=/\$(?:{([\w$]+)}|(\d\d?|[\s\S]))/g,j=void 0===S.exec.call(/()??/,"")[1],I=function(){var e=!0;try{new RegExp("","u")}catch(t){e=!1}return e}(),A=function(){var e=!0;try{new RegExp("","y")}catch(t){e=!1}return e}(),M=void 0!==/a/.flags,H={g:!0,i:!0,m:!0,u:I,y:A},$={}.toString;w.prototype=new RegExp,w.version="3.1.0-dev",w.addToken=function(e,t,n){n=n||{};var r,a=n.optionalFlags;if(n.flag&&h(n.flag),a)for(a=S.split.call(a,""),r=0;r<a.length;++r)h(a[r]);L.push({regex:i(e,{addG:!0,addY:A,isInternalOnly:!0}),handler:t,scope:n.scope||R,flag:n.flag,reparse:n.reparse,leadChar:n.leadChar}),w.cache.flush("patterns")},w.cache=function(e,t){return N[e]||(N[e]={}),N[e][t]||(N[e][t]=w(e,t))},w.cache.flush=function(e){"patterns"===e?k={}:N={}},w.escape=function(e){return S.replace.call(y(e),/[-[\]{}()*+?.,\\^$|#\s]/g,"\\$&")},w.exec=function(e,t,n,r){var a,s,o="g",l=!1;return l=A&&!!(r||t.sticky&&r!==!1),l&&(o+="y"),t[b]=t[b]||{},s=t[b][o]||(t[b][o]=i(t,{addG:!0,addY:l,removeY:r===!1,isInternalOnly:!0})),s.lastIndex=n=n||0,a=C.exec.call(s,e),r&&a&&a.index!==n&&(a=null),t.global&&(t.lastIndex=a?s.lastIndex:0),a},w.forEach=function(e,t,n){for(var r,i=0,a=-1;r=w.exec(e,t,i);)n(r,++a,e,t),i=r.index+(r[0].length||1)},w.globalize=function(e){return i(e,{addG:!0})},w.install=function(e){e=d(e),!E.astral&&e.astral&&x(!0),!E.natives&&e.natives&&v(!0)},w.isInstalled=function(e){return!!E[e]},w.isRegExp=function(e){return"[object RegExp]"===$.call(e)},w.match=function(e,t,n){var r,a,s=t.global&&"one"!==n||"all"===n,o=(s?"g":"")+(t.sticky?"y":"")||"noGY";return t[b]=t[b]||{},a=t[b][o]||(t[b][o]=i(t,{addG:!!s,addY:!!t.sticky,removeG:"one"===n,isInternalOnly:!0})),r=S.match.call(y(e),a),t.global&&(t.lastIndex="one"===n&&r?r.index+r[0].length:0),s?r||[]:r&&r[0]},w.matchChain=function(e,t){return function n(e,r){var i,a=t[r].regex?t[r]:{regex:t[r]},s=[],o=function(e){if(a.backref){if(!(e.hasOwnProperty(a.backref)||+a.backref<e.length))throw new ReferenceError("Backreference to undefined group: "+a.backref);s.push(e[a.backref]||"")}else s.push(e[0])};for(i=0;i<e.length;++i)w.forEach(e[i],a.regex,o);return r!==t.length-1&&s.length?n(s,r+1):s}([e],0)},w.replace=function(e,t,n,r){var a,s=w.isRegExp(t),o=t.global&&"one"!==r||"all"===r,l=(o?"g":"")+(t.sticky?"y":"")||"noGY",u=t;return s?(t[b]=t[b]||{},u=t[b][l]||(t[b][l]=i(t,{addG:!!o,addY:!!t.sticky,removeG:"one"===r,isInternalOnly:!0}))):o&&(u=new RegExp(w.escape(String(t)),"g")),a=C.replace.call(y(e),u,n),s&&t.global&&(t.lastIndex=0),a},w.replaceEach=function(e,t){var n,r;for(n=0;n<t.length;++n)r=t[n],e=w.replace(e,r[0],r[1],r[2]);return e},w.split=function(e,t,n){return C.split.call(y(e),t,n)},w.test=function(e,t,n,r){return!!w.exec(e,t,n,r)},w.uninstall=function(e){e=d(e),E.astral&&e.astral&&x(!1),E.natives&&e.natives&&v(!1)},w.union=function(e,t){var n,r,i,a,s=/(\()(?!\?)|\\([1-9]\d*)|\\[\s\S]|\[(?:[^\\\]]|\\[\s\S])*]/g,o=[],l=0,u=function(e,t,i){var a=r[l-n];if(t){if(++l,a)return"(?<"+a+">"}else if(i)return"\\"+(+i+n);return e};if(!c(e,"Array")||!e.length)throw new TypeError("Must provide a nonempty array of patterns to merge");for(a=0;a<e.length;++a)i=e[a],w.isRegExp(i)?(n=l,r=i[b]&&i[b].captureNames||[],o.push(S.replace.call(w(i.source).source,s,u))):o.push(w.escape(i));return w(o.join("|"),t)},C.exec=function(e){var t,n,r,a=this.lastIndex,s=S.exec.apply(this,arguments);if(s){if(!j&&s.length>1&&u(s,"")>-1&&(n=i(this,{removeG:!0,isInternalOnly:!0}),S.replace.call(String(e).slice(s.index),n,function(){var e,t=arguments.length;for(e=1;t-2>e;++e)void 0===arguments[e]&&(s[e]=void 0)})),this[b]&&this[b].captureNames)for(r=1;r<s.length;++r)t=this[b].captureNames[r-1],t&&(s[t]=s[r]);this.global&&!s[0].length&&this.lastIndex>s.index&&(this.lastIndex=s.index)}return this.global||(this.lastIndex=a),s},C.test=function(e){return!!C.exec.call(this,e)},C.match=function(e){var t;if(w.isRegExp(e)){if(e.global)return t=S.match.apply(this,arguments),e.lastIndex=0,t}else e=new RegExp(e);return C.exec.call(e,y(this))},C.replace=function(e,t){var n,r,i,a=w.isRegExp(e);return a?(e[b]&&(r=e[b].captureNames),n=e.lastIndex):e+="",i=c(t,"Function")?S.replace.call(String(this),e,function(){var n,i=arguments;if(r)for(i[0]=new String(i[0]),n=0;n<r.length;++n)r[n]&&(i[0][r[n]]=i[n+1]);return a&&e.global&&(e.lastIndex=i[i.length-2]+i[0].length),t.apply(void 0,i)}):S.replace.call(null==this?this:String(this),e,function(){var e=arguments;return S.replace.call(String(t),O,function(t,n,i){var a;if(n){if(a=+n,a<=e.length-3)return e[a]||"";if(a=r?u(r,n):-1,0>a)throw new SyntaxError("Backreference to undefined group "+t);return e[a+1]||""}if("$"===i)return"$";if("&"===i||0===+i)return e[0];if("`"===i)return e[e.length-1].slice(0,e[e.length-2]);if("'"===i)return e[e.length-1].slice(e[e.length-2]+e[0].length);if(i=+i,!isNaN(i)){if(i>e.length-3)throw new SyntaxError("Backreference to undefined group "+t);return e[i]||""}throw new SyntaxError("Invalid token "+t)})}),a&&(e.global?e.lastIndex=0:e.lastIndex=n),i},C.split=function(e,t){if(!w.isRegExp(e))return S.split.apply(this,arguments);var n,r=String(this),i=[],a=e.lastIndex,s=0;return t=(void 0===t?-1:t)>>>0,w.forEach(r,e,function(e){e.index+e[0].length>s&&(i.push(r.slice(s,e.index)),e.length>1&&e.index<r.length&&Array.prototype.push.apply(i,e.slice(1)),n=e[0].length,s=e.index+n)}),s===r.length?(!S.test.call(e,"")||n)&&i.push(""):i.push(r.slice(s)),e.lastIndex=a,i.length>t?i.slice(0,t):i},w.addToken(/\\([ABCE-RTUVXYZaeg-mopqyz]|c(?![A-Za-z])|u(?![\dA-Fa-f]{4}|{[\dA-Fa-f]+})|x(?![\dA-Fa-f]{2}))/,function(e,t){if("B"===e[1]&&t===R)return e[0];throw new SyntaxError("Invalid escape "+e[0])},{scope:"all",leadChar:"\\"}),w.addToken(/\\u{([\dA-Fa-f]+)}/,function(e,t,n){var r=a(e[1]);if(r>1114111)throw new SyntaxError("Invalid Unicode code point "+e[0]);if(65535>=r)return"\\u"+g(l(r));if(I&&n.indexOf("u")>-1)return e[0];throw new SyntaxError("Cannot use Unicode code point above \\u{FFFF} without flag u")},{scope:"all",leadChar:"\\"}),w.addToken(/\[(\^?)]/,function(e){return e[1]?"[\\s\\S]":"\\b\\B"},{leadChar:"["}),w.addToken(/\(\?#[^)]*\)/,function(e,t,n){return f(e.input,e.index+e[0].length,n)?"":"(?:)"},{leadChar:"("}),w.addToken(/\s+|#.*/,function(e,t,n){return f(e.input,e.index+e[0].length,n)?"":"(?:)"},{flag:"x"}),w.addToken(/\./,function(){return"[\\s\\S]"},{flag:"s",leadChar:"."}),w.addToken(/\\k<([\w$]+)>/,function(e){var t=isNaN(e[1])?u(this.captureNames,e[1])+1:+e[1],n=e.index+e[0].length;if(!t||t>this.captureNames.length)throw new SyntaxError("Backreference to undefined group "+e[0]);return"\\"+t+(n===e.input.length||isNaN(e.input.charAt(n))?"":"(?:)")},{leadChar:"\\"}),w.addToken(/\\(\d+)/,function(e,t){if(!(t===R&&/^[1-9]/.test(e[1])&&+e[1]<=this.captureNames.length)&&"0"!==e[1])throw new SyntaxError("Cannot use octal escape or backreference to undefined group "+e[0]);return e[0]},{scope:"all",leadChar:"\\"}),w.addToken(/\(\?P?<([\w$]+)>/,function(e){if(!isNaN(e[1]))throw new SyntaxError("Cannot use integer as capture name "+e[0]);if("length"===e[1]||"__proto__"===e[1])throw new SyntaxError("Cannot use reserved word as capture name "+e[0]);if(u(this.captureNames,e[1])>-1)throw new SyntaxError("Cannot use same name for multiple groups "+e[0]);return this.captureNames.push(e[1]),this.hasNamedCapture=!0,"("},{leadChar:"("}),w.addToken(/\((?!\?)/,function(e,t,n){return n.indexOf("n")>-1?"(?:":(this.captureNames.push(null),"(")},{optionalFlags:"n",leadChar:"("}),e.exports=w},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(6);Object.keys(r).forEach(function(e){"default"!==e&&Object.defineProperty(t,e,{enumerable:!0,get:function(){return r[e]}})});var i=n(7);Object.keys(i).forEach(function(e){"default"!==e&&Object.defineProperty(t,e,{enumerable:!0,get:function(){return i[e]}})})},function(e,t){"use strict";function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}();t.Match=function(){function e(t,r,i){n(this,e),this.value=t,this.index=r,this.length=t.length,this.css=i,this.brushName=null}return r(e,[{key:"toString",value:function(){return this.value}}]),e}()},function(e,t,n){"use strict";function r(e,t){var n=[];t=t||[];for(var r=0,s=t.length;s>r;r++)"object"===i(t[r])&&(n=n.concat((0,a.find)(e,t[r])));return n=(0,a.sort)(n),n=(0,a.removeNested)(n),n=(0,a.compact)(n)}Object.defineProperty(t,"__esModule",{value:!0});var i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol?"symbol":typeof e};t.applyRegexList=r;var a=n(8)},function(e,t,n){"use strict";function r(e,t){function n(e,t){return e[0]}for(var r=null,i=[],a=t.func?t.func:n,s=0;r=l.XRegExp.exec(e,t.regex,s);){var u=a(r,t);"string"==typeof u&&(u=[new o.Match(u,r.index,t.css)]),i=i.concat(u),s=r.index+r[0].length}return i}function i(e){function t(e,t){return e.index<t.index?-1:e.index>t.index?1:e.length<t.length?-1:e.length>t.length?1:0}return e.sort(t)}function a(e){var t,n,r=[];for(t=0,n=e.length;n>t;t++)e[t]&&r.push(e[t]);return r}function s(e){for(var t=0,n=e.length;n>t;t++)if(null!==e[t])for(var r=e[t],i=r.index+r.length,a=t+1,n=e.length;n>a&&null!==e[t];a++){var s=e[a];if(null!==s){if(s.index>i)break;s.index==r.index&&s.length>r.length?e[t]=null:s.index>=r.index&&s.index<i&&(e[a]=null)}}return e}Object.defineProperty(t,"__esModule",{value:!0}),t.find=r,t.sort=i,t.compact=a,t.removeNested=s;var o=n(6),l=n(3)},function(e,t){"use strict";function n(e,t){for(var n=e.toString();n.length<t;)n="0"+n;return n}function r(e){return e.split(/\r?\n/)}function i(e){var t,n,r,i={};for(t=e.highlight||[],"function"!=typeof t.push&&(t=[t]),r=0,n=t.length;n>r;r++)i[t[r]]=!0;return i}function a(e,t,n){var a=this;a.opts=n,a.code=e,a.matches=t,a.lines=r(e),a.linesToHighlight=i(n)}Object.defineProperty(t,"__esModule",{value:!0}),t["default"]=a,a.prototype={wrapLinesWithCode:function(e,t){if(null==e||0==e.length||"\n"==e||null==t)return e;var n,i,a,s,o,l=this,u=[];for(e=e.replace(/</g,"&lt;"),e=e.replace(/ {2,}/g,function(e){for(a="",s=0,o=e.length;o-1>s;s++)a+=l.opts.space;return a+" "}),n=r(e),s=0,o=n.length;o>s;s++)i=n[s],a="",i.length>0&&(i=i.replace(/^(&nbsp;| )+/,function(e){return a=e,""}),i=0===i.length?a:a+'<code class="'+t+'">'+i+"</code>"),u.push(i);return u.join("\n")},processUrls:function(e){var t=/(.*)((&gt;|&lt;).*)/,n=/\w+:\/\/[\w-.\/?%&=:@;#]*/g;return e.replace(n,function(e){var n="",r=null;return(r=t.exec(e))&&(e=r[1],n=r[2]),'<a href="'+e+'">'+e+"</a>"+n})},figureOutLineNumbers:function(e){var t,n,r=[],i=this.lines,a=parseInt(this.opts.firstLine||1);for(t=0,n=i.length;n>t;t++)r.push(t+a);return r},wrapLine:function(e,t,n){var r=["line","number"+t,"index"+e,"alt"+(t%2==0?1:2).toString()];return this.linesToHighlight[t]&&r.push("highlighted"),0==t&&r.push("break"),'<div class="'+r.join(" ")+'">'+n+"</div>"},renderLineNumbers:function(e,t){var r,i,a=this,s=a.opts,o="",l=a.lines.length,u=parseInt(s.firstLine||1),c=s.padLineNumbers;for(1==c?c=(u+l-1).toString().length:1==isNaN(c)&&(c=0),i=0;l>i;i++)r=t?t[i]:u+i,e=0==r?s.space:n(r,c),o+=a.wrapLine(i,r,e);return o},getCodeLinesHtml:function(e,t){for(var n=this,i=n.opts,a=r(e),s=(i.padLineNumbers,parseInt(i.firstLine||1)),o=i.brush,e="",l=0,u=a.length;u>l;l++){var c=a[l],f=/^(&nbsp;|\s)+/.exec(c),g=null,p=t?t[l]:s+l;null!=f&&(g=f[0].toString(),c=c.substr(g.length),g=g.replace(" ",i.space)),0==c.length&&(c=i.space),e+=n.wrapLine(l,p,(null!=g?'<code class="'+o+' spaces">'+g+"</code>":"")+c)}return e},getTitleHtml:function(e){return e?"<caption>"+e+"</caption>":""},getMatchesHtml:function(e,t){function n(e){var t=e?e.brushName||c:c;return t?t+" ":""}var r,i,a,s,o=this,l=0,u="",c=o.opts.brush||"";for(a=0,s=t.length;s>a;a++)r=t[a],null!==r&&0!==r.length&&(i=n(r),u+=o.wrapLinesWithCode(e.substr(l,r.index-l),i+"plain")+o.wrapLinesWithCode(r.value,i+r.css),l=r.index+r.length+(r.offset||0));return u+=o.wrapLinesWithCode(e.substr(l),n()+"plain")},getHtml:function(){var e,t,n,r=this,i=r.opts,a=r.code,s=r.matches,o=["syntaxhighlighter"];return i.collapse===!0&&o.push("collapsed"),t=i.gutter!==!1,t||o.push("nogutter"),o.push(i.className),o.push(i.brush),t&&(e=r.figureOutLineNumbers(a)),n=r.getMatchesHtml(a,s),n=r.getCodeLinesHtml(n,e),i.autoLinks&&(n=r.processUrls(n)),n='\n <div class="'+o.join(" ")+'">\n <table border="0" cellpadding="0" cellspacing="0">\n '+r.getTitleHtml(i.title)+"\n <tbody>\n <tr>\n "+(t?'<td class="gutter">'+r.renderLineNumbers(a)+"</td>":"")+'\n <td class="code">\n <div class="container">'+n+"</div>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n "}}},function(e,t){"use strict";function n(e){return e.split(/\r?\n/)}function r(e,t){for(var r=n(e),i=0,a=r.length;a>i;i++)r[i]=t(r[i],i);return r.join("\n")}function i(e){return(e||"")+Math.round(1e6*Math.random()).toString()}function a(e,t){var n,r={};for(n in e)r[n]=e[n];for(n in t)r[n]=t[n];return r}function s(e){return e.replace(/^\s+|\s+$/g,"")}function o(e){return Array.prototype.slice.apply(e)}function l(e){var t={"true":!0,"false":!1}[e];return null==t?e:t}e.exports={splitLines:n,eachLine:r,guid:i,merge:a,trim:s,toArray:o,toBoolean:l}},function(e,t,n){"use strict";var r=n(12),i=n(13),a=n(14),s=n(15),o=n(16);e.exports=function(e,t){e=r(e,t),e=i(e,t),e=a(e,t),e=s.unindent(e,t);var n=t["tab-size"];return e=t["smart-tabs"]===!0?o.smart(e,n):o.regular(e,n)}},function(e,t){"use strict";e.exports=function(e,t){return e.replace(/^[ ]*[\n]+|[\n]*[ ]*$/g,"").replace(/\r/g," ")}},function(e,t){"use strict";e.exports=function(e,t){var n=/<br\s*\/?>|&lt;br\s*\/?&gt;/gi;return t.bloggerMode===!0&&(e=e.replace(n,"\n")),e}},function(e,t){"use strict";e.exports=function(e,t){var n=/<br\s*\/?>|&lt;br\s*\/?&gt;/gi;return t.stripBrs===!0&&(e=e.replace(n,"")),e}},function(e,t){"use strict";function n(e){return/^\s*$/.test(e)}e.exports={unindent:function(e){var t,r,i,a,s=e.split(/\r?\n/),o=/^\s*/,l=1e3;for(i=0,a=s.length;a>i&&l>0;i++)if(t=s[i],!n(t)){if(r=o.exec(t),null==r)return e;l=Math.min(r[0].length,l)}if(l>0)for(i=0,a=s.length;a>i;i++)n(s[i])||(s[i]=s[i].substr(l));return s.join("\n")}}},function(e,t){"use strict";function n(e,t,n){return e.substr(0,t)+r.substr(0,n)+e.substr(t+1,e.length)}for(var r="",i=0;50>i;i++)r+=" ";e.exports={smart:function(e,t){var r,i,a,s,o=e.split(/\r?\n/),l=" ";for(a=0,s=o.length;s>a;a++)if(r=o[a],-1!==r.indexOf(l)){for(i=0;-1!==(i=r.indexOf(l));)r=n(r,i,t-i%t);o[a]=r}return o.join("\n")},regular:function(e,t){return e.replace(/\t/g,r.substr(0,t))}}},function(e,t){"use strict";function n(){for(var e=document.getElementsByTagName("script"),t=[],n=0;n<e.length;n++)("text/syntaxhighlighter"==e[n].type||"syntaxhighlighter"==e[n].type)&&t.push(e[n]);return t}function r(e,t){return-1!=e.className.indexOf(t)}function i(e,t){r(e,t)||(e.className+=" "+t)}function a(e,t){e.className=e.className.replace(t,"")}function s(e,t,n,r){function i(e){e=e||window.event,e.target||(e.target=e.srcElement,e.preventDefault=function(){this.returnValue=!1}),n.call(r||window,e)}e.attachEvent?e.attachEvent("on"+t,i):e.addEventListener(t,i,!1)}function o(e,t,n){if(null==e)return null;var r,i,a=1!=n?e.childNodes:[e.parentNode],s={"#":"id",".":"className"}[t.substr(0,1)]||"nodeName";if(r="nodeName"!=s?t.substr(1):t.toUpperCase(),-1!=(e[s]||"").indexOf(r))return e;for(var l=0,u=a.length;a&&u>l&&null==i;l++)i=o(a[l],t,n);return i}function l(e,t){return o(e,t,!0)}function u(e,t,n,r,i){var a=(screen.width-n)/2,s=(screen.height-r)/2;i+=", left="+a+", top="+s+", width="+n+", height="+r,i=i.replace(/^,/,"");var o=window.open(e,t,i);return o.focus(),o}function c(e){return document.getElementsByTagName(e)}function f(e){var t,n,r=c(e.tagName);if(e.useScriptTags)for(t=c("script"),n=0;n<t.length;n++)t[n].type.match(/^(text\/)?syntaxhighlighter$/)&&r.push(t[n]);return r}function g(e){return document.createElement(e)}function p(e){var t=e.target,n=l(t,".syntaxhighlighter"),r=l(t,".container"),u=document.createElement("textarea");if(r&&n&&!o(r,"textarea")){i(n,"source");for(var c=r.childNodes,f=[],g=0,p=c.length;p>g;g++)f.push(c[g].innerText||c[g].textContent);f=f.join("\r"),f=f.replace(/\u00a0/g," "),u.readOnly=!0,u.appendChild(document.createTextNode(f)),r.appendChild(u),u.focus(),u.select(),s(u,"blur",function(e){u.parentNode.removeChild(u),a(n,"source")})}}e.exports={quickCodeHandler:p,create:g,popup:u,hasClass:r,addClass:i,removeClass:a,attachEvent:s,findElement:o,findParentElement:l,getSyntaxHighlighterScriptTags:n,findElementsToHighlight:f}},function(e,t){"use strict";e.exports={space:"&nbsp;",useScriptTags:!0,bloggerMode:!1,stripBrs:!1,tagName:"pre"}},function(e,t){"use strict";e.exports={"class-name":"","first-line":1,"pad-line-numbers":!1,highlight:null,title:null,"smart-tabs":!0,"tab-size":4,gutter:!0,"quick-code":!0,collapse:!1,"auto-links":!0,unindent:!0,"html-script":!1}},function(e,t,n){(function(t){"use strict";function r(e,t){function n(e,t){for(var n=0,r=e.length;r>n;n++)e[n].index+=t}function r(e,r){function s(e){u=u.concat(e)}var o,l=e.code,u=[],c=a.regexList,f=e.index+e.left.length,g=a.htmlScript;o=i(l,c),n(o,f),s(o),null!=g.left&&null!=e.left&&(o=i(e.left,[g.left]),n(o,e.index),s(o)),null!=g.right&&null!=e.right&&(o=i(e.right,[g.right]),n(o,e.index+e[0].lastIndexOf(e.right)),s(o));for(var p=0,d=u.length;d>p;p++)u[p].brushName=t.brushName;return u}var a,s=new e;if(null!=t){if(a=new t,null==a.htmlScript)throw new Error("Brush wasn't configured for html-script option: "+t.brushName);s.regexList.push({regex:a.htmlScript.code,func:r}),this.regexList=s.regexList}}var i=n(5).applyRegexList;e.exports=r}).call(t,n(21))},function(e,t){"use strict";function n(){f&&u&&(f=!1,u.length?c=u.concat(c):g=-1,c.length&&r())}function r(){if(!f){var e=s(n);f=!0;for(var t=c.length;t;){for(u=c,c=[];++g<t;)u&&u[g].run();g=-1,t=c.length}u=null,f=!1,o(e)}}function i(e,t){this.fun=e,this.array=t}function a(){}var s,o,l=e.exports={};!function(){try{s=setTimeout}catch(e){s=function(){throw new Error("setTimeout is not defined")}}try{o=clearTimeout}catch(e){o=function(){throw new Error("clearTimeout is not defined")}}}();var u,c=[],f=!1,g=-1;l.nextTick=function(e){var t=new Array(arguments.length-1);if(arguments.length>1)for(var n=1;n<arguments.length;n++)t[n-1]=arguments[n];c.push(new i(e,t)),1!==c.length||f||s(r,0)},i.prototype.run=function(){this.fun.apply(null,this.array)},l.title="browser",l.browser=!0,l.env={},l.argv=[],l.version="",l.versions={},l.on=a,l.addListener=a,l.once=a,l.off=a,l.removeListener=a,l.removeAllListeners=a,l.emit=a,l.binding=function(e){throw new Error("process.binding is not supported")},l.cwd=function(){return"/"},l.chdir=function(e){throw new Error("process.chdir is not supported")},l.umask=function(){return 0}},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}var a=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),s=n(9),o=r(s),l=n(3),u=n(5);e.exports=function(){function e(){i(this,e)}return a(e,[{key:"getKeywords",value:function(e){var t=e.replace(/^\s+|\s+$/g,"").replace(/\s+/g,"|");return"\\b(?:"+t+")\\b"}},{key:"forHtmlScript",value:function(e){var t={end:e.right.source};e.eof&&(t.end="(?:(?:"+t.end+")|$)"),this.htmlScript={left:{regex:e.left,css:"script"},right:{regex:e.right,css:"script"},code:(0,l.XRegExp)("(?<left>"+e.left.source+")(?<code>.*?)(?<right>"+t.end+")","sgi")}}},{key:"getHtml",value:function(e){var t=arguments.length<=1||void 0===arguments[1]?{}:arguments[1],n=(0,u.applyRegexList)(e,this.regexList),r=new o["default"](e,n,t);return r.getHtml()}}]),e}()},function(e,t,n){"use strict";function r(){var e="break case catch class continue default delete do else enum export extends false for from as function if implements import in instanceof interface let new null package private protected static return super switch this throw true try typeof var while with yield";this.regexList=[{regex:a.multiLineDoubleQuotedString,css:"string"},{regex:a.multiLineSingleQuotedString,css:"string"},{regex:a.singleLineCComments,css:"comments"},{regex:a.multiLineCComments,css:"comments"},{regex:/\s*#.*/gm,css:"preprocessor"},{regex:new RegExp(this.getKeywords(e),"gm"),css:"keyword"}],this.forHtmlScript(a.scriptScriptTags)}var i=n(22),a=n(3).commonRegExp;r.prototype=new i,r.aliases=["js","jscript","javascript","json"],e.exports=r},function(e,t,n){"use strict";function r(){var e="alias and BEGIN begin break case class def define_method defined do each else elsif END end ensure false for if in module new next nil not or raise redo rescue retry return self super then throw true undef unless until when while yield",t="Array Bignum Binding Class Continuation Dir Exception FalseClass File::Stat File Fixnum Fload Hash Integer IO MatchData Method Module NilClass Numeric Object Proc Range Regexp String Struct::TMS Symbol ThreadGroup Thread Time TrueClass";this.regexList=[{regex:a.singleLinePerlComments,css:"comments"},{regex:a.doubleQuotedString,css:"string"},{regex:a.singleQuotedString,css:"string"},{regex:/\b[A-Z0-9_]+\b/g,css:"constants"},{regex:/:[a-z][A-Za-z0-9_]*/g,css:"color2"},{regex:/(\$|@@|@)\w+/g,css:"variable bold"},{regex:new RegExp(this.getKeywords(e),"gm"),css:"keyword"},{regex:new RegExp(this.getKeywords(t),"gm"),css:"color1"}],this.forHtmlScript(a.aspScriptTags)}var i=n(22),a=n(3).commonRegExp;r.prototype=new i,r.aliases=["ruby","rails","ror","rb"],e.exports=r},function(e,t,n){"use strict";function r(){function e(e,t){var n=e[0],r=s.exec(n,s("(&lt;|<)[\\s\\/\\?!]*(?<name>[:\\w-\\.]+)","xg")),i=[];if(null!=e.attributes)for(var a,l=0,u=s("(?<name> [\\w:.-]+)\\s*=\\s*(?<value> \".*?\"|'.*?'|\\w+)","xg");null!=(a=s.exec(n,u,l));)i.push(new o(a.name,e.index+a.index,"color1")),i.push(new o(a.value,e.index+a.index+a[0].indexOf(a.value),"string")),l=a.index+a[0].length;return null!=r&&i.push(new o(r.name,e.index+r[0].indexOf(r.name),"keyword")),i}this.regexList=[{regex:s("(\\&lt;|<)\\!\\[[\\w\\s]*?\\[(.|\\s)*?\\]\\](\\&gt;|>)","gm"),css:"color2"},{regex:a.xmlComments,css:"comments"},{regex:s("(&lt;|<)[\\s\\/\\?!]*(\\w+)(?<attributes>.*?)[\\s\\/\\?]*(&gt;|>)","sg"),func:e}]}var i=n(22),a=n(3).commonRegExp,s=n(3).XRegExp,o=n(5).Match;r.prototype=new i,r.aliases=["xml","xhtml","xslt","html","plist"],e.exports=r},function(e,t,n){"use strict";function r(){var e="abs avg case cast coalesce convert count current_timestamp current_user day isnull left lower month nullif replace right session_user space substring sum system_user upper user year",t="absolute action add after alter as asc at authorization begin bigint binary bit by cascade char character check checkpoint close collate column commit committed connect connection constraint contains continue create cube current current_date current_time cursor database date deallocate dec decimal declare default delete desc distinct double drop dynamic else end end-exec escape except exec execute false fetch first float for force foreign forward free from full function global goto grant group grouping having hour ignore index inner insensitive insert instead int integer intersect into is isolation key last level load local max min minute modify move name national nchar next no numeric of off on only open option order out output partial password precision prepare primary prior privileges procedure public read real references relative repeatable restrict return returns revoke rollback rollup rows rule schema scroll second section select sequence serializable set size smallint static statistics table temp temporary then time timestamp to top transaction translation trigger true truncate uncommitted union unique update values varchar varying view when where with work",n="all and any between cross in join like not null or outer some";
+ this.regexList=[{regex:/--(.*)$/gm,css:"comments"},{regex:/\/\*([^\*][\s\S]*?)?\*\//gm,css:"comments"},{regex:a.multiLineDoubleQuotedString,css:"string"},{regex:a.multiLineSingleQuotedString,css:"string"},{regex:new RegExp(this.getKeywords(e),"gmi"),css:"color2"},{regex:new RegExp(this.getKeywords(n),"gmi"),css:"color1"},{regex:new RegExp(this.getKeywords(t),"gmi"),css:"keyword"}]}var i=n(22),a=n(3).commonRegExp;r.prototype=new i,r.aliases=["sql"],e.exports=r},function(e,t,n){"use strict";function r(){this.regexList=[]}var i=n(22);n(3).commonRegExp;r.prototype=new i,r.aliases=["text","plain"],e.exports=r},function(e,t,n){"use strict";"function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol?"symbol":typeof e};!function(t,n){e.exports=n()}("domready",function(){var e,t=[],n=document,r=n.documentElement.doScroll,i="DOMContentLoaded",a=(r?/^loaded|^c/:/^loaded|^i|^c/).test(n.readyState);return a||n.addEventListener(i,e=function(){for(n.removeEventListener(i,e),a=1;e=t.shift();)e()}),function(e){a?setTimeout(e,0):t.push(e)}})},function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var n=t.string=function(e){return e.replace(/^([A-Z])/g,function(e,t){return t.toLowerCase()}).replace(/([A-Z])/g,function(e,t){return"-"+t.toLowerCase()})};t.object=function(e){var t={};return Object.keys(e).forEach(function(r){return t[n(r)]=e[r]}),t}},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}var i=n(1),a=r(i);window.SyntaxHighlighter=a["default"],"undefined"==typeof window.XRegExp&&(window.XRegExp=n(3).XRegExp)}]);
diff --git a/guides/assets/javascripts/syntaxhighlighter/shBrushAS3.js b/guides/assets/javascripts/syntaxhighlighter/shBrushAS3.js
deleted file mode 100644
index 8aa3ed2732..0000000000
--- a/guides/assets/javascripts/syntaxhighlighter/shBrushAS3.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- *
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-;(function()
-{
- // CommonJS
- typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null;
-
- function Brush()
- {
- // Created by Peter Atoria @ http://iAtoria.com
-
- var inits = 'class interface function package';
-
- var keywords = '-Infinity ...rest Array as AS3 Boolean break case catch const continue Date decodeURI ' +
- 'decodeURIComponent default delete do dynamic each else encodeURI encodeURIComponent escape ' +
- 'extends false final finally flash_proxy for get if implements import in include Infinity ' +
- 'instanceof int internal is isFinite isNaN isXMLName label namespace NaN native new null ' +
- 'Null Number Object object_proxy override parseFloat parseInt private protected public ' +
- 'return set static String super switch this throw true try typeof uint undefined unescape ' +
- 'use void while with'
- ;
-
- this.regexList = [
- { regex: SyntaxHighlighter.regexLib.singleLineCComments, css: 'comments' }, // one line comments
- { regex: SyntaxHighlighter.regexLib.multiLineCComments, css: 'comments' }, // multiline comments
- { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, // double quoted strings
- { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // single quoted strings
- { regex: /\b([\d]+(\.[\d]+)?|0x[a-f0-9]+)\b/gi, css: 'value' }, // numbers
- { regex: new RegExp(this.getKeywords(inits), 'gm'), css: 'color3' }, // initializations
- { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' }, // keywords
- { regex: new RegExp('var', 'gm'), css: 'variable' }, // variable
- { regex: new RegExp('trace', 'gm'), css: 'color1' } // trace
- ];
-
- this.forHtmlScript(SyntaxHighlighter.regexLib.scriptScriptTags);
- };
-
- Brush.prototype = new SyntaxHighlighter.Highlighter();
- Brush.aliases = ['actionscript3', 'as3'];
-
- SyntaxHighlighter.brushes.AS3 = Brush;
-
- // CommonJS
- typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
-})();
diff --git a/guides/assets/javascripts/syntaxhighlighter/shBrushAppleScript.js b/guides/assets/javascripts/syntaxhighlighter/shBrushAppleScript.js
deleted file mode 100644
index d40bbd7dd2..0000000000
--- a/guides/assets/javascripts/syntaxhighlighter/shBrushAppleScript.js
+++ /dev/null
@@ -1,75 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- *
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-;(function()
-{
- // CommonJS
- typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null;
-
- function Brush()
- {
- // AppleScript brush by David Chambers
- // http://davidchambersdesign.com/
- var keywords = 'after before beginning continue copy each end every from return get global in local named of set some that the then times to where whose with without';
- var ordinals = 'first second third fourth fifth sixth seventh eighth ninth tenth last front back middle';
- var specials = 'activate add alias AppleScript ask attachment boolean class constant delete duplicate empty exists false id integer list make message modal modified new no paragraph pi properties quit real record remove rest result reveal reverse run running save string true word yes';
-
- this.regexList = [
-
- { regex: /(--|#).*$/gm,
- css: 'comments' },
-
- { regex: /\(\*(?:[\s\S]*?\(\*[\s\S]*?\*\))*[\s\S]*?\*\)/gm, // support nested comments
- css: 'comments' },
-
- { regex: /"[\s\S]*?"/gm,
- css: 'string' },
-
- { regex: /(?:,|:|¬|'s\b|\(|\)|\{|\}|«|\b\w*»)/g,
- css: 'color1' },
-
- { regex: /(-)?(\d)+(\.(\d)?)?(E\+(\d)+)?/g, // numbers
- css: 'color1' },
-
- { regex: /(?:&(amp;|gt;|lt;)?|=|� |>|<|≥|>=|≤|<=|\*|\+|-|\/|÷|\^)/g,
- css: 'color2' },
-
- { regex: /\b(?:and|as|div|mod|not|or|return(?!\s&)(ing)?|equals|(is(n't| not)? )?equal( to)?|does(n't| not) equal|(is(n't| not)? )?(greater|less) than( or equal( to)?)?|(comes|does(n't| not) come) (after|before)|is(n't| not)?( in)? (back|front) of|is(n't| not)? behind|is(n't| not)?( (in|contained by))?|does(n't| not) contain|contain(s)?|(start|begin|end)(s)? with|((but|end) )?(consider|ignor)ing|prop(erty)?|(a )?ref(erence)?( to)?|repeat (until|while|with)|((end|exit) )?repeat|((else|end) )?if|else|(end )?(script|tell|try)|(on )?error|(put )?into|(of )?(it|me)|its|my|with (timeout( of)?|transaction)|end (timeout|transaction))\b/g,
- css: 'keyword' },
-
- { regex: /\b\d+(st|nd|rd|th)\b/g, // ordinals
- css: 'keyword' },
-
- { regex: /\b(?:about|above|against|around|at|below|beneath|beside|between|by|(apart|aside) from|(instead|out) of|into|on(to)?|over|since|thr(ough|u)|under)\b/g,
- css: 'color3' },
-
- { regex: /\b(?:adding folder items to|after receiving|choose( ((remote )?application|color|folder|from list|URL))?|clipboard info|set the clipboard to|(the )?clipboard|entire contents|display(ing| (alert|dialog|mode))?|document( (edited|file|nib name))?|file( (name|type))?|(info )?for|giving up after|(name )?extension|quoted form|return(ed)?|second(?! item)(s)?|list (disks|folder)|text item(s| delimiters)?|(Unicode )?text|(disk )?item(s)?|((current|list) )?view|((container|key) )?window|with (data|icon( (caution|note|stop))?|parameter(s)?|prompt|properties|seed|title)|case|diacriticals|hyphens|numeric strings|punctuation|white space|folder creation|application(s( folder)?| (processes|scripts position|support))?|((desktop )?(pictures )?|(documents|downloads|favorites|home|keychain|library|movies|music|public|scripts|sites|system|users|utilities|workflows) )folder|desktop|Folder Action scripts|font(s| panel)?|help|internet plugins|modem scripts|(system )?preferences|printer descriptions|scripting (additions|components)|shared (documents|libraries)|startup (disk|items)|temporary items|trash|on server|in AppleTalk zone|((as|long|short) )?user name|user (ID|locale)|(with )?password|in (bundle( with identifier)?|directory)|(close|open for) access|read|write( permission)?|(g|s)et eof|using( delimiters)?|starting at|default (answer|button|color|country code|entr(y|ies)|identifiers|items|name|location|script editor)|hidden( answer)?|open(ed| (location|untitled))?|error (handling|reporting)|(do( shell)?|load|run|store) script|administrator privileges|altering line endings|get volume settings|(alert|boot|input|mount|output|set) volume|output muted|(fax|random )?number|round(ing)?|up|down|toward zero|to nearest|as taught in school|system (attribute|info)|((AppleScript( Studio)?|system) )?version|(home )?directory|(IPv4|primary Ethernet) address|CPU (type|speed)|physical memory|time (stamp|to GMT)|replacing|ASCII (character|number)|localized string|from table|offset|summarize|beep|delay|say|(empty|multiple) selections allowed|(of|preferred) type|invisibles|showing( package contents)?|editable URL|(File|FTP|News|Media|Web) [Ss]ervers|Telnet hosts|Directory services|Remote applications|waiting until completion|saving( (in|to))?|path (for|to( (((current|frontmost) )?application|resource))?)|POSIX (file|path)|(background|RGB) color|(OK|cancel) button name|cancel button|button(s)?|cubic ((centi)?met(re|er)s|yards|feet|inches)|square ((kilo)?met(re|er)s|miles|yards|feet)|(centi|kilo)?met(re|er)s|miles|yards|feet|inches|lit(re|er)s|gallons|quarts|(kilo)?grams|ounces|pounds|degrees (Celsius|Fahrenheit|Kelvin)|print( (dialog|settings))?|clos(e(able)?|ing)|(de)?miniaturized|miniaturizable|zoom(ed|able)|attribute run|action (method|property|title)|phone|email|((start|end)ing|home) page|((birth|creation|current|custom|modification) )?date|((((phonetic )?(first|last|middle))|computer|host|maiden|related) |nick)?name|aim|icq|jabber|msn|yahoo|address(es)?|save addressbook|should enable action|city|country( code)?|formatte(r|d address)|(palette )?label|state|street|zip|AIM [Hh]andle(s)?|my card|select(ion| all)?|unsaved|(alpha )?value|entr(y|ies)|group|(ICQ|Jabber|MSN) handle|person|people|company|department|icon image|job title|note|organization|suffix|vcard|url|copies|collating|pages (across|down)|request print time|target( printer)?|((GUI Scripting|Script menu) )?enabled|show Computer scripts|(de)?activated|awake from nib|became (key|main)|call method|of (class|object)|center|clicked toolbar item|closed|for document|exposed|(can )?hide|idle|keyboard (down|up)|event( (number|type))?|launch(ed)?|load (image|movie|nib|sound)|owner|log|mouse (down|dragged|entered|exited|moved|up)|move|column|localization|resource|script|register|drag (info|types)|resigned (active|key|main)|resiz(e(d)?|able)|right mouse (down|dragged|up)|scroll wheel|(at )?index|should (close|open( untitled)?|quit( after last window closed)?|zoom)|((proposed|screen) )?bounds|show(n)?|behind|in front of|size (mode|to fit)|update(d| toolbar item)?|was (hidden|miniaturized)|will (become active|close|finish launching|hide|miniaturize|move|open|quit|(resign )?active|((maximum|minimum|proposed) )?size|show|zoom)|bundle|data source|movie|pasteboard|sound|tool(bar| tip)|(color|open|save) panel|coordinate system|frontmost|main( (bundle|menu|window))?|((services|(excluded from )?windows) )?menu|((executable|frameworks|resource|scripts|shared (frameworks|support)) )?path|(selected item )?identifier|data|content(s| view)?|character(s)?|click count|(command|control|option|shift) key down|context|delta (x|y|z)|key( code)?|location|pressure|unmodified characters|types|(first )?responder|playing|(allowed|selectable) identifiers|allows customization|(auto saves )?configuration|visible|image( name)?|menu form representation|tag|user(-| )defaults|associated file name|(auto|needs) display|current field editor|floating|has (resize indicator|shadow)|hides when deactivated|level|minimized (image|title)|opaque|position|release when closed|sheet|title(d)?)\b/g,
- css: 'color3' },
-
- { regex: new RegExp(this.getKeywords(specials), 'gm'), css: 'color3' },
- { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' },
- { regex: new RegExp(this.getKeywords(ordinals), 'gm'), css: 'keyword' }
- ];
- };
-
- Brush.prototype = new SyntaxHighlighter.Highlighter();
- Brush.aliases = ['applescript'];
-
- SyntaxHighlighter.brushes.AppleScript = Brush;
-
- // CommonJS
- typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
-})();
diff --git a/guides/assets/javascripts/syntaxhighlighter/shBrushBash.js b/guides/assets/javascripts/syntaxhighlighter/shBrushBash.js
deleted file mode 100644
index 8c296969ff..0000000000
--- a/guides/assets/javascripts/syntaxhighlighter/shBrushBash.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- *
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-;(function()
-{
- // CommonJS
- typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null;
-
- function Brush()
- {
- var keywords = 'if fi then elif else for do done until while break continue case function return in eq ne ge le';
- var commands = 'alias apropos awk basename bash bc bg builtin bzip2 cal cat cd cfdisk chgrp chmod chown chroot' +
- 'cksum clear cmp comm command cp cron crontab csplit cut date dc dd ddrescue declare df ' +
- 'diff diff3 dig dir dircolors dirname dirs du echo egrep eject enable env ethtool eval ' +
- 'exec exit expand export expr false fdformat fdisk fg fgrep file find fmt fold format ' +
- 'free fsck ftp gawk getopts grep groups gzip hash head history hostname id ifconfig ' +
- 'import install join kill less let ln local locate logname logout look lpc lpr lprint ' +
- 'lprintd lprintq lprm ls lsof make man mkdir mkfifo mkisofs mknod more mount mtools ' +
- 'mv netstat nice nl nohup nslookup open op passwd paste pathchk ping popd pr printcap ' +
- 'printenv printf ps pushd pwd quota quotacheck quotactl ram rcp read readonly renice ' +
- 'remsync rm rmdir rsync screen scp sdiff sed select seq set sftp shift shopt shutdown ' +
- 'sleep sort source split ssh strace su sudo sum symlink sync tail tar tee test time ' +
- 'times touch top traceroute trap tr true tsort tty type ulimit umask umount unalias ' +
- 'uname unexpand uniq units unset unshar useradd usermod users uuencode uudecode v vdir ' +
- 'vi watch wc whereis which who whoami Wget xargs yes'
- ;
-
- this.regexList = [
- { regex: /^#!.*$/gm, css: 'preprocessor bold' },
- { regex: /\/[\w-\/]+/gm, css: 'plain' },
- { regex: SyntaxHighlighter.regexLib.singleLinePerlComments, css: 'comments' }, // one line comments
- { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, // double quoted strings
- { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // single quoted strings
- { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' }, // keywords
- { regex: new RegExp(this.getKeywords(commands), 'gm'), css: 'functions' } // commands
- ];
- }
-
- Brush.prototype = new SyntaxHighlighter.Highlighter();
- Brush.aliases = ['bash', 'shell'];
-
- SyntaxHighlighter.brushes.Bash = Brush;
-
- // CommonJS
- typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
-})();
diff --git a/guides/assets/javascripts/syntaxhighlighter/shBrushCSharp.js b/guides/assets/javascripts/syntaxhighlighter/shBrushCSharp.js
deleted file mode 100644
index 079214efe1..0000000000
--- a/guides/assets/javascripts/syntaxhighlighter/shBrushCSharp.js
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- *
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-;(function()
-{
- // CommonJS
- typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null;
-
- function Brush()
- {
- var keywords = 'abstract as base bool break byte case catch char checked class const ' +
- 'continue decimal default delegate do double else enum event explicit ' +
- 'extern false finally fixed float for foreach get goto if implicit in int ' +
- 'interface internal is lock long namespace new null object operator out ' +
- 'override params private protected public readonly ref return sbyte sealed set ' +
- 'short sizeof stackalloc static string struct switch this throw true try ' +
- 'typeof uint ulong unchecked unsafe ushort using virtual void while';
-
- function fixComments(match, regexInfo)
- {
- var css = (match[0].indexOf("///") == 0)
- ? 'color1'
- : 'comments'
- ;
-
- return [new SyntaxHighlighter.Match(match[0], match.index, css)];
- }
-
- this.regexList = [
- { regex: SyntaxHighlighter.regexLib.singleLineCComments, func : fixComments }, // one line comments
- { regex: SyntaxHighlighter.regexLib.multiLineCComments, css: 'comments' }, // multiline comments
- { regex: /@"(?:[^"]|"")*"/g, css: 'string' }, // @-quoted strings
- { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, // strings
- { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // strings
- { regex: /^\s*#.*/gm, css: 'preprocessor' }, // preprocessor tags like #region and #endregion
- { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' }, // c# keyword
- { regex: /\bpartial(?=\s+(?:class|interface|struct)\b)/g, css: 'keyword' }, // contextual keyword: 'partial'
- { regex: /\byield(?=\s+(?:return|break)\b)/g, css: 'keyword' } // contextual keyword: 'yield'
- ];
-
- this.forHtmlScript(SyntaxHighlighter.regexLib.aspScriptTags);
- };
-
- Brush.prototype = new SyntaxHighlighter.Highlighter();
- Brush.aliases = ['c#', 'c-sharp', 'csharp'];
-
- SyntaxHighlighter.brushes.CSharp = Brush;
-
- // CommonJS
- typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
-})();
-
diff --git a/guides/assets/javascripts/syntaxhighlighter/shBrushColdFusion.js b/guides/assets/javascripts/syntaxhighlighter/shBrushColdFusion.js
deleted file mode 100644
index 627dbb9b76..0000000000
--- a/guides/assets/javascripts/syntaxhighlighter/shBrushColdFusion.js
+++ /dev/null
@@ -1,100 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- *
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-;(function()
-{
- // CommonJS
- typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null;
-
- function Brush()
- {
- // Contributed by Jen
- // http://www.jensbits.com/2009/05/14/coldfusion-brush-for-syntaxhighlighter-plus
-
- var funcs = 'Abs ACos AddSOAPRequestHeader AddSOAPResponseHeader AjaxLink AjaxOnLoad ArrayAppend ArrayAvg ArrayClear ArrayDeleteAt ' +
- 'ArrayInsertAt ArrayIsDefined ArrayIsEmpty ArrayLen ArrayMax ArrayMin ArraySet ArraySort ArraySum ArraySwap ArrayToList ' +
- 'Asc ASin Atn BinaryDecode BinaryEncode BitAnd BitMaskClear BitMaskRead BitMaskSet BitNot BitOr BitSHLN BitSHRN BitXor ' +
- 'Ceiling CharsetDecode CharsetEncode Chr CJustify Compare CompareNoCase Cos CreateDate CreateDateTime CreateObject ' +
- 'CreateODBCDate CreateODBCDateTime CreateODBCTime CreateTime CreateTimeSpan CreateUUID DateAdd DateCompare DateConvert ' +
- 'DateDiff DateFormat DatePart Day DayOfWeek DayOfWeekAsString DayOfYear DaysInMonth DaysInYear DE DecimalFormat DecrementValue ' +
- 'Decrypt DecryptBinary DeleteClientVariable DeserializeJSON DirectoryExists DollarFormat DotNetToCFType Duplicate Encrypt ' +
- 'EncryptBinary Evaluate Exp ExpandPath FileClose FileCopy FileDelete FileExists FileIsEOF FileMove FileOpen FileRead ' +
- 'FileReadBinary FileReadLine FileSetAccessMode FileSetAttribute FileSetLastModified FileWrite Find FindNoCase FindOneOf ' +
- 'FirstDayOfMonth Fix FormatBaseN GenerateSecretKey GetAuthUser GetBaseTagData GetBaseTagList GetBaseTemplatePath ' +
- 'GetClientVariablesList GetComponentMetaData GetContextRoot GetCurrentTemplatePath GetDirectoryFromPath GetEncoding ' +
- 'GetException GetFileFromPath GetFileInfo GetFunctionList GetGatewayHelper GetHttpRequestData GetHttpTimeString ' +
- 'GetK2ServerDocCount GetK2ServerDocCountLimit GetLocale GetLocaleDisplayName GetLocalHostIP GetMetaData GetMetricData ' +
- 'GetPageContext GetPrinterInfo GetProfileSections GetProfileString GetReadableImageFormats GetSOAPRequest GetSOAPRequestHeader ' +
- 'GetSOAPResponse GetSOAPResponseHeader GetTempDirectory GetTempFile GetTemplatePath GetTickCount GetTimeZoneInfo GetToken ' +
- 'GetUserRoles GetWriteableImageFormats Hash Hour HTMLCodeFormat HTMLEditFormat IIf ImageAddBorder ImageBlur ImageClearRect ' +
- 'ImageCopy ImageCrop ImageDrawArc ImageDrawBeveledRect ImageDrawCubicCurve ImageDrawLine ImageDrawLines ImageDrawOval ' +
- 'ImageDrawPoint ImageDrawQuadraticCurve ImageDrawRect ImageDrawRoundRect ImageDrawText ImageFlip ImageGetBlob ImageGetBufferedImage ' +
- 'ImageGetEXIFTag ImageGetHeight ImageGetIPTCTag ImageGetWidth ImageGrayscale ImageInfo ImageNegative ImageNew ImageOverlay ImagePaste ' +
- 'ImageRead ImageReadBase64 ImageResize ImageRotate ImageRotateDrawingAxis ImageScaleToFit ImageSetAntialiasing ImageSetBackgroundColor ' +
- 'ImageSetDrawingColor ImageSetDrawingStroke ImageSetDrawingTransparency ImageSharpen ImageShear ImageShearDrawingAxis ImageTranslate ' +
- 'ImageTranslateDrawingAxis ImageWrite ImageWriteBase64 ImageXORDrawingMode IncrementValue InputBaseN Insert Int IsArray IsBinary ' +
- 'IsBoolean IsCustomFunction IsDate IsDDX IsDebugMode IsDefined IsImage IsImageFile IsInstanceOf IsJSON IsLeapYear IsLocalHost ' +
- 'IsNumeric IsNumericDate IsObject IsPDFFile IsPDFObject IsQuery IsSimpleValue IsSOAPRequest IsStruct IsUserInAnyRole IsUserInRole ' +
- 'IsUserLoggedIn IsValid IsWDDX IsXML IsXmlAttribute IsXmlDoc IsXmlElem IsXmlNode IsXmlRoot JavaCast JSStringFormat LCase Left Len ' +
- 'ListAppend ListChangeDelims ListContains ListContainsNoCase ListDeleteAt ListFind ListFindNoCase ListFirst ListGetAt ListInsertAt ' +
- 'ListLast ListLen ListPrepend ListQualify ListRest ListSetAt ListSort ListToArray ListValueCount ListValueCountNoCase LJustify Log ' +
- 'Log10 LSCurrencyFormat LSDateFormat LSEuroCurrencyFormat LSIsCurrency LSIsDate LSIsNumeric LSNumberFormat LSParseCurrency LSParseDateTime ' +
- 'LSParseEuroCurrency LSParseNumber LSTimeFormat LTrim Max Mid Min Minute Month MonthAsString Now NumberFormat ParagraphFormat ParseDateTime ' +
- 'Pi PrecisionEvaluate PreserveSingleQuotes Quarter QueryAddColumn QueryAddRow QueryConvertForGrid QueryNew QuerySetCell QuotedValueList Rand ' +
- 'Randomize RandRange REFind REFindNoCase ReleaseComObject REMatch REMatchNoCase RemoveChars RepeatString Replace ReplaceList ReplaceNoCase ' +
- 'REReplace REReplaceNoCase Reverse Right RJustify Round RTrim Second SendGatewayMessage SerializeJSON SetEncoding SetLocale SetProfileString ' +
- 'SetVariable Sgn Sin Sleep SpanExcluding SpanIncluding Sqr StripCR StructAppend StructClear StructCopy StructCount StructDelete StructFind ' +
- 'StructFindKey StructFindValue StructGet StructInsert StructIsEmpty StructKeyArray StructKeyExists StructKeyList StructKeyList StructNew ' +
- 'StructSort StructUpdate Tan TimeFormat ToBase64 ToBinary ToScript ToString Trim UCase URLDecode URLEncodedFormat URLSessionFormat Val ' +
- 'ValueList VerifyClient Week Wrap Wrap WriteOutput XmlChildPos XmlElemNew XmlFormat XmlGetNodeType XmlNew XmlParse XmlSearch XmlTransform ' +
- 'XmlValidate Year YesNoFormat';
-
- var keywords = 'cfabort cfajaximport cfajaxproxy cfapplet cfapplication cfargument cfassociate cfbreak cfcache cfcalendar ' +
- 'cfcase cfcatch cfchart cfchartdata cfchartseries cfcol cfcollection cfcomponent cfcontent cfcookie cfdbinfo ' +
- 'cfdefaultcase cfdirectory cfdiv cfdocument cfdocumentitem cfdocumentsection cfdump cfelse cfelseif cferror ' +
- 'cfexchangecalendar cfexchangeconnection cfexchangecontact cfexchangefilter cfexchangemail cfexchangetask ' +
- 'cfexecute cfexit cffeed cffile cfflush cfform cfformgroup cfformitem cfftp cffunction cfgrid cfgridcolumn ' +
- 'cfgridrow cfgridupdate cfheader cfhtmlhead cfhttp cfhttpparam cfif cfimage cfimport cfinclude cfindex ' +
- 'cfinput cfinsert cfinterface cfinvoke cfinvokeargument cflayout cflayoutarea cfldap cflocation cflock cflog ' +
- 'cflogin cfloginuser cflogout cfloop cfmail cfmailparam cfmailpart cfmenu cfmenuitem cfmodule cfNTauthenticate ' +
- 'cfobject cfobjectcache cfoutput cfparam cfpdf cfpdfform cfpdfformparam cfpdfparam cfpdfsubform cfpod cfpop ' +
- 'cfpresentation cfpresentationslide cfpresenter cfprint cfprocessingdirective cfprocparam cfprocresult ' +
- 'cfproperty cfquery cfqueryparam cfregistry cfreport cfreportparam cfrethrow cfreturn cfsavecontent cfschedule ' +
- 'cfscript cfsearch cfselect cfset cfsetting cfsilent cfslider cfsprydataset cfstoredproc cfswitch cftable ' +
- 'cftextarea cfthread cfthrow cftimer cftooltip cftrace cftransaction cftree cftreeitem cftry cfupdate cfwddx ' +
- 'cfwindow cfxml cfzip cfzipparam';
-
- var operators = 'all and any between cross in join like not null or outer some';
-
- this.regexList = [
- { regex: new RegExp('--(.*)$', 'gm'), css: 'comments' }, // one line and multiline comments
- { regex: SyntaxHighlighter.regexLib.xmlComments, css: 'comments' }, // single quoted strings
- { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, // double quoted strings
- { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // single quoted strings
- { regex: new RegExp(this.getKeywords(funcs), 'gmi'), css: 'functions' }, // functions
- { regex: new RegExp(this.getKeywords(operators), 'gmi'), css: 'color1' }, // operators and such
- { regex: new RegExp(this.getKeywords(keywords), 'gmi'), css: 'keyword' } // keyword
- ];
- }
-
- Brush.prototype = new SyntaxHighlighter.Highlighter();
- Brush.aliases = ['coldfusion','cf'];
-
- SyntaxHighlighter.brushes.ColdFusion = Brush;
-
- // CommonJS
- typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
-})();
diff --git a/guides/assets/javascripts/syntaxhighlighter/shBrushCpp.js b/guides/assets/javascripts/syntaxhighlighter/shBrushCpp.js
deleted file mode 100644
index 9f70d3aed6..0000000000
--- a/guides/assets/javascripts/syntaxhighlighter/shBrushCpp.js
+++ /dev/null
@@ -1,97 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- *
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-;(function()
-{
- // CommonJS
- typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null;
-
- function Brush()
- {
- // Copyright 2006 Shin, YoungJin
-
- var datatypes = 'ATOM BOOL BOOLEAN BYTE CHAR COLORREF DWORD DWORDLONG DWORD_PTR ' +
- 'DWORD32 DWORD64 FLOAT HACCEL HALF_PTR HANDLE HBITMAP HBRUSH ' +
- 'HCOLORSPACE HCONV HCONVLIST HCURSOR HDC HDDEDATA HDESK HDROP HDWP ' +
- 'HENHMETAFILE HFILE HFONT HGDIOBJ HGLOBAL HHOOK HICON HINSTANCE HKEY ' +
- 'HKL HLOCAL HMENU HMETAFILE HMODULE HMONITOR HPALETTE HPEN HRESULT ' +
- 'HRGN HRSRC HSZ HWINSTA HWND INT INT_PTR INT32 INT64 LANGID LCID LCTYPE ' +
- 'LGRPID LONG LONGLONG LONG_PTR LONG32 LONG64 LPARAM LPBOOL LPBYTE LPCOLORREF ' +
- 'LPCSTR LPCTSTR LPCVOID LPCWSTR LPDWORD LPHANDLE LPINT LPLONG LPSTR LPTSTR ' +
- 'LPVOID LPWORD LPWSTR LRESULT PBOOL PBOOLEAN PBYTE PCHAR PCSTR PCTSTR PCWSTR ' +
- 'PDWORDLONG PDWORD_PTR PDWORD32 PDWORD64 PFLOAT PHALF_PTR PHANDLE PHKEY PINT ' +
- 'PINT_PTR PINT32 PINT64 PLCID PLONG PLONGLONG PLONG_PTR PLONG32 PLONG64 POINTER_32 ' +
- 'POINTER_64 PSHORT PSIZE_T PSSIZE_T PSTR PTBYTE PTCHAR PTSTR PUCHAR PUHALF_PTR ' +
- 'PUINT PUINT_PTR PUINT32 PUINT64 PULONG PULONGLONG PULONG_PTR PULONG32 PULONG64 ' +
- 'PUSHORT PVOID PWCHAR PWORD PWSTR SC_HANDLE SC_LOCK SERVICE_STATUS_HANDLE SHORT ' +
- 'SIZE_T SSIZE_T TBYTE TCHAR UCHAR UHALF_PTR UINT UINT_PTR UINT32 UINT64 ULONG ' +
- 'ULONGLONG ULONG_PTR ULONG32 ULONG64 USHORT USN VOID WCHAR WORD WPARAM WPARAM WPARAM ' +
- 'char bool short int __int32 __int64 __int8 __int16 long float double __wchar_t ' +
- 'clock_t _complex _dev_t _diskfree_t div_t ldiv_t _exception _EXCEPTION_POINTERS ' +
- 'FILE _finddata_t _finddatai64_t _wfinddata_t _wfinddatai64_t __finddata64_t ' +
- '__wfinddata64_t _FPIEEE_RECORD fpos_t _HEAPINFO _HFILE lconv intptr_t ' +
- 'jmp_buf mbstate_t _off_t _onexit_t _PNH ptrdiff_t _purecall_handler ' +
- 'sig_atomic_t size_t _stat __stat64 _stati64 terminate_function ' +
- 'time_t __time64_t _timeb __timeb64 tm uintptr_t _utimbuf ' +
- 'va_list wchar_t wctrans_t wctype_t wint_t signed';
-
- var keywords = 'break case catch class const __finally __exception __try ' +
- 'const_cast continue private public protected __declspec ' +
- 'default delete deprecated dllexport dllimport do dynamic_cast ' +
- 'else enum explicit extern if for friend goto inline ' +
- 'mutable naked namespace new noinline noreturn nothrow ' +
- 'register reinterpret_cast return selectany ' +
- 'sizeof static static_cast struct switch template this ' +
- 'thread throw true false try typedef typeid typename union ' +
- 'using uuid virtual void volatile whcar_t while';
-
- var functions = 'assert isalnum isalpha iscntrl isdigit isgraph islower isprint' +
- 'ispunct isspace isupper isxdigit tolower toupper errno localeconv ' +
- 'setlocale acos asin atan atan2 ceil cos cosh exp fabs floor fmod ' +
- 'frexp ldexp log log10 modf pow sin sinh sqrt tan tanh jmp_buf ' +
- 'longjmp setjmp raise signal sig_atomic_t va_arg va_end va_start ' +
- 'clearerr fclose feof ferror fflush fgetc fgetpos fgets fopen ' +
- 'fprintf fputc fputs fread freopen fscanf fseek fsetpos ftell ' +
- 'fwrite getc getchar gets perror printf putc putchar puts remove ' +
- 'rename rewind scanf setbuf setvbuf sprintf sscanf tmpfile tmpnam ' +
- 'ungetc vfprintf vprintf vsprintf abort abs atexit atof atoi atol ' +
- 'bsearch calloc div exit free getenv labs ldiv malloc mblen mbstowcs ' +
- 'mbtowc qsort rand realloc srand strtod strtol strtoul system ' +
- 'wcstombs wctomb memchr memcmp memcpy memmove memset strcat strchr ' +
- 'strcmp strcoll strcpy strcspn strerror strlen strncat strncmp ' +
- 'strncpy strpbrk strrchr strspn strstr strtok strxfrm asctime ' +
- 'clock ctime difftime gmtime localtime mktime strftime time';
-
- this.regexList = [
- { regex: SyntaxHighlighter.regexLib.singleLineCComments, css: 'comments' }, // one line comments
- { regex: SyntaxHighlighter.regexLib.multiLineCComments, css: 'comments' }, // multiline comments
- { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, // strings
- { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // strings
- { regex: /^ *#.*/gm, css: 'preprocessor' },
- { regex: new RegExp(this.getKeywords(datatypes), 'gm'), css: 'color1 bold' },
- { regex: new RegExp(this.getKeywords(functions), 'gm'), css: 'functions bold' },
- { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword bold' }
- ];
- };
-
- Brush.prototype = new SyntaxHighlighter.Highlighter();
- Brush.aliases = ['cpp', 'c'];
-
- SyntaxHighlighter.brushes.Cpp = Brush;
-
- // CommonJS
- typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
-})();
diff --git a/guides/assets/javascripts/syntaxhighlighter/shBrushCss.js b/guides/assets/javascripts/syntaxhighlighter/shBrushCss.js
deleted file mode 100644
index 4297a9a648..0000000000
--- a/guides/assets/javascripts/syntaxhighlighter/shBrushCss.js
+++ /dev/null
@@ -1,91 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- *
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-;(function()
-{
- // CommonJS
- typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null;
-
- function Brush()
- {
- function getKeywordsCSS(str)
- {
- return '\\b([a-z_]|)' + str.replace(/ /g, '(?=:)\\b|\\b([a-z_\\*]|\\*|)') + '(?=:)\\b';
- };
-
- function getValuesCSS(str)
- {
- return '\\b' + str.replace(/ /g, '(?!-)(?!:)\\b|\\b()') + '\:\\b';
- };
-
- var keywords = 'ascent azimuth background-attachment background-color background-image background-position ' +
- 'background-repeat background baseline bbox border-collapse border-color border-spacing border-style border-top ' +
- 'border-right border-bottom border-left border-top-color border-right-color border-bottom-color border-left-color ' +
- 'border-top-style border-right-style border-bottom-style border-left-style border-top-width border-right-width ' +
- 'border-bottom-width border-left-width border-width border bottom cap-height caption-side centerline clear clip color ' +
- 'content counter-increment counter-reset cue-after cue-before cue cursor definition-src descent direction display ' +
- 'elevation empty-cells float font-size-adjust font-family font-size font-stretch font-style font-variant font-weight font ' +
- 'height left letter-spacing line-height list-style-image list-style-position list-style-type list-style margin-top ' +
- 'margin-right margin-bottom margin-left margin marker-offset marks mathline max-height max-width min-height min-width orphans ' +
- 'outline-color outline-style outline-width outline overflow padding-top padding-right padding-bottom padding-left padding page ' +
- 'page-break-after page-break-before page-break-inside pause pause-after pause-before pitch pitch-range play-during position ' +
- 'quotes right richness size slope src speak-header speak-numeral speak-punctuation speak speech-rate stemh stemv stress ' +
- 'table-layout text-align top text-decoration text-indent text-shadow text-transform unicode-bidi unicode-range units-per-em ' +
- 'vertical-align visibility voice-family volume white-space widows width widths word-spacing x-height z-index';
-
- var values = 'above absolute all always aqua armenian attr aural auto avoid baseline behind below bidi-override black blink block blue bold bolder '+
- 'both bottom braille capitalize caption center center-left center-right circle close-quote code collapse compact condensed '+
- 'continuous counter counters crop cross crosshair cursive dashed decimal decimal-leading-zero default digits disc dotted double '+
- 'embed embossed e-resize expanded extra-condensed extra-expanded fantasy far-left far-right fast faster fixed format fuchsia '+
- 'gray green groove handheld hebrew help hidden hide high higher icon inline-table inline inset inside invert italic '+
- 'justify landscape large larger left-side left leftwards level lighter lime line-through list-item local loud lower-alpha '+
- 'lowercase lower-greek lower-latin lower-roman lower low ltr marker maroon medium message-box middle mix move narrower '+
- 'navy ne-resize no-close-quote none no-open-quote no-repeat normal nowrap n-resize nw-resize oblique olive once open-quote outset '+
- 'outside overline pointer portrait pre print projection purple red relative repeat repeat-x repeat-y rgb ridge right right-side '+
- 'rightwards rtl run-in screen scroll semi-condensed semi-expanded separate se-resize show silent silver slower slow '+
- 'small small-caps small-caption smaller soft solid speech spell-out square s-resize static status-bar sub super sw-resize '+
- 'table-caption table-cell table-column table-column-group table-footer-group table-header-group table-row table-row-group teal '+
- 'text-bottom text-top thick thin top transparent tty tv ultra-condensed ultra-expanded underline upper-alpha uppercase upper-latin '+
- 'upper-roman url visible wait white wider w-resize x-fast x-high x-large x-loud x-low x-slow x-small x-soft xx-large xx-small yellow';
-
- var fonts = '[mM]onospace [tT]ahoma [vV]erdana [aA]rial [hH]elvetica [sS]ans-serif [sS]erif [cC]ourier mono sans serif';
-
- this.regexList = [
- { regex: SyntaxHighlighter.regexLib.multiLineCComments, css: 'comments' }, // multiline comments
- { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, // double quoted strings
- { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // single quoted strings
- { regex: /\#[a-fA-F0-9]{3,6}/g, css: 'value' }, // html colors
- { regex: /(-?\d+)(\.\d+)?(px|em|pt|\:|\%|)/g, css: 'value' }, // sizes
- { regex: /!important/g, css: 'color3' }, // !important
- { regex: new RegExp(getKeywordsCSS(keywords), 'gm'), css: 'keyword' }, // keywords
- { regex: new RegExp(getValuesCSS(values), 'g'), css: 'value' }, // values
- { regex: new RegExp(this.getKeywords(fonts), 'g'), css: 'color1' } // fonts
- ];
-
- this.forHtmlScript({
- left: /(&lt;|<)\s*style.*?(&gt;|>)/gi,
- right: /(&lt;|<)\/\s*style\s*(&gt;|>)/gi
- });
- };
-
- Brush.prototype = new SyntaxHighlighter.Highlighter();
- Brush.aliases = ['css'];
-
- SyntaxHighlighter.brushes.CSS = Brush;
-
- // CommonJS
- typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
-})();
diff --git a/guides/assets/javascripts/syntaxhighlighter/shBrushDelphi.js b/guides/assets/javascripts/syntaxhighlighter/shBrushDelphi.js
deleted file mode 100644
index e1060d4468..0000000000
--- a/guides/assets/javascripts/syntaxhighlighter/shBrushDelphi.js
+++ /dev/null
@@ -1,55 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- *
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-;(function()
-{
- // CommonJS
- typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null;
-
- function Brush()
- {
- var keywords = 'abs addr and ansichar ansistring array as asm begin boolean byte cardinal ' +
- 'case char class comp const constructor currency destructor div do double ' +
- 'downto else end except exports extended false file finalization finally ' +
- 'for function goto if implementation in inherited int64 initialization ' +
- 'integer interface is label library longint longword mod nil not object ' +
- 'of on or packed pansichar pansistring pchar pcurrency pdatetime pextended ' +
- 'pint64 pointer private procedure program property pshortstring pstring ' +
- 'pvariant pwidechar pwidestring protected public published raise real real48 ' +
- 'record repeat set shl shortint shortstring shr single smallint string then ' +
- 'threadvar to true try type unit until uses val var varirnt while widechar ' +
- 'widestring with word write writeln xor';
-
- this.regexList = [
- { regex: /\(\*[\s\S]*?\*\)/gm, css: 'comments' }, // multiline comments (* *)
- { regex: /{(?!\$)[\s\S]*?}/gm, css: 'comments' }, // multiline comments { }
- { regex: SyntaxHighlighter.regexLib.singleLineCComments, css: 'comments' }, // one line
- { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // strings
- { regex: /\{\$[a-zA-Z]+ .+\}/g, css: 'color1' }, // compiler Directives and Region tags
- { regex: /\b[\d\.]+\b/g, css: 'value' }, // numbers 12345
- { regex: /\$[a-zA-Z0-9]+\b/g, css: 'value' }, // numbers $F5D3
- { regex: new RegExp(this.getKeywords(keywords), 'gmi'), css: 'keyword' } // keyword
- ];
- };
-
- Brush.prototype = new SyntaxHighlighter.Highlighter();
- Brush.aliases = ['delphi', 'pascal', 'pas'];
-
- SyntaxHighlighter.brushes.Delphi = Brush;
-
- // CommonJS
- typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
-})();
diff --git a/guides/assets/javascripts/syntaxhighlighter/shBrushDiff.js b/guides/assets/javascripts/syntaxhighlighter/shBrushDiff.js
deleted file mode 100644
index e9b14fc580..0000000000
--- a/guides/assets/javascripts/syntaxhighlighter/shBrushDiff.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- *
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-;(function()
-{
- // CommonJS
- typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null;
-
- function Brush()
- {
- this.regexList = [
- { regex: /^\+\+\+.*$/gm, css: 'color2' },
- { regex: /^\-\-\-.*$/gm, css: 'color2' },
- { regex: /^\s.*$/gm, css: 'color1' },
- { regex: /^@@.*@@$/gm, css: 'variable' },
- { regex: /^\+[^\+]{1}.*$/gm, css: 'string' },
- { regex: /^\-[^\-]{1}.*$/gm, css: 'comments' }
- ];
- };
-
- Brush.prototype = new SyntaxHighlighter.Highlighter();
- Brush.aliases = ['diff', 'patch'];
-
- SyntaxHighlighter.brushes.Diff = Brush;
-
- // CommonJS
- typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
-})();
diff --git a/guides/assets/javascripts/syntaxhighlighter/shBrushErlang.js b/guides/assets/javascripts/syntaxhighlighter/shBrushErlang.js
deleted file mode 100644
index 6ba7d9da87..0000000000
--- a/guides/assets/javascripts/syntaxhighlighter/shBrushErlang.js
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- *
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-;(function()
-{
- // CommonJS
- typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null;
-
- function Brush()
- {
- // Contributed by Jean-Lou Dupont
- // http://jldupont.blogspot.com/2009/06/erlang-syntax-highlighter.html
-
- // According to: http://erlang.org/doc/reference_manual/introduction.html#1.5
- var keywords = 'after and andalso band begin bnot bor bsl bsr bxor '+
- 'case catch cond div end fun if let not of or orelse '+
- 'query receive rem try when xor'+
- // additional
- ' module export import define';
-
- this.regexList = [
- { regex: new RegExp("[A-Z][A-Za-z0-9_]+", 'g'), css: 'constants' },
- { regex: new RegExp("\\%.+", 'gm'), css: 'comments' },
- { regex: new RegExp("\\?[A-Za-z0-9_]+", 'g'), css: 'preprocessor' },
- { regex: new RegExp("[a-z0-9_]+:[a-z0-9_]+", 'g'), css: 'functions' },
- { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' },
- { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' },
- { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' }
- ];
- };
-
- Brush.prototype = new SyntaxHighlighter.Highlighter();
- Brush.aliases = ['erl', 'erlang'];
-
- SyntaxHighlighter.brushes.Erland = Brush;
-
- // CommonJS
- typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
-})();
diff --git a/guides/assets/javascripts/syntaxhighlighter/shBrushGroovy.js b/guides/assets/javascripts/syntaxhighlighter/shBrushGroovy.js
deleted file mode 100644
index 6ec5c18521..0000000000
--- a/guides/assets/javascripts/syntaxhighlighter/shBrushGroovy.js
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- *
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-;(function()
-{
- // CommonJS
- typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null;
-
- function Brush()
- {
- // Contributed by Andres Almiray
- // http://jroller.com/aalmiray/entry/nice_source_code_syntax_highlighter
-
- var keywords = 'as assert break case catch class continue def default do else extends finally ' +
- 'if in implements import instanceof interface new package property return switch ' +
- 'throw throws try while public protected private static';
- var types = 'void boolean byte char short int long float double';
- var constants = 'null';
- var methods = 'allProperties count get size '+
- 'collect each eachProperty eachPropertyName eachWithIndex find findAll ' +
- 'findIndexOf grep inject max min reverseEach sort ' +
- 'asImmutable asSynchronized flatten intersect join pop reverse subMap toList ' +
- 'padRight padLeft contains eachMatch toCharacter toLong toUrl tokenize ' +
- 'eachFile eachFileRecurse eachB yte eachLine readBytes readLine getText ' +
- 'splitEachLine withReader append encodeBase64 decodeBase64 filterLine ' +
- 'transformChar transformLine withOutputStream withPrintWriter withStream ' +
- 'withStreams withWriter withWriterAppend write writeLine '+
- 'dump inspect invokeMethod print println step times upto use waitForOrKill '+
- 'getText';
-
- this.regexList = [
- { regex: SyntaxHighlighter.regexLib.singleLineCComments, css: 'comments' }, // one line comments
- { regex: SyntaxHighlighter.regexLib.multiLineCComments, css: 'comments' }, // multiline comments
- { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, // strings
- { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // strings
- { regex: /""".*"""/g, css: 'string' }, // GStrings
- { regex: new RegExp('\\b([\\d]+(\\.[\\d]+)?|0x[a-f0-9]+)\\b', 'gi'), css: 'value' }, // numbers
- { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' }, // goovy keyword
- { regex: new RegExp(this.getKeywords(types), 'gm'), css: 'color1' }, // goovy/java type
- { regex: new RegExp(this.getKeywords(constants), 'gm'), css: 'constants' }, // constants
- { regex: new RegExp(this.getKeywords(methods), 'gm'), css: 'functions' } // methods
- ];
-
- this.forHtmlScript(SyntaxHighlighter.regexLib.aspScriptTags);
- }
-
- Brush.prototype = new SyntaxHighlighter.Highlighter();
- Brush.aliases = ['groovy'];
-
- SyntaxHighlighter.brushes.Groovy = Brush;
-
- // CommonJS
- typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
-})();
diff --git a/guides/assets/javascripts/syntaxhighlighter/shBrushJScript.js b/guides/assets/javascripts/syntaxhighlighter/shBrushJScript.js
deleted file mode 100644
index ff98daba16..0000000000
--- a/guides/assets/javascripts/syntaxhighlighter/shBrushJScript.js
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- *
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-;(function()
-{
- // CommonJS
- typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null;
-
- function Brush()
- {
- var keywords = 'break case catch continue ' +
- 'default delete do else false ' +
- 'for function if in instanceof ' +
- 'new null return super switch ' +
- 'this throw true try typeof var while with'
- ;
-
- var r = SyntaxHighlighter.regexLib;
-
- this.regexList = [
- { regex: r.multiLineDoubleQuotedString, css: 'string' }, // double quoted strings
- { regex: r.multiLineSingleQuotedString, css: 'string' }, // single quoted strings
- { regex: r.singleLineCComments, css: 'comments' }, // one line comments
- { regex: r.multiLineCComments, css: 'comments' }, // multiline comments
- { regex: /\s*#.*/gm, css: 'preprocessor' }, // preprocessor tags like #region and #endregion
- { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' } // keywords
- ];
-
- this.forHtmlScript(r.scriptScriptTags);
- };
-
- Brush.prototype = new SyntaxHighlighter.Highlighter();
- Brush.aliases = ['js', 'jscript', 'javascript'];
-
- SyntaxHighlighter.brushes.JScript = Brush;
-
- // CommonJS
- typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
-})();
diff --git a/guides/assets/javascripts/syntaxhighlighter/shBrushJava.js b/guides/assets/javascripts/syntaxhighlighter/shBrushJava.js
deleted file mode 100644
index d692fd6382..0000000000
--- a/guides/assets/javascripts/syntaxhighlighter/shBrushJava.js
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- *
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-;(function()
-{
- // CommonJS
- typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null;
-
- function Brush()
- {
- var keywords = 'abstract assert boolean break byte case catch char class const ' +
- 'continue default do double else enum extends ' +
- 'false final finally float for goto if implements import ' +
- 'instanceof int interface long native new null ' +
- 'package private protected public return ' +
- 'short static strictfp super switch synchronized this throw throws true ' +
- 'transient try void volatile while';
-
- this.regexList = [
- { regex: SyntaxHighlighter.regexLib.singleLineCComments, css: 'comments' }, // one line comments
- { regex: /\/\*([^\*][\s\S]*)?\*\//gm, css: 'comments' }, // multiline comments
- { regex: /\/\*(?!\*\/)\*[\s\S]*?\*\//gm, css: 'preprocessor' }, // documentation comments
- { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, // strings
- { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // strings
- { regex: /\b([\d]+(\.[\d]+)?|0x[a-f0-9]+)\b/gi, css: 'value' }, // numbers
- { regex: /(?!\@interface\b)\@[\$\w]+\b/g, css: 'color1' }, // annotation @anno
- { regex: /\@interface\b/g, css: 'color2' }, // @interface keyword
- { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' } // java keyword
- ];
-
- this.forHtmlScript({
- left : /(&lt;|<)%[@!=]?/g,
- right : /%(&gt;|>)/g
- });
- };
-
- Brush.prototype = new SyntaxHighlighter.Highlighter();
- Brush.aliases = ['java'];
-
- SyntaxHighlighter.brushes.Java = Brush;
-
- // CommonJS
- typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
-})();
diff --git a/guides/assets/javascripts/syntaxhighlighter/shBrushJavaFX.js b/guides/assets/javascripts/syntaxhighlighter/shBrushJavaFX.js
deleted file mode 100644
index 1a150a6ad3..0000000000
--- a/guides/assets/javascripts/syntaxhighlighter/shBrushJavaFX.js
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- *
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-;(function()
-{
- // CommonJS
- typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null;
-
- function Brush()
- {
- // Contributed by Patrick Webster
- // http://patrickwebster.blogspot.com/2009/04/javafx-brush-for-syntaxhighlighter.html
- var datatypes = 'Boolean Byte Character Double Duration '
- + 'Float Integer Long Number Short String Void'
- ;
-
- var keywords = 'abstract after and as assert at before bind bound break catch class '
- + 'continue def delete else exclusive extends false finally first for from '
- + 'function if import in indexof init insert instanceof into inverse last '
- + 'lazy mixin mod nativearray new not null on or override package postinit '
- + 'protected public public-init public-read replace return reverse sizeof '
- + 'step super then this throw true try tween typeof var where while with '
- + 'attribute let private readonly static trigger'
- ;
-
- this.regexList = [
- { regex: SyntaxHighlighter.regexLib.singleLineCComments, css: 'comments' },
- { regex: SyntaxHighlighter.regexLib.multiLineCComments, css: 'comments' },
- { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' },
- { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' },
- { regex: /(-?\.?)(\b(\d*\.?\d+|\d+\.?\d*)(e[+-]?\d+)?|0x[a-f\d]+)\b\.?/gi, css: 'color2' }, // numbers
- { regex: new RegExp(this.getKeywords(datatypes), 'gm'), css: 'variable' }, // datatypes
- { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' }
- ];
- this.forHtmlScript(SyntaxHighlighter.regexLib.aspScriptTags);
- };
-
- Brush.prototype = new SyntaxHighlighter.Highlighter();
- Brush.aliases = ['jfx', 'javafx'];
-
- SyntaxHighlighter.brushes.JavaFX = Brush;
-
- // CommonJS
- typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
-})();
diff --git a/guides/assets/javascripts/syntaxhighlighter/shBrushPerl.js b/guides/assets/javascripts/syntaxhighlighter/shBrushPerl.js
deleted file mode 100644
index d94a2e0ec5..0000000000
--- a/guides/assets/javascripts/syntaxhighlighter/shBrushPerl.js
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- *
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-;(function()
-{
- // CommonJS
- typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null;
-
- function Brush()
- {
- // Contributed by David Simmons-Duffin and Marty Kube
-
- var funcs =
- 'abs accept alarm atan2 bind binmode chdir chmod chomp chop chown chr ' +
- 'chroot close closedir connect cos crypt defined delete each endgrent ' +
- 'endhostent endnetent endprotoent endpwent endservent eof exec exists ' +
- 'exp fcntl fileno flock fork format formline getc getgrent getgrgid ' +
- 'getgrnam gethostbyaddr gethostbyname gethostent getlogin getnetbyaddr ' +
- 'getnetbyname getnetent getpeername getpgrp getppid getpriority ' +
- 'getprotobyname getprotobynumber getprotoent getpwent getpwnam getpwuid ' +
- 'getservbyname getservbyport getservent getsockname getsockopt glob ' +
- 'gmtime grep hex index int ioctl join keys kill lc lcfirst length link ' +
- 'listen localtime lock log lstat map mkdir msgctl msgget msgrcv msgsnd ' +
- 'oct open opendir ord pack pipe pop pos print printf prototype push ' +
- 'quotemeta rand read readdir readline readlink readpipe recv rename ' +
- 'reset reverse rewinddir rindex rmdir scalar seek seekdir select semctl ' +
- 'semget semop send setgrent sethostent setnetent setpgrp setpriority ' +
- 'setprotoent setpwent setservent setsockopt shift shmctl shmget shmread ' +
- 'shmwrite shutdown sin sleep socket socketpair sort splice split sprintf ' +
- 'sqrt srand stat study substr symlink syscall sysopen sysread sysseek ' +
- 'system syswrite tell telldir time times tr truncate uc ucfirst umask ' +
- 'undef unlink unpack unshift utime values vec wait waitpid warn write';
-
- var keywords =
- 'bless caller continue dbmclose dbmopen die do dump else elsif eval exit ' +
- 'for foreach goto if import last local my next no our package redo ref ' +
- 'require return sub tie tied unless untie until use wantarray while';
-
- this.regexList = [
- { regex: new RegExp('#[^!].*$', 'gm'), css: 'comments' },
- { regex: new RegExp('^\\s*#!.*$', 'gm'), css: 'preprocessor' }, // shebang
- { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' },
- { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' },
- { regex: new RegExp('(\\$|@|%)\\w+', 'g'), css: 'variable' },
- { regex: new RegExp(this.getKeywords(funcs), 'gmi'), css: 'functions' },
- { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' }
- ];
-
- this.forHtmlScript(SyntaxHighlighter.regexLib.phpScriptTags);
- }
-
- Brush.prototype = new SyntaxHighlighter.Highlighter();
- Brush.aliases = ['perl', 'Perl', 'pl'];
-
- SyntaxHighlighter.brushes.Perl = Brush;
-
- // CommonJS
- typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
-})();
diff --git a/guides/assets/javascripts/syntaxhighlighter/shBrushPhp.js b/guides/assets/javascripts/syntaxhighlighter/shBrushPhp.js
deleted file mode 100644
index 95e6e4325b..0000000000
--- a/guides/assets/javascripts/syntaxhighlighter/shBrushPhp.js
+++ /dev/null
@@ -1,88 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- *
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-;(function()
-{
- // CommonJS
- typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null;
-
- function Brush()
- {
- var funcs = 'abs acos acosh addcslashes addslashes ' +
- 'array_change_key_case array_chunk array_combine array_count_values array_diff '+
- 'array_diff_assoc array_diff_key array_diff_uassoc array_diff_ukey array_fill '+
- 'array_filter array_flip array_intersect array_intersect_assoc array_intersect_key '+
- 'array_intersect_uassoc array_intersect_ukey array_key_exists array_keys array_map '+
- 'array_merge array_merge_recursive array_multisort array_pad array_pop array_product '+
- 'array_push array_rand array_reduce array_reverse array_search array_shift '+
- 'array_slice array_splice array_sum array_udiff array_udiff_assoc '+
- 'array_udiff_uassoc array_uintersect array_uintersect_assoc '+
- 'array_uintersect_uassoc array_unique array_unshift array_values array_walk '+
- 'array_walk_recursive atan atan2 atanh base64_decode base64_encode base_convert '+
- 'basename bcadd bccomp bcdiv bcmod bcmul bindec bindtextdomain bzclose bzcompress '+
- 'bzdecompress bzerrno bzerror bzerrstr bzflush bzopen bzread bzwrite ceil chdir '+
- 'checkdate checkdnsrr chgrp chmod chop chown chr chroot chunk_split class_exists '+
- 'closedir closelog copy cos cosh count count_chars date decbin dechex decoct '+
- 'deg2rad delete ebcdic2ascii echo empty end ereg ereg_replace eregi eregi_replace error_log '+
- 'error_reporting escapeshellarg escapeshellcmd eval exec exit exp explode extension_loaded '+
- 'feof fflush fgetc fgetcsv fgets fgetss file_exists file_get_contents file_put_contents '+
- 'fileatime filectime filegroup fileinode filemtime fileowner fileperms filesize filetype '+
- 'floatval flock floor flush fmod fnmatch fopen fpassthru fprintf fputcsv fputs fread fscanf '+
- 'fseek fsockopen fstat ftell ftok getallheaders getcwd getdate getenv gethostbyaddr gethostbyname '+
- 'gethostbynamel getimagesize getlastmod getmxrr getmygid getmyinode getmypid getmyuid getopt '+
- 'getprotobyname getprotobynumber getrandmax getrusage getservbyname getservbyport gettext '+
- 'gettimeofday gettype glob gmdate gmmktime ini_alter ini_get ini_get_all ini_restore ini_set '+
- 'interface_exists intval ip2long is_a is_array is_bool is_callable is_dir is_double '+
- 'is_executable is_file is_finite is_float is_infinite is_int is_integer is_link is_long '+
- 'is_nan is_null is_numeric is_object is_readable is_real is_resource is_scalar is_soap_fault '+
- 'is_string is_subclass_of is_uploaded_file is_writable is_writeable mkdir mktime nl2br '+
- 'parse_ini_file parse_str parse_url passthru pathinfo print readlink realpath rewind rewinddir rmdir '+
- 'round str_ireplace str_pad str_repeat str_replace str_rot13 str_shuffle str_split '+
- 'str_word_count strcasecmp strchr strcmp strcoll strcspn strftime strip_tags stripcslashes '+
- 'stripos stripslashes stristr strlen strnatcasecmp strnatcmp strncasecmp strncmp strpbrk '+
- 'strpos strptime strrchr strrev strripos strrpos strspn strstr strtok strtolower strtotime '+
- 'strtoupper strtr strval substr substr_compare';
-
- var keywords = 'abstract and array as break case catch cfunction class clone const continue declare default die do ' +
- 'else elseif enddeclare endfor endforeach endif endswitch endwhile extends final for foreach ' +
- 'function include include_once global goto if implements interface instanceof namespace new ' +
- 'old_function or private protected public return require require_once static switch ' +
- 'throw try use var while xor ';
-
- var constants = '__FILE__ __LINE__ __METHOD__ __FUNCTION__ __CLASS__';
-
- this.regexList = [
- { regex: SyntaxHighlighter.regexLib.singleLineCComments, css: 'comments' }, // one line comments
- { regex: SyntaxHighlighter.regexLib.multiLineCComments, css: 'comments' }, // multiline comments
- { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, // double quoted strings
- { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // single quoted strings
- { regex: /\$\w+/g, css: 'variable' }, // variables
- { regex: new RegExp(this.getKeywords(funcs), 'gmi'), css: 'functions' }, // common functions
- { regex: new RegExp(this.getKeywords(constants), 'gmi'), css: 'constants' }, // constants
- { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' } // keyword
- ];
-
- this.forHtmlScript(SyntaxHighlighter.regexLib.phpScriptTags);
- };
-
- Brush.prototype = new SyntaxHighlighter.Highlighter();
- Brush.aliases = ['php'];
-
- SyntaxHighlighter.brushes.Php = Brush;
-
- // CommonJS
- typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
-})();
diff --git a/guides/assets/javascripts/syntaxhighlighter/shBrushPlain.js b/guides/assets/javascripts/syntaxhighlighter/shBrushPlain.js
deleted file mode 100644
index 9f7d9e90c3..0000000000
--- a/guides/assets/javascripts/syntaxhighlighter/shBrushPlain.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- *
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-;(function()
-{
- // CommonJS
- typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null;
-
- function Brush()
- {
- };
-
- Brush.prototype = new SyntaxHighlighter.Highlighter();
- Brush.aliases = ['text', 'plain'];
-
- SyntaxHighlighter.brushes.Plain = Brush;
-
- // CommonJS
- typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
-})();
diff --git a/guides/assets/javascripts/syntaxhighlighter/shBrushPowerShell.js b/guides/assets/javascripts/syntaxhighlighter/shBrushPowerShell.js
deleted file mode 100644
index 0be1752968..0000000000
--- a/guides/assets/javascripts/syntaxhighlighter/shBrushPowerShell.js
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- *
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-;(function()
-{
- // CommonJS
- typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null;
-
- function Brush()
- {
- // Contributes by B.v.Zanten, Getronics
- // http://confluence.atlassian.com/display/CONFEXT/New+Code+Macro
-
- var keywords = 'Add-Content Add-History Add-Member Add-PSSnapin Clear(-Content)? Clear-Item ' +
- 'Clear-ItemProperty Clear-Variable Compare-Object ConvertFrom-SecureString Convert-Path ' +
- 'ConvertTo-Html ConvertTo-SecureString Copy(-Item)? Copy-ItemProperty Export-Alias ' +
- 'Export-Clixml Export-Console Export-Csv ForEach(-Object)? Format-Custom Format-List ' +
- 'Format-Table Format-Wide Get-Acl Get-Alias Get-AuthenticodeSignature Get-ChildItem Get-Command ' +
- 'Get-Content Get-Credential Get-Culture Get-Date Get-EventLog Get-ExecutionPolicy ' +
- 'Get-Help Get-History Get-Host Get-Item Get-ItemProperty Get-Location Get-Member ' +
- 'Get-PfxCertificate Get-Process Get-PSDrive Get-PSProvider Get-PSSnapin Get-Service ' +
- 'Get-TraceSource Get-UICulture Get-Unique Get-Variable Get-WmiObject Group-Object ' +
- 'Import-Alias Import-Clixml Import-Csv Invoke-Expression Invoke-History Invoke-Item ' +
- 'Join-Path Measure-Command Measure-Object Move(-Item)? Move-ItemProperty New-Alias ' +
- 'New-Item New-ItemProperty New-Object New-PSDrive New-Service New-TimeSpan ' +
- 'New-Variable Out-Default Out-File Out-Host Out-Null Out-Printer Out-String Pop-Location ' +
- 'Push-Location Read-Host Remove-Item Remove-ItemProperty Remove-PSDrive Remove-PSSnapin ' +
- 'Remove-Variable Rename-Item Rename-ItemProperty Resolve-Path Restart-Service Resume-Service ' +
- 'Select-Object Select-String Set-Acl Set-Alias Set-AuthenticodeSignature Set-Content ' +
- 'Set-Date Set-ExecutionPolicy Set-Item Set-ItemProperty Set-Location Set-PSDebug ' +
- 'Set-Service Set-TraceSource Set(-Variable)? Sort-Object Split-Path Start-Service ' +
- 'Start-Sleep Start-Transcript Stop-Process Stop-Service Stop-Transcript Suspend-Service ' +
- 'Tee-Object Test-Path Trace-Command Update-FormatData Update-TypeData Where(-Object)? ' +
- 'Write-Debug Write-Error Write(-Host)? Write-Output Write-Progress Write-Verbose Write-Warning';
- var alias = 'ac asnp clc cli clp clv cpi cpp cvpa diff epal epcsv fc fl ' +
- 'ft fw gal gc gci gcm gdr ghy gi gl gm gp gps group gsv ' +
- 'gsnp gu gv gwmi iex ihy ii ipal ipcsv mi mp nal ndr ni nv oh rdr ' +
- 'ri rni rnp rp rsnp rv rvpa sal sasv sc select si sl sleep sort sp ' +
- 'spps spsv sv tee cat cd cp h history kill lp ls ' +
- 'mount mv popd ps pushd pwd r rm rmdir echo cls chdir del dir ' +
- 'erase rd ren type % \\?';
-
- this.regexList = [
- { regex: /#.*$/gm, css: 'comments' }, // one line comments
- { regex: /\$[a-zA-Z0-9]+\b/g, css: 'value' }, // variables $Computer1
- { regex: /\-[a-zA-Z]+\b/g, css: 'keyword' }, // Operators -not -and -eq
- { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, // strings
- { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // strings
- { regex: new RegExp(this.getKeywords(keywords), 'gmi'), css: 'keyword' },
- { regex: new RegExp(this.getKeywords(alias), 'gmi'), css: 'keyword' }
- ];
- };
-
- Brush.prototype = new SyntaxHighlighter.Highlighter();
- Brush.aliases = ['powershell', 'ps'];
-
- SyntaxHighlighter.brushes.PowerShell = Brush;
-
- // CommonJS
- typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
-})();
diff --git a/guides/assets/javascripts/syntaxhighlighter/shBrushPython.js b/guides/assets/javascripts/syntaxhighlighter/shBrushPython.js
deleted file mode 100644
index ce77462975..0000000000
--- a/guides/assets/javascripts/syntaxhighlighter/shBrushPython.js
+++ /dev/null
@@ -1,64 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- *
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-;(function()
-{
- // CommonJS
- typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null;
-
- function Brush()
- {
- // Contributed by Gheorghe Milas and Ahmad Sherif
-
- var keywords = 'and assert break class continue def del elif else ' +
- 'except exec finally for from global if import in is ' +
- 'lambda not or pass print raise return try yield while';
-
- var funcs = '__import__ abs all any apply basestring bin bool buffer callable ' +
- 'chr classmethod cmp coerce compile complex delattr dict dir ' +
- 'divmod enumerate eval execfile file filter float format frozenset ' +
- 'getattr globals hasattr hash help hex id input int intern ' +
- 'isinstance issubclass iter len list locals long map max min next ' +
- 'object oct open ord pow print property range raw_input reduce ' +
- 'reload repr reversed round set setattr slice sorted staticmethod ' +
- 'str sum super tuple type type unichr unicode vars xrange zip';
-
- var special = 'None True False self cls class_';
-
- this.regexList = [
- { regex: SyntaxHighlighter.regexLib.singleLinePerlComments, css: 'comments' },
- { regex: /^\s*@\w+/gm, css: 'decorator' },
- { regex: /(['\"]{3})([^\1])*?\1/gm, css: 'comments' },
- { regex: /"(?!")(?:\.|\\\"|[^\""\n])*"/gm, css: 'string' },
- { regex: /'(?!')(?:\.|(\\\')|[^\''\n])*'/gm, css: 'string' },
- { regex: /\+|\-|\*|\/|\%|=|==/gm, css: 'keyword' },
- { regex: /\b\d+\.?\w*/g, css: 'value' },
- { regex: new RegExp(this.getKeywords(funcs), 'gmi'), css: 'functions' },
- { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' },
- { regex: new RegExp(this.getKeywords(special), 'gm'), css: 'color1' }
- ];
-
- this.forHtmlScript(SyntaxHighlighter.regexLib.aspScriptTags);
- };
-
- Brush.prototype = new SyntaxHighlighter.Highlighter();
- Brush.aliases = ['py', 'python'];
-
- SyntaxHighlighter.brushes.Python = Brush;
-
- // CommonJS
- typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
-})();
diff --git a/guides/assets/javascripts/syntaxhighlighter/shBrushRuby.js b/guides/assets/javascripts/syntaxhighlighter/shBrushRuby.js
deleted file mode 100644
index ff82130a7a..0000000000
--- a/guides/assets/javascripts/syntaxhighlighter/shBrushRuby.js
+++ /dev/null
@@ -1,55 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- *
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-;(function()
-{
- // CommonJS
- typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null;
-
- function Brush()
- {
- // Contributed by Erik Peterson.
-
- var keywords = 'alias and BEGIN begin break case class def define_method defined do each else elsif ' +
- 'END end ensure false for if in module new next nil not or raise redo rescue retry return ' +
- 'self super then throw true undef unless until when while yield';
-
- var builtins = 'Array Bignum Binding Class Continuation Dir Exception FalseClass File::Stat File Fixnum Fload ' +
- 'Hash Integer IO MatchData Method Module NilClass Numeric Object Proc Range Regexp String Struct::TMS Symbol ' +
- 'ThreadGroup Thread Time TrueClass';
-
- this.regexList = [
- { regex: SyntaxHighlighter.regexLib.singleLinePerlComments, css: 'comments' }, // one line comments
- { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, // double quoted strings
- { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // single quoted strings
- { regex: /\b[A-Z0-9_]+\b/g, css: 'constants' }, // constants
- { regex: /:[a-z][A-Za-z0-9_]*/g, css: 'color2' }, // symbols
- { regex: /(\$|@@|@)\w+/g, css: 'variable bold' }, // $global, @instance, and @@class variables
- { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' }, // keywords
- { regex: new RegExp(this.getKeywords(builtins), 'gm'), css: 'color1' } // builtins
- ];
-
- this.forHtmlScript(SyntaxHighlighter.regexLib.aspScriptTags);
- };
-
- Brush.prototype = new SyntaxHighlighter.Highlighter();
- Brush.aliases = ['ruby', 'rails', 'ror', 'rb'];
-
- SyntaxHighlighter.brushes.Ruby = Brush;
-
- // CommonJS
- typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
-})();
diff --git a/guides/assets/javascripts/syntaxhighlighter/shBrushSass.js b/guides/assets/javascripts/syntaxhighlighter/shBrushSass.js
deleted file mode 100644
index aa04da0996..0000000000
--- a/guides/assets/javascripts/syntaxhighlighter/shBrushSass.js
+++ /dev/null
@@ -1,94 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- *
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-;(function()
-{
- // CommonJS
- typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null;
-
- function Brush()
- {
- function getKeywordsCSS(str)
- {
- return '\\b([a-z_]|)' + str.replace(/ /g, '(?=:)\\b|\\b([a-z_\\*]|\\*|)') + '(?=:)\\b';
- };
-
- function getValuesCSS(str)
- {
- return '\\b' + str.replace(/ /g, '(?!-)(?!:)\\b|\\b()') + '\:\\b';
- };
-
- var keywords = 'ascent azimuth background-attachment background-color background-image background-position ' +
- 'background-repeat background baseline bbox border-collapse border-color border-spacing border-style border-top ' +
- 'border-right border-bottom border-left border-top-color border-right-color border-bottom-color border-left-color ' +
- 'border-top-style border-right-style border-bottom-style border-left-style border-top-width border-right-width ' +
- 'border-bottom-width border-left-width border-width border bottom cap-height caption-side centerline clear clip color ' +
- 'content counter-increment counter-reset cue-after cue-before cue cursor definition-src descent direction display ' +
- 'elevation empty-cells float font-size-adjust font-family font-size font-stretch font-style font-variant font-weight font ' +
- 'height left letter-spacing line-height list-style-image list-style-position list-style-type list-style margin-top ' +
- 'margin-right margin-bottom margin-left margin marker-offset marks mathline max-height max-width min-height min-width orphans ' +
- 'outline-color outline-style outline-width outline overflow padding-top padding-right padding-bottom padding-left padding page ' +
- 'page-break-after page-break-before page-break-inside pause pause-after pause-before pitch pitch-range play-during position ' +
- 'quotes right richness size slope src speak-header speak-numeral speak-punctuation speak speech-rate stemh stemv stress ' +
- 'table-layout text-align top text-decoration text-indent text-shadow text-transform unicode-bidi unicode-range units-per-em ' +
- 'vertical-align visibility voice-family volume white-space widows width widths word-spacing x-height z-index';
-
- var values = 'above absolute all always aqua armenian attr aural auto avoid baseline behind below bidi-override black blink block blue bold bolder '+
- 'both bottom braille capitalize caption center center-left center-right circle close-quote code collapse compact condensed '+
- 'continuous counter counters crop cross crosshair cursive dashed decimal decimal-leading-zero digits disc dotted double '+
- 'embed embossed e-resize expanded extra-condensed extra-expanded fantasy far-left far-right fast faster fixed format fuchsia '+
- 'gray green groove handheld hebrew help hidden hide high higher icon inline-table inline inset inside invert italic '+
- 'justify landscape large larger left-side left leftwards level lighter lime line-through list-item local loud lower-alpha '+
- 'lowercase lower-greek lower-latin lower-roman lower low ltr marker maroon medium message-box middle mix move narrower '+
- 'navy ne-resize no-close-quote none no-open-quote no-repeat normal nowrap n-resize nw-resize oblique olive once open-quote outset '+
- 'outside overline pointer portrait pre print projection purple red relative repeat repeat-x repeat-y rgb ridge right right-side '+
- 'rightwards rtl run-in screen scroll semi-condensed semi-expanded separate se-resize show silent silver slower slow '+
- 'small small-caps small-caption smaller soft solid speech spell-out square s-resize static status-bar sub super sw-resize '+
- 'table-caption table-cell table-column table-column-group table-footer-group table-header-group table-row table-row-group teal '+
- 'text-bottom text-top thick thin top transparent tty tv ultra-condensed ultra-expanded underline upper-alpha uppercase upper-latin '+
- 'upper-roman url visible wait white wider w-resize x-fast x-high x-large x-loud x-low x-slow x-small x-soft xx-large xx-small yellow';
-
- var fonts = '[mM]onospace [tT]ahoma [vV]erdana [aA]rial [hH]elvetica [sS]ans-serif [sS]erif [cC]ourier mono sans serif';
-
- var statements = '!important !default';
- var preprocessor = '@import @extend @debug @warn @if @for @while @mixin @include';
-
- var r = SyntaxHighlighter.regexLib;
-
- this.regexList = [
- { regex: r.multiLineCComments, css: 'comments' }, // multiline comments
- { regex: r.singleLineCComments, css: 'comments' }, // singleline comments
- { regex: r.doubleQuotedString, css: 'string' }, // double quoted strings
- { regex: r.singleQuotedString, css: 'string' }, // single quoted strings
- { regex: /\#[a-fA-F0-9]{3,6}/g, css: 'value' }, // html colors
- { regex: /\b(-?\d+)(\.\d+)?(px|em|pt|\:|\%|)\b/g, css: 'value' }, // sizes
- { regex: /\$\w+/g, css: 'variable' }, // variables
- { regex: new RegExp(this.getKeywords(statements), 'g'), css: 'color3' }, // statements
- { regex: new RegExp(this.getKeywords(preprocessor), 'g'), css: 'preprocessor' }, // preprocessor
- { regex: new RegExp(getKeywordsCSS(keywords), 'gm'), css: 'keyword' }, // keywords
- { regex: new RegExp(getValuesCSS(values), 'g'), css: 'value' }, // values
- { regex: new RegExp(this.getKeywords(fonts), 'g'), css: 'color1' } // fonts
- ];
- };
-
- Brush.prototype = new SyntaxHighlighter.Highlighter();
- Brush.aliases = ['sass', 'scss'];
-
- SyntaxHighlighter.brushes.Sass = Brush;
-
- // CommonJS
- typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
-})();
diff --git a/guides/assets/javascripts/syntaxhighlighter/shBrushScala.js b/guides/assets/javascripts/syntaxhighlighter/shBrushScala.js
deleted file mode 100644
index 4b0b6f04d2..0000000000
--- a/guides/assets/javascripts/syntaxhighlighter/shBrushScala.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- *
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-;(function()
-{
- // CommonJS
- typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null;
-
- function Brush()
- {
- // Contributed by Yegor Jbanov and David Bernard.
-
- var keywords = 'val sealed case def true trait implicit forSome import match object null finally super ' +
- 'override try lazy for var catch throw type extends class while with new final yield abstract ' +
- 'else do if return protected private this package false';
-
- var keyops = '[_:=><%#@]+';
-
- this.regexList = [
- { regex: SyntaxHighlighter.regexLib.singleLineCComments, css: 'comments' }, // one line comments
- { regex: SyntaxHighlighter.regexLib.multiLineCComments, css: 'comments' }, // multiline comments
- { regex: SyntaxHighlighter.regexLib.multiLineSingleQuotedString, css: 'string' }, // multi-line strings
- { regex: SyntaxHighlighter.regexLib.multiLineDoubleQuotedString, css: 'string' }, // double-quoted string
- { regex: SyntaxHighlighter.regexLib.singleQuotedString, css: 'string' }, // strings
- { regex: /0x[a-f0-9]+|\d+(\.\d+)?/gi, css: 'value' }, // numbers
- { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' }, // keywords
- { regex: new RegExp(keyops, 'gm'), css: 'keyword' } // scala keyword
- ];
- }
-
- Brush.prototype = new SyntaxHighlighter.Highlighter();
- Brush.aliases = ['scala'];
-
- SyntaxHighlighter.brushes.Scala = Brush;
-
- // CommonJS
- typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
-})();
diff --git a/guides/assets/javascripts/syntaxhighlighter/shBrushSql.js b/guides/assets/javascripts/syntaxhighlighter/shBrushSql.js
deleted file mode 100644
index 5c2cd8806f..0000000000
--- a/guides/assets/javascripts/syntaxhighlighter/shBrushSql.js
+++ /dev/null
@@ -1,66 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- *
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-;(function()
-{
- // CommonJS
- typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null;
-
- function Brush()
- {
- var funcs = 'abs avg case cast coalesce convert count current_timestamp ' +
- 'current_user day isnull left lower month nullif replace right ' +
- 'session_user space substring sum system_user upper user year';
-
- var keywords = 'absolute action add after alter as asc at authorization begin bigint ' +
- 'binary bit by cascade char character check checkpoint close collate ' +
- 'column commit committed connect connection constraint contains continue ' +
- 'create cube current current_date current_time cursor database date ' +
- 'deallocate dec decimal declare default delete desc distinct double drop ' +
- 'dynamic else end end-exec escape except exec execute false fetch first ' +
- 'float for force foreign forward free from full function global goto grant ' +
- 'group grouping having hour ignore index inner insensitive insert instead ' +
- 'int integer intersect into is isolation key last level load local max min ' +
- 'minute modify move name national nchar next no numeric of off on only ' +
- 'open option order out output partial password precision prepare primary ' +
- 'prior privileges procedure public read real references relative repeatable ' +
- 'restrict return returns revoke rollback rollup rows rule schema scroll ' +
- 'second section select sequence serializable set size smallint static ' +
- 'statistics table temp temporary then time timestamp to top transaction ' +
- 'translation trigger true truncate uncommitted union unique update values ' +
- 'varchar varying view when where with work';
-
- var operators = 'all and any between cross in join like not null or outer some';
-
- this.regexList = [
- { regex: /--(.*)$/gm, css: 'comments' }, // one line and multiline comments
- { regex: SyntaxHighlighter.regexLib.multiLineDoubleQuotedString, css: 'string' }, // double quoted strings
- { regex: SyntaxHighlighter.regexLib.multiLineSingleQuotedString, css: 'string' }, // single quoted strings
- { regex: new RegExp(this.getKeywords(funcs), 'gmi'), css: 'color2' }, // functions
- { regex: new RegExp(this.getKeywords(operators), 'gmi'), css: 'color1' }, // operators and such
- { regex: new RegExp(this.getKeywords(keywords), 'gmi'), css: 'keyword' } // keyword
- ];
- };
-
- Brush.prototype = new SyntaxHighlighter.Highlighter();
- Brush.aliases = ['sql'];
-
- SyntaxHighlighter.brushes.Sql = Brush;
-
- // CommonJS
- typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
-})();
-
diff --git a/guides/assets/javascripts/syntaxhighlighter/shBrushVb.js b/guides/assets/javascripts/syntaxhighlighter/shBrushVb.js
deleted file mode 100644
index be845dc0b3..0000000000
--- a/guides/assets/javascripts/syntaxhighlighter/shBrushVb.js
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- *
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-;(function()
-{
- // CommonJS
- typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null;
-
- function Brush()
- {
- var keywords = 'AddHandler AddressOf AndAlso Alias And Ansi As Assembly Auto ' +
- 'Boolean ByRef Byte ByVal Call Case Catch CBool CByte CChar CDate ' +
- 'CDec CDbl Char CInt Class CLng CObj Const CShort CSng CStr CType ' +
- 'Date Decimal Declare Default Delegate Dim DirectCast Do Double Each ' +
- 'Else ElseIf End Enum Erase Error Event Exit False Finally For Friend ' +
- 'Function Get GetType GoSub GoTo Handles If Implements Imports In ' +
- 'Inherits Integer Interface Is Let Lib Like Long Loop Me Mod Module ' +
- 'MustInherit MustOverride MyBase MyClass Namespace New Next Not Nothing ' +
- 'NotInheritable NotOverridable Object On Option Optional Or OrElse ' +
- 'Overloads Overridable Overrides ParamArray Preserve Private Property ' +
- 'Protected Public RaiseEvent ReadOnly ReDim REM RemoveHandler Resume ' +
- 'Return Select Set Shadows Shared Short Single Static Step Stop String ' +
- 'Structure Sub SyncLock Then Throw To True Try TypeOf Unicode Until ' +
- 'Variant When While With WithEvents WriteOnly Xor';
-
- this.regexList = [
- { regex: /'.*$/gm, css: 'comments' }, // one line comments
- { regex: SyntaxHighlighter.regexLib.doubleQuotedString, css: 'string' }, // strings
- { regex: /^\s*#.*$/gm, css: 'preprocessor' }, // preprocessor tags like #region and #endregion
- { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' } // vb keyword
- ];
-
- this.forHtmlScript(SyntaxHighlighter.regexLib.aspScriptTags);
- };
-
- Brush.prototype = new SyntaxHighlighter.Highlighter();
- Brush.aliases = ['vb', 'vbnet'];
-
- SyntaxHighlighter.brushes.Vb = Brush;
-
- // CommonJS
- typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
-})();
diff --git a/guides/assets/javascripts/syntaxhighlighter/shBrushXml.js b/guides/assets/javascripts/syntaxhighlighter/shBrushXml.js
deleted file mode 100644
index 69d9fd0b1f..0000000000
--- a/guides/assets/javascripts/syntaxhighlighter/shBrushXml.js
+++ /dev/null
@@ -1,69 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- *
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-;(function()
-{
- // CommonJS
- typeof(require) != 'undefined' ? SyntaxHighlighter = require('shCore').SyntaxHighlighter : null;
-
- function Brush()
- {
- function process(match, regexInfo)
- {
- var constructor = SyntaxHighlighter.Match,
- code = match[0],
- tag = new XRegExp('(&lt;|<)[\\s\\/\\?]*(?<name>[:\\w-\\.]+)', 'xg').exec(code),
- result = []
- ;
-
- if (match.attributes != null)
- {
- var attributes,
- regex = new XRegExp('(?<name> [\\w:\\-\\.]+)' +
- '\\s*=\\s*' +
- '(?<value> ".*?"|\'.*?\'|\\w+)',
- 'xg');
-
- while ((attributes = regex.exec(code)) != null)
- {
- result.push(new constructor(attributes.name, match.index + attributes.index, 'color1'));
- result.push(new constructor(attributes.value, match.index + attributes.index + attributes[0].indexOf(attributes.value), 'string'));
- }
- }
-
- if (tag != null)
- result.push(
- new constructor(tag.name, match.index + tag[0].indexOf(tag.name), 'keyword')
- );
-
- return result;
- }
-
- this.regexList = [
- { regex: new XRegExp('(\\&lt;|<)\\!\\[[\\w\\s]*?\\[(.|\\s)*?\\]\\](\\&gt;|>)', 'gm'), css: 'color2' }, // <![ ... [ ... ]]>
- { regex: SyntaxHighlighter.regexLib.xmlComments, css: 'comments' }, // <!-- ... -->
- { regex: new XRegExp('(&lt;|<)[\\s\\/\\?]*(\\w+)(?<attributes>.*?)[\\s\\/\\?]*(&gt;|>)', 'sg'), func: process }
- ];
- };
-
- Brush.prototype = new SyntaxHighlighter.Highlighter();
- Brush.aliases = ['xml', 'xhtml', 'xslt', 'html'];
-
- SyntaxHighlighter.brushes.Xml = Brush;
-
- // CommonJS
- typeof(exports) != 'undefined' ? exports.Brush = Brush : null;
-})();
diff --git a/guides/assets/javascripts/syntaxhighlighter/shCore.js b/guides/assets/javascripts/syntaxhighlighter/shCore.js
deleted file mode 100644
index b47b645472..0000000000
--- a/guides/assets/javascripts/syntaxhighlighter/shCore.js
+++ /dev/null
@@ -1,17 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- *
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-eval(function(p,a,c,k,e,d){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--){d[e(c)]=k[c]||e(c)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('K M;I(M)1S 2U("2a\'t 4k M 4K 2g 3l 4G 4H");(6(){6 r(f,e){I(!M.1R(f))1S 3m("3s 15 4R");K a=f.1w;f=M(f.1m,t(f)+(e||""));I(a)f.1w={1m:a.1m,19:a.19?a.19.1a(0):N};H f}6 t(f){H(f.1J?"g":"")+(f.4s?"i":"")+(f.4p?"m":"")+(f.4v?"x":"")+(f.3n?"y":"")}6 B(f,e,a,b){K c=u.L,d,h,g;v=R;5K{O(;c--;){g=u[c];I(a&g.3r&&(!g.2p||g.2p.W(b))){g.2q.12=e;I((h=g.2q.X(f))&&h.P===e){d={3k:g.2b.W(b,h,a),1C:h};1N}}}}5v(i){1S i}5q{v=11}H d}6 p(f,e,a){I(3b.Z.1i)H f.1i(e,a);O(a=a||0;a<f.L;a++)I(f[a]===e)H a;H-1}M=6(f,e){K a=[],b=M.1B,c=0,d,h;I(M.1R(f)){I(e!==1d)1S 3m("2a\'t 5r 5I 5F 5B 5C 15 5E 5p");H r(f)}I(v)1S 2U("2a\'t W 3l M 59 5m 5g 5x 5i");e=e||"";O(d={2N:11,19:[],2K:6(g){H e.1i(g)>-1},3d:6(g){e+=g}};c<f.L;)I(h=B(f,c,b,d)){a.U(h.3k);c+=h.1C[0].L||1}Y I(h=n.X.W(z[b],f.1a(c))){a.U(h[0]);c+=h[0].L}Y{h=f.3a(c);I(h==="[")b=M.2I;Y I(h==="]")b=M.1B;a.U(h);c++}a=15(a.1K(""),n.Q.W(e,w,""));a.1w={1m:f,19:d.2N?d.19:N};H a};M.3v="1.5.0";M.2I=1;M.1B=2;K C=/\\$(?:(\\d\\d?|[$&`\'])|{([$\\w]+)})/g,w=/[^5h]+|([\\s\\S])(?=[\\s\\S]*\\1)/g,A=/^(?:[?*+]|{\\d+(?:,\\d*)?})\\??/,v=11,u=[],n={X:15.Z.X,1A:15.Z.1A,1C:1r.Z.1C,Q:1r.Z.Q,1e:1r.Z.1e},x=n.X.W(/()??/,"")[1]===1d,D=6(){K f=/^/g;n.1A.W(f,"");H!f.12}(),y=6(){K f=/x/g;n.Q.W("x",f,"");H!f.12}(),E=15.Z.3n!==1d,z={};z[M.2I]=/^(?:\\\\(?:[0-3][0-7]{0,2}|[4-7][0-7]?|x[\\29-26-f]{2}|u[\\29-26-f]{4}|c[A-3o-z]|[\\s\\S]))/;z[M.1B]=/^(?:\\\\(?:0(?:[0-3][0-7]{0,2}|[4-7][0-7]?)?|[1-9]\\d*|x[\\29-26-f]{2}|u[\\29-26-f]{4}|c[A-3o-z]|[\\s\\S])|\\(\\?[:=!]|[?*+]\\?|{\\d+(?:,\\d*)?}\\??)/;M.1h=6(f,e,a,b){u.U({2q:r(f,"g"+(E?"y":"")),2b:e,3r:a||M.1B,2p:b||N})};M.2n=6(f,e){K a=f+"/"+(e||"");H M.2n[a]||(M.2n[a]=M(f,e))};M.3c=6(f){H r(f,"g")};M.5l=6(f){H f.Q(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g,"\\\\$&")};M.5e=6(f,e,a,b){e=r(e,"g"+(b&&E?"y":""));e.12=a=a||0;f=e.X(f);H b?f&&f.P===a?f:N:f};M.3q=6(){M.1h=6(){1S 2U("2a\'t 55 1h 54 3q")}};M.1R=6(f){H 53.Z.1q.W(f)==="[2m 15]"};M.3p=6(f,e,a,b){O(K c=r(e,"g"),d=-1,h;h=c.X(f);){a.W(b,h,++d,f,c);c.12===h.P&&c.12++}I(e.1J)e.12=0};M.57=6(f,e){H 6 a(b,c){K d=e[c].1I?e[c]:{1I:e[c]},h=r(d.1I,"g"),g=[],i;O(i=0;i<b.L;i++)M.3p(b[i],h,6(k){g.U(d.3j?k[d.3j]||"":k[0])});H c===e.L-1||!g.L?g:a(g,c+1)}([f],0)};15.Z.1p=6(f,e){H J.X(e[0])};15.Z.W=6(f,e){H J.X(e)};15.Z.X=6(f){K e=n.X.1p(J,14),a;I(e){I(!x&&e.L>1&&p(e,"")>-1){a=15(J.1m,n.Q.W(t(J),"g",""));n.Q.W(f.1a(e.P),a,6(){O(K c=1;c<14.L-2;c++)I(14[c]===1d)e[c]=1d})}I(J.1w&&J.1w.19)O(K b=1;b<e.L;b++)I(a=J.1w.19[b-1])e[a]=e[b];!D&&J.1J&&!e[0].L&&J.12>e.P&&J.12--}H e};I(!D)15.Z.1A=6(f){(f=n.X.W(J,f))&&J.1J&&!f[0].L&&J.12>f.P&&J.12--;H!!f};1r.Z.1C=6(f){M.1R(f)||(f=15(f));I(f.1J){K e=n.1C.1p(J,14);f.12=0;H e}H f.X(J)};1r.Z.Q=6(f,e){K a=M.1R(f),b,c;I(a&&1j e.58()==="3f"&&e.1i("${")===-1&&y)H n.Q.1p(J,14);I(a){I(f.1w)b=f.1w.19}Y f+="";I(1j e==="6")c=n.Q.W(J,f,6(){I(b){14[0]=1f 1r(14[0]);O(K d=0;d<b.L;d++)I(b[d])14[0][b[d]]=14[d+1]}I(a&&f.1J)f.12=14[14.L-2]+14[0].L;H e.1p(N,14)});Y{c=J+"";c=n.Q.W(c,f,6(){K d=14;H n.Q.W(e,C,6(h,g,i){I(g)5b(g){24"$":H"$";24"&":H d[0];24"`":H d[d.L-1].1a(0,d[d.L-2]);24"\'":H d[d.L-1].1a(d[d.L-2]+d[0].L);5a:i="";g=+g;I(!g)H h;O(;g>d.L-3;){i=1r.Z.1a.W(g,-1)+i;g=1Q.3i(g/10)}H(g?d[g]||"":"$")+i}Y{g=+i;I(g<=d.L-3)H d[g];g=b?p(b,i):-1;H g>-1?d[g+1]:h}})})}I(a&&f.1J)f.12=0;H c};1r.Z.1e=6(f,e){I(!M.1R(f))H n.1e.1p(J,14);K a=J+"",b=[],c=0,d,h;I(e===1d||+e<0)e=5D;Y{e=1Q.3i(+e);I(!e)H[]}O(f=M.3c(f);d=f.X(a);){I(f.12>c){b.U(a.1a(c,d.P));d.L>1&&d.P<a.L&&3b.Z.U.1p(b,d.1a(1));h=d[0].L;c=f.12;I(b.L>=e)1N}f.12===d.P&&f.12++}I(c===a.L){I(!n.1A.W(f,"")||h)b.U("")}Y b.U(a.1a(c));H b.L>e?b.1a(0,e):b};M.1h(/\\(\\?#[^)]*\\)/,6(f){H n.1A.W(A,f.2S.1a(f.P+f[0].L))?"":"(?:)"});M.1h(/\\((?!\\?)/,6(){J.19.U(N);H"("});M.1h(/\\(\\?<([$\\w]+)>/,6(f){J.19.U(f[1]);J.2N=R;H"("});M.1h(/\\\\k<([\\w$]+)>/,6(f){K e=p(J.19,f[1]);H e>-1?"\\\\"+(e+1)+(3R(f.2S.3a(f.P+f[0].L))?"":"(?:)"):f[0]});M.1h(/\\[\\^?]/,6(f){H f[0]==="[]"?"\\\\b\\\\B":"[\\\\s\\\\S]"});M.1h(/^\\(\\?([5A]+)\\)/,6(f){J.3d(f[1]);H""});M.1h(/(?:\\s+|#.*)+/,6(f){H n.1A.W(A,f.2S.1a(f.P+f[0].L))?"":"(?:)"},M.1B,6(){H J.2K("x")});M.1h(/\\./,6(){H"[\\\\s\\\\S]"},M.1B,6(){H J.2K("s")})})();1j 2e!="1d"&&(2e.M=M);K 1v=6(){6 r(a,b){a.1l.1i(b)!=-1||(a.1l+=" "+b)}6 t(a){H a.1i("3e")==0?a:"3e"+a}6 B(a){H e.1Y.2A[t(a)]}6 p(a,b,c){I(a==N)H N;K d=c!=R?a.3G:[a.2G],h={"#":"1c",".":"1l"}[b.1o(0,1)]||"3h",g,i;g=h!="3h"?b.1o(1):b.5u();I((a[h]||"").1i(g)!=-1)H a;O(a=0;d&&a<d.L&&i==N;a++)i=p(d[a],b,c);H i}6 C(a,b){K c={},d;O(d 2g a)c[d]=a[d];O(d 2g b)c[d]=b[d];H c}6 w(a,b,c,d){6 h(g){g=g||1P.5y;I(!g.1F){g.1F=g.52;g.3N=6(){J.5w=11}}c.W(d||1P,g)}a.3g?a.3g("4U"+b,h):a.4y(b,h,11)}6 A(a,b){K c=e.1Y.2j,d=N;I(c==N){c={};O(K h 2g e.1U){K g=e.1U[h];d=g.4x;I(d!=N){g.1V=h.4w();O(g=0;g<d.L;g++)c[d[g]]=h}}e.1Y.2j=c}d=e.1U[c[a]];d==N&&b!=11&&1P.1X(e.13.1x.1X+(e.13.1x.3E+a));H d}6 v(a,b){O(K c=a.1e("\\n"),d=0;d<c.L;d++)c[d]=b(c[d],d);H c.1K("\\n")}6 u(a,b){I(a==N||a.L==0||a=="\\n")H a;a=a.Q(/</g,"&1y;");a=a.Q(/ {2,}/g,6(c){O(K d="",h=0;h<c.L-1;h++)d+=e.13.1W;H d+" "});I(b!=N)a=v(a,6(c){I(c.L==0)H"";K d="";c=c.Q(/^(&2s;| )+/,6(h){d=h;H""});I(c.L==0)H d;H d+\'<17 1g="\'+b+\'">\'+c+"</17>"});H a}6 n(a,b){a.1e("\\n");O(K c="",d=0;d<50;d++)c+=" ";H a=v(a,6(h){I(h.1i("\\t")==-1)H h;O(K g=0;(g=h.1i("\\t"))!=-1;)h=h.1o(0,g)+c.1o(0,b-g%b)+h.1o(g+1,h.L);H h})}6 x(a){H a.Q(/^\\s+|\\s+$/g,"")}6 D(a,b){I(a.P<b.P)H-1;Y I(a.P>b.P)H 1;Y I(a.L<b.L)H-1;Y I(a.L>b.L)H 1;H 0}6 y(a,b){6 c(k){H k[0]}O(K d=N,h=[],g=b.2D?b.2D:c;(d=b.1I.X(a))!=N;){K i=g(d,b);I(1j i=="3f")i=[1f e.2L(i,d.P,b.23)];h=h.1O(i)}H h}6 E(a){K b=/(.*)((&1G;|&1y;).*)/;H a.Q(e.3A.3M,6(c){K d="",h=N;I(h=b.X(c)){c=h[1];d=h[2]}H\'<a 2h="\'+c+\'">\'+c+"</a>"+d})}6 z(){O(K a=1E.36("1k"),b=[],c=0;c<a.L;c++)a[c].3s=="20"&&b.U(a[c]);H b}6 f(a){a=a.1F;K b=p(a,".20",R);a=p(a,".3O",R);K c=1E.4i("3t");I(!(!a||!b||p(a,"3t"))){B(b.1c);r(b,"1m");O(K d=a.3G,h=[],g=0;g<d.L;g++)h.U(d[g].4z||d[g].4A);h=h.1K("\\r");c.39(1E.4D(h));a.39(c);c.2C();c.4C();w(c,"4u",6(){c.2G.4E(c);b.1l=b.1l.Q("1m","")})}}I(1j 3F!="1d"&&1j M=="1d")M=3F("M").M;K e={2v:{"1g-27":"","2i-1s":1,"2z-1s-2t":11,1M:N,1t:N,"42-45":R,"43-22":4,1u:R,16:R,"3V-17":R,2l:11,"41-40":R,2k:11,"1z-1k":11},13:{1W:"&2s;",2M:R,46:11,44:11,34:"4n",1x:{21:"4o 1m",2P:"?",1X:"1v\\n\\n",3E:"4r\'t 4t 1D O: ",4g:"4m 4B\'t 51 O 1z-1k 4F: ",37:\'<!4T 1z 4S "-//4V//3H 4W 1.0 4Z//4Y" "1Z://2y.3L.3K/4X/3I/3H/3I-4P.4J"><1z 4I="1Z://2y.3L.3K/4L/5L"><3J><4N 1Z-4M="5G-5M" 6K="2O/1z; 6J=6I-8" /><1t>6L 1v</1t></3J><3B 1L="25-6M:6Q,6P,6O,6N-6F;6y-2f:#6x;2f:#6w;25-22:6v;2O-3D:3C;"><T 1L="2O-3D:3C;3w-32:1.6z;"><T 1L="25-22:6A-6E;">1v</T><T 1L="25-22:.6C;3w-6B:6R;"><T>3v 3.0.76 (72 73 3x)</T><T><a 2h="1Z://3u.2w/1v" 1F="38" 1L="2f:#3y">1Z://3u.2w/1v</a></T><T>70 17 6U 71.</T><T>6T 6X-3x 6Y 6D.</T></T><T>6t 61 60 J 1k, 5Z <a 2h="6u://2y.62.2w/63-66/65?64=5X-5W&5P=5O" 1L="2f:#3y">5R</a> 5V <2R/>5U 5T 5S!</T></T></3B></1z>\'}},1Y:{2j:N,2A:{}},1U:{},3A:{6n:/\\/\\*[\\s\\S]*?\\*\\//2c,6m:/\\/\\/.*$/2c,6l:/#.*$/2c,6k:/"([^\\\\"\\n]|\\\\.)*"/g,6o:/\'([^\\\\\'\\n]|\\\\.)*\'/g,6p:1f M(\'"([^\\\\\\\\"]|\\\\\\\\.)*"\',"3z"),6s:1f M("\'([^\\\\\\\\\']|\\\\\\\\.)*\'","3z"),6q:/(&1y;|<)!--[\\s\\S]*?--(&1G;|>)/2c,3M:/\\w+:\\/\\/[\\w-.\\/?%&=:@;]*/g,6a:{18:/(&1y;|<)\\?=?/g,1b:/\\?(&1G;|>)/g},69:{18:/(&1y;|<)%=?/g,1b:/%(&1G;|>)/g},6d:{18:/(&1y;|<)\\s*1k.*?(&1G;|>)/2T,1b:/(&1y;|<)\\/\\s*1k\\s*(&1G;|>)/2T}},16:{1H:6(a){6 b(i,k){H e.16.2o(i,k,e.13.1x[k])}O(K c=\'<T 1g="16">\',d=e.16.2x,h=d.2X,g=0;g<h.L;g++)c+=(d[h[g]].1H||b)(a,h[g]);c+="</T>";H c},2o:6(a,b,c){H\'<2W><a 2h="#" 1g="6e 6h\'+b+" "+b+\'">\'+c+"</a></2W>"},2b:6(a){K b=a.1F,c=b.1l||"";b=B(p(b,".20",R).1c);K d=6(h){H(h=15(h+"6f(\\\\w+)").X(c))?h[1]:N}("6g");b&&d&&e.16.2x[d].2B(b);a.3N()},2x:{2X:["21","2P"],21:{1H:6(a){I(a.V("2l")!=R)H"";K b=a.V("1t");H e.16.2o(a,"21",b?b:e.13.1x.21)},2B:6(a){a=1E.6j(t(a.1c));a.1l=a.1l.Q("47","")}},2P:{2B:6(){K a="68=0";a+=", 18="+(31.30-33)/2+", 32="+(31.2Z-2Y)/2+", 30=33, 2Z=2Y";a=a.Q(/^,/,"");a=1P.6Z("","38",a);a.2C();K b=a.1E;b.6W(e.13.1x.37);b.6V();a.2C()}}}},35:6(a,b){K c;I(b)c=[b];Y{c=1E.36(e.13.34);O(K d=[],h=0;h<c.L;h++)d.U(c[h]);c=d}c=c;d=[];I(e.13.2M)c=c.1O(z());I(c.L===0)H d;O(h=0;h<c.L;h++){O(K g=c[h],i=a,k=c[h].1l,j=3W 0,l={},m=1f M("^\\\\[(?<2V>(.*?))\\\\]$"),s=1f M("(?<27>[\\\\w-]+)\\\\s*:\\\\s*(?<1T>[\\\\w-%#]+|\\\\[.*?\\\\]|\\".*?\\"|\'.*?\')\\\\s*;?","g");(j=s.X(k))!=N;){K o=j.1T.Q(/^[\'"]|[\'"]$/g,"");I(o!=N&&m.1A(o)){o=m.X(o);o=o.2V.L>0?o.2V.1e(/\\s*,\\s*/):[]}l[j.27]=o}g={1F:g,1n:C(i,l)};g.1n.1D!=N&&d.U(g)}H d},1M:6(a,b){K c=J.35(a,b),d=N,h=e.13;I(c.L!==0)O(K g=0;g<c.L;g++){b=c[g];K i=b.1F,k=b.1n,j=k.1D,l;I(j!=N){I(k["1z-1k"]=="R"||e.2v["1z-1k"]==R){d=1f e.4l(j);j="4O"}Y I(d=A(j))d=1f d;Y 6H;l=i.3X;I(h.2M){l=l;K m=x(l),s=11;I(m.1i("<![6G[")==0){m=m.4h(9);s=R}K o=m.L;I(m.1i("]]\\>")==o-3){m=m.4h(0,o-3);s=R}l=s?m:l}I((i.1t||"")!="")k.1t=i.1t;k.1D=j;d.2Q(k);b=d.2F(l);I((i.1c||"")!="")b.1c=i.1c;i.2G.74(b,i)}}},2E:6(a){w(1P,"4k",6(){e.1M(a)})}};e.2E=e.2E;e.1M=e.1M;e.2L=6(a,b,c){J.1T=a;J.P=b;J.L=a.L;J.23=c;J.1V=N};e.2L.Z.1q=6(){H J.1T};e.4l=6(a){6 b(j,l){O(K m=0;m<j.L;m++)j[m].P+=l}K c=A(a),d,h=1f e.1U.5Y,g=J,i="2F 1H 2Q".1e(" ");I(c!=N){d=1f c;O(K k=0;k<i.L;k++)(6(){K j=i[k];g[j]=6(){H h[j].1p(h,14)}})();d.28==N?1P.1X(e.13.1x.1X+(e.13.1x.4g+a)):h.2J.U({1I:d.28.17,2D:6(j){O(K l=j.17,m=[],s=d.2J,o=j.P+j.18.L,F=d.28,q,G=0;G<s.L;G++){q=y(l,s[G]);b(q,o);m=m.1O(q)}I(F.18!=N&&j.18!=N){q=y(j.18,F.18);b(q,j.P);m=m.1O(q)}I(F.1b!=N&&j.1b!=N){q=y(j.1b,F.1b);b(q,j.P+j[0].5Q(j.1b));m=m.1O(q)}O(j=0;j<m.L;j++)m[j].1V=c.1V;H m}})}};e.4j=6(){};e.4j.Z={V:6(a,b){K c=J.1n[a];c=c==N?b:c;K d={"R":R,"11":11}[c];H d==N?c:d},3Y:6(a){H 1E.4i(a)},4c:6(a,b){K c=[];I(a!=N)O(K d=0;d<a.L;d++)I(1j a[d]=="2m")c=c.1O(y(b,a[d]));H J.4e(c.6b(D))},4e:6(a){O(K b=0;b<a.L;b++)I(a[b]!==N)O(K c=a[b],d=c.P+c.L,h=b+1;h<a.L&&a[b]!==N;h++){K g=a[h];I(g!==N)I(g.P>d)1N;Y I(g.P==c.P&&g.L>c.L)a[b]=N;Y I(g.P>=c.P&&g.P<d)a[h]=N}H a},4d:6(a){K b=[],c=2u(J.V("2i-1s"));v(a,6(d,h){b.U(h+c)});H b},3U:6(a){K b=J.V("1M",[]);I(1j b!="2m"&&b.U==N)b=[b];a:{a=a.1q();K c=3W 0;O(c=c=1Q.6c(c||0,0);c<b.L;c++)I(b[c]==a){b=c;1N a}b=-1}H b!=-1},2r:6(a,b,c){a=["1s","6i"+b,"P"+a,"6r"+(b%2==0?1:2).1q()];J.3U(b)&&a.U("67");b==0&&a.U("1N");H\'<T 1g="\'+a.1K(" ")+\'">\'+c+"</T>"},3Q:6(a,b){K c="",d=a.1e("\\n").L,h=2u(J.V("2i-1s")),g=J.V("2z-1s-2t");I(g==R)g=(h+d-1).1q().L;Y I(3R(g)==R)g=0;O(K i=0;i<d;i++){K k=b?b[i]:h+i,j;I(k==0)j=e.13.1W;Y{j=g;O(K l=k.1q();l.L<j;)l="0"+l;j=l}a=j;c+=J.2r(i,k,a)}H c},49:6(a,b){a=x(a);K c=a.1e("\\n");J.V("2z-1s-2t");K d=2u(J.V("2i-1s"));a="";O(K h=J.V("1D"),g=0;g<c.L;g++){K i=c[g],k=/^(&2s;|\\s)+/.X(i),j=N,l=b?b[g]:d+g;I(k!=N){j=k[0].1q();i=i.1o(j.L);j=j.Q(" ",e.13.1W)}i=x(i);I(i.L==0)i=e.13.1W;a+=J.2r(g,l,(j!=N?\'<17 1g="\'+h+\' 5N">\'+j+"</17>":"")+i)}H a},4f:6(a){H a?"<4a>"+a+"</4a>":""},4b:6(a,b){6 c(l){H(l=l?l.1V||g:g)?l+" ":""}O(K d=0,h="",g=J.V("1D",""),i=0;i<b.L;i++){K k=b[i],j;I(!(k===N||k.L===0)){j=c(k);h+=u(a.1o(d,k.P-d),j+"48")+u(k.1T,j+k.23);d=k.P+k.L+(k.75||0)}}h+=u(a.1o(d),c()+"48");H h},1H:6(a){K b="",c=["20"],d;I(J.V("2k")==R)J.1n.16=J.1n.1u=11;1l="20";J.V("2l")==R&&c.U("47");I((1u=J.V("1u"))==11)c.U("6S");c.U(J.V("1g-27"));c.U(J.V("1D"));a=a.Q(/^[ ]*[\\n]+|[\\n]*[ ]*$/g,"").Q(/\\r/g," ");b=J.V("43-22");I(J.V("42-45")==R)a=n(a,b);Y{O(K h="",g=0;g<b;g++)h+=" ";a=a.Q(/\\t/g,h)}a=a;a:{b=a=a;h=/<2R\\s*\\/?>|&1y;2R\\s*\\/?&1G;/2T;I(e.13.46==R)b=b.Q(h,"\\n");I(e.13.44==R)b=b.Q(h,"");b=b.1e("\\n");h=/^\\s*/;g=4Q;O(K i=0;i<b.L&&g>0;i++){K k=b[i];I(x(k).L!=0){k=h.X(k);I(k==N){a=a;1N a}g=1Q.4q(k[0].L,g)}}I(g>0)O(i=0;i<b.L;i++)b[i]=b[i].1o(g);a=b.1K("\\n")}I(1u)d=J.4d(a);b=J.4c(J.2J,a);b=J.4b(a,b);b=J.49(b,d);I(J.V("41-40"))b=E(b);1j 2H!="1d"&&2H.3S&&2H.3S.1C(/5s/)&&c.U("5t");H b=\'<T 1c="\'+t(J.1c)+\'" 1g="\'+c.1K(" ")+\'">\'+(J.V("16")?e.16.1H(J):"")+\'<3Z 5z="0" 5H="0" 5J="0">\'+J.4f(J.V("1t"))+"<3T><3P>"+(1u?\'<2d 1g="1u">\'+J.3Q(a)+"</2d>":"")+\'<2d 1g="17"><T 1g="3O">\'+b+"</T></2d></3P></3T></3Z></T>"},2F:6(a){I(a===N)a="";J.17=a;K b=J.3Y("T");b.3X=J.1H(a);J.V("16")&&w(p(b,".16"),"5c",e.16.2b);J.V("3V-17")&&w(p(b,".17"),"56",f);H b},2Q:6(a){J.1c=""+1Q.5d(1Q.5n()*5k).1q();e.1Y.2A[t(J.1c)]=J;J.1n=C(e.2v,a||{});I(J.V("2k")==R)J.1n.16=J.1n.1u=11},5j:6(a){a=a.Q(/^\\s+|\\s+$/g,"").Q(/\\s+/g,"|");H"\\\\b(?:"+a+")\\\\b"},5f:6(a){J.28={18:{1I:a.18,23:"1k"},1b:{1I:a.1b,23:"1k"},17:1f M("(?<18>"+a.18.1m+")(?<17>.*?)(?<1b>"+a.1b.1m+")","5o")}}};H e}();1j 2e!="1d"&&(2e.1v=1v);',62,441,'||||||function|||||||||||||||||||||||||||||||||||||return|if|this|var|length|XRegExp|null|for|index|replace|true||div|push|getParam|call|exec|else|prototype||false|lastIndex|config|arguments|RegExp|toolbar|code|left|captureNames|slice|right|id|undefined|split|new|class|addToken|indexOf|typeof|script|className|source|params|substr|apply|toString|String|line|title|gutter|SyntaxHighlighter|_xregexp|strings|lt|html|test|OUTSIDE_CLASS|match|brush|document|target|gt|getHtml|regex|global|join|style|highlight|break|concat|window|Math|isRegExp|throw|value|brushes|brushName|space|alert|vars|http|syntaxhighlighter|expandSource|size|css|case|font|Fa|name|htmlScript|dA|can|handler|gm|td|exports|color|in|href|first|discoveredBrushes|light|collapse|object|cache|getButtonHtml|trigger|pattern|getLineHtml|nbsp|numbers|parseInt|defaults|com|items|www|pad|highlighters|execute|focus|func|all|getDiv|parentNode|navigator|INSIDE_CLASS|regexList|hasFlag|Match|useScriptTags|hasNamedCapture|text|help|init|br|input|gi|Error|values|span|list|250|height|width|screen|top|500|tagName|findElements|getElementsByTagName|aboutDialog|_blank|appendChild|charAt|Array|copyAsGlobal|setFlag|highlighter_|string|attachEvent|nodeName|floor|backref|output|the|TypeError|sticky|Za|iterate|freezeTokens|scope|type|textarea|alexgorbatchev|version|margin|2010|005896|gs|regexLib|body|center|align|noBrush|require|childNodes|DTD|xhtml1|head|org|w3|url|preventDefault|container|tr|getLineNumbersHtml|isNaN|userAgent|tbody|isLineHighlighted|quick|void|innerHTML|create|table|links|auto|smart|tab|stripBrs|tabs|bloggerMode|collapsed|plain|getCodeLinesHtml|caption|getMatchesHtml|findMatches|figureOutLineNumbers|removeNestedMatches|getTitleHtml|brushNotHtmlScript|substring|createElement|Highlighter|load|HtmlScript|Brush|pre|expand|multiline|min|Can|ignoreCase|find|blur|extended|toLowerCase|aliases|addEventListener|innerText|textContent|wasn|select|createTextNode|removeChild|option|same|frame|xmlns|dtd|twice|1999|equiv|meta|htmlscript|transitional|1E3|expected|PUBLIC|DOCTYPE|on|W3C|XHTML|TR|EN|Transitional||configured|srcElement|Object|after|run|dblclick|matchChain|valueOf|constructor|default|switch|click|round|execAt|forHtmlScript|token|gimy|functions|getKeywords|1E6|escape|within|random|sgi|another|finally|supply|MSIE|ie|toUpperCase|catch|returnValue|definition|event|border|imsx|constructing|one|Infinity|from|when|Content|cellpadding|flags|cellspacing|try|xhtml|Type|spaces|2930402|hosted_button_id|lastIndexOf|donate|active|development|keep|to|xclick|_s|Xml|please|like|you|paypal|cgi|cmd|webscr|bin|highlighted|scrollbars|aspScriptTags|phpScriptTags|sort|max|scriptScriptTags|toolbar_item|_|command|command_|number|getElementById|doubleQuotedString|singleLinePerlComments|singleLineCComments|multiLineCComments|singleQuotedString|multiLineDoubleQuotedString|xmlComments|alt|multiLineSingleQuotedString|If|https|1em|000|fff|background|5em|xx|bottom|75em|Gorbatchev|large|serif|CDATA|continue|utf|charset|content|About|family|sans|Helvetica|Arial|Geneva|3em|nogutter|Copyright|syntax|close|write|2004|Alex|open|JavaScript|highlighter|July|02|replaceChild|offset|83'.split('|'),0,{}))
diff --git a/guides/assets/stylesheets/syntaxhighlighter/shCoreDefault.css b/guides/assets/stylesheets/syntaxhighlighter/shCoreDefault.css
deleted file mode 100644
index 08f9e10e4e..0000000000
--- a/guides/assets/stylesheets/syntaxhighlighter/shCoreDefault.css
+++ /dev/null
@@ -1,328 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- *
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-.syntaxhighlighter a,
-.syntaxhighlighter div,
-.syntaxhighlighter code,
-.syntaxhighlighter table,
-.syntaxhighlighter table td,
-.syntaxhighlighter table tr,
-.syntaxhighlighter table tbody,
-.syntaxhighlighter table thead,
-.syntaxhighlighter table caption,
-.syntaxhighlighter textarea {
- -moz-border-radius: 0 0 0 0 !important;
- -webkit-border-radius: 0 0 0 0 !important;
- background: none !important;
- border: 0 !important;
- bottom: auto !important;
- float: none !important;
- height: auto !important;
- left: auto !important;
- line-height: 1.1em !important;
- margin: 0 !important;
- outline: 0 !important;
- overflow: visible !important;
- padding: 0 !important;
- position: static !important;
- right: auto !important;
- text-align: left !important;
- top: auto !important;
- vertical-align: baseline !important;
- width: auto !important;
- box-sizing: content-box !important;
- font-family: "Consolas", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace !important;
- font-weight: normal !important;
- font-style: normal !important;
- font-size: 1em !important;
- min-height: inherit !important;
- min-height: auto !important;
-}
-
-.syntaxhighlighter {
- width: 100% !important;
- margin: 1em 0 1em 0 !important;
- position: relative !important;
- overflow: auto !important;
- font-size: 1em !important;
-}
-.syntaxhighlighter.source {
- overflow: hidden !important;
-}
-.syntaxhighlighter .bold {
- font-weight: bold !important;
-}
-.syntaxhighlighter .italic {
- font-style: italic !important;
-}
-.syntaxhighlighter .line {
- white-space: pre !important;
-}
-.syntaxhighlighter table {
- width: 100% !important;
-}
-.syntaxhighlighter table caption {
- text-align: left !important;
- padding: .5em 0 0.5em 1em !important;
-}
-.syntaxhighlighter table td.code {
- width: 100% !important;
-}
-.syntaxhighlighter table td.code .container {
- position: relative !important;
-}
-.syntaxhighlighter table td.code .container textarea {
- box-sizing: border-box !important;
- position: absolute !important;
- left: 0 !important;
- top: 0 !important;
- width: 100% !important;
- height: 100% !important;
- border: none !important;
- background: white !important;
- padding-left: 1em !important;
- overflow: hidden !important;
- white-space: pre !important;
-}
-.syntaxhighlighter table td.gutter .line {
- text-align: right !important;
- padding: 0 0.5em 0 1em !important;
-}
-.syntaxhighlighter table td.code .line {
- padding: 0 1em !important;
-}
-.syntaxhighlighter.nogutter td.code .container textarea, .syntaxhighlighter.nogutter td.code .line {
- padding-left: 0em !important;
-}
-.syntaxhighlighter.show {
- display: block !important;
-}
-.syntaxhighlighter.collapsed table {
- display: none !important;
-}
-.syntaxhighlighter.collapsed .toolbar {
- padding: 0.1em 0.8em 0em 0.8em !important;
- font-size: 1em !important;
- position: static !important;
- width: auto !important;
- height: auto !important;
-}
-.syntaxhighlighter.collapsed .toolbar span {
- display: inline !important;
- margin-right: 1em !important;
-}
-.syntaxhighlighter.collapsed .toolbar span a {
- padding: 0 !important;
- display: none !important;
-}
-.syntaxhighlighter.collapsed .toolbar span a.expandSource {
- display: inline !important;
-}
-.syntaxhighlighter .toolbar {
- position: absolute !important;
- right: 1px !important;
- top: 1px !important;
- width: 11px !important;
- height: 11px !important;
- font-size: 10px !important;
- z-index: 10 !important;
-}
-.syntaxhighlighter .toolbar span.title {
- display: inline !important;
-}
-.syntaxhighlighter .toolbar a {
- display: block !important;
- text-align: center !important;
- text-decoration: none !important;
- padding-top: 1px !important;
-}
-.syntaxhighlighter .toolbar a.expandSource {
- display: none !important;
-}
-.syntaxhighlighter.ie {
- font-size: .9em !important;
- padding: 1px 0 1px 0 !important;
-}
-.syntaxhighlighter.ie .toolbar {
- line-height: 8px !important;
-}
-.syntaxhighlighter.ie .toolbar a {
- padding-top: 0px !important;
-}
-.syntaxhighlighter.printing .line.alt1 .content,
-.syntaxhighlighter.printing .line.alt2 .content,
-.syntaxhighlighter.printing .line.highlighted .number,
-.syntaxhighlighter.printing .line.highlighted.alt1 .content,
-.syntaxhighlighter.printing .line.highlighted.alt2 .content {
- background: none !important;
-}
-.syntaxhighlighter.printing .line .number {
- color: #bbbbbb !important;
-}
-.syntaxhighlighter.printing .line .content {
- color: black !important;
-}
-.syntaxhighlighter.printing .toolbar {
- display: none !important;
-}
-.syntaxhighlighter.printing a {
- text-decoration: none !important;
-}
-.syntaxhighlighter.printing .plain, .syntaxhighlighter.printing .plain a {
- color: black !important;
-}
-.syntaxhighlighter.printing .comments, .syntaxhighlighter.printing .comments a {
- color: #008200 !important;
-}
-.syntaxhighlighter.printing .string, .syntaxhighlighter.printing .string a {
- color: blue !important;
-}
-.syntaxhighlighter.printing .keyword {
- color: #006699 !important;
- font-weight: bold !important;
-}
-.syntaxhighlighter.printing .preprocessor {
- color: gray !important;
-}
-.syntaxhighlighter.printing .variable {
- color: #aa7700 !important;
-}
-.syntaxhighlighter.printing .value {
- color: #009900 !important;
-}
-.syntaxhighlighter.printing .functions {
- color: #ff1493 !important;
-}
-.syntaxhighlighter.printing .constants {
- color: #0066cc !important;
-}
-.syntaxhighlighter.printing .script {
- font-weight: bold !important;
-}
-.syntaxhighlighter.printing .color1, .syntaxhighlighter.printing .color1 a {
- color: gray !important;
-}
-.syntaxhighlighter.printing .color2, .syntaxhighlighter.printing .color2 a {
- color: #ff1493 !important;
-}
-.syntaxhighlighter.printing .color3, .syntaxhighlighter.printing .color3 a {
- color: red !important;
-}
-.syntaxhighlighter.printing .break, .syntaxhighlighter.printing .break a {
- color: black !important;
-}
-
-.syntaxhighlighter {
- background-color: white !important;
-}
-.syntaxhighlighter .line.alt1 {
- background-color: white !important;
-}
-.syntaxhighlighter .line.alt2 {
- background-color: white !important;
-}
-.syntaxhighlighter .line.highlighted.alt1, .syntaxhighlighter .line.highlighted.alt2 {
- background-color: #e0e0e0 !important;
-}
-.syntaxhighlighter .line.highlighted.number {
- color: black !important;
-}
-.syntaxhighlighter table caption {
- color: black !important;
-}
-.syntaxhighlighter .gutter {
- color: #afafaf !important;
-}
-.syntaxhighlighter .gutter .line {
- border-right: 3px solid #6ce26c !important;
-}
-.syntaxhighlighter .gutter .line.highlighted {
- background-color: #6ce26c !important;
- color: white !important;
-}
-.syntaxhighlighter.printing .line .content {
- border: none !important;
-}
-.syntaxhighlighter.collapsed {
- overflow: visible !important;
-}
-.syntaxhighlighter.collapsed .toolbar {
- color: blue !important;
- background: white !important;
- border: 1px solid #6ce26c !important;
-}
-.syntaxhighlighter.collapsed .toolbar a {
- color: blue !important;
-}
-.syntaxhighlighter.collapsed .toolbar a:hover {
- color: red !important;
-}
-.syntaxhighlighter .toolbar {
- color: white !important;
- background: #6ce26c !important;
- border: none !important;
-}
-.syntaxhighlighter .toolbar a {
- color: white !important;
-}
-.syntaxhighlighter .toolbar a:hover {
- color: black !important;
-}
-.syntaxhighlighter .plain, .syntaxhighlighter .plain a {
- color: black !important;
-}
-.syntaxhighlighter .comments, .syntaxhighlighter .comments a {
- color: #008200 !important;
-}
-.syntaxhighlighter .string, .syntaxhighlighter .string a {
- color: blue !important;
-}
-.syntaxhighlighter .keyword {
- color: #006699 !important;
-}
-.syntaxhighlighter .preprocessor {
- color: gray !important;
-}
-.syntaxhighlighter .variable {
- color: #aa7700 !important;
-}
-.syntaxhighlighter .value {
- color: #009900 !important;
-}
-.syntaxhighlighter .functions {
- color: #ff1493 !important;
-}
-.syntaxhighlighter .constants {
- color: #0066cc !important;
-}
-.syntaxhighlighter .script {
- font-weight: bold !important;
- color: #006699 !important;
- background-color: none !important;
-}
-.syntaxhighlighter .color1, .syntaxhighlighter .color1 a {
- color: gray !important;
-}
-.syntaxhighlighter .color2, .syntaxhighlighter .color2 a {
- color: #ff1493 !important;
-}
-.syntaxhighlighter .color3, .syntaxhighlighter .color3 a {
- color: red !important;
-}
-
-.syntaxhighlighter .keyword {
- font-weight: bold !important;
-}
diff --git a/guides/assets/stylesheets/syntaxhighlighter/shCoreDjango.css b/guides/assets/stylesheets/syntaxhighlighter/shCoreDjango.css
deleted file mode 100644
index 1db1f70cb0..0000000000
--- a/guides/assets/stylesheets/syntaxhighlighter/shCoreDjango.css
+++ /dev/null
@@ -1,331 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- *
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-.syntaxhighlighter a,
-.syntaxhighlighter div,
-.syntaxhighlighter code,
-.syntaxhighlighter table,
-.syntaxhighlighter table td,
-.syntaxhighlighter table tr,
-.syntaxhighlighter table tbody,
-.syntaxhighlighter table thead,
-.syntaxhighlighter table caption,
-.syntaxhighlighter textarea {
- -moz-border-radius: 0 0 0 0 !important;
- -webkit-border-radius: 0 0 0 0 !important;
- background: none !important;
- border: 0 !important;
- bottom: auto !important;
- float: none !important;
- height: auto !important;
- left: auto !important;
- line-height: 1.1em !important;
- margin: 0 !important;
- outline: 0 !important;
- overflow: visible !important;
- padding: 0 !important;
- position: static !important;
- right: auto !important;
- text-align: left !important;
- top: auto !important;
- vertical-align: baseline !important;
- width: auto !important;
- box-sizing: content-box !important;
- font-family: "Consolas", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace !important;
- font-weight: normal !important;
- font-style: normal !important;
- font-size: 1em !important;
- min-height: inherit !important;
- min-height: auto !important;
-}
-
-.syntaxhighlighter {
- width: 100% !important;
- margin: 1em 0 1em 0 !important;
- position: relative !important;
- overflow: auto !important;
- font-size: 1em !important;
-}
-.syntaxhighlighter.source {
- overflow: hidden !important;
-}
-.syntaxhighlighter .bold {
- font-weight: bold !important;
-}
-.syntaxhighlighter .italic {
- font-style: italic !important;
-}
-.syntaxhighlighter .line {
- white-space: pre !important;
-}
-.syntaxhighlighter table {
- width: 100% !important;
-}
-.syntaxhighlighter table caption {
- text-align: left !important;
- padding: .5em 0 0.5em 1em !important;
-}
-.syntaxhighlighter table td.code {
- width: 100% !important;
-}
-.syntaxhighlighter table td.code .container {
- position: relative !important;
-}
-.syntaxhighlighter table td.code .container textarea {
- box-sizing: border-box !important;
- position: absolute !important;
- left: 0 !important;
- top: 0 !important;
- width: 100% !important;
- height: 100% !important;
- border: none !important;
- background: white !important;
- padding-left: 1em !important;
- overflow: hidden !important;
- white-space: pre !important;
-}
-.syntaxhighlighter table td.gutter .line {
- text-align: right !important;
- padding: 0 0.5em 0 1em !important;
-}
-.syntaxhighlighter table td.code .line {
- padding: 0 1em !important;
-}
-.syntaxhighlighter.nogutter td.code .container textarea, .syntaxhighlighter.nogutter td.code .line {
- padding-left: 0em !important;
-}
-.syntaxhighlighter.show {
- display: block !important;
-}
-.syntaxhighlighter.collapsed table {
- display: none !important;
-}
-.syntaxhighlighter.collapsed .toolbar {
- padding: 0.1em 0.8em 0em 0.8em !important;
- font-size: 1em !important;
- position: static !important;
- width: auto !important;
- height: auto !important;
-}
-.syntaxhighlighter.collapsed .toolbar span {
- display: inline !important;
- margin-right: 1em !important;
-}
-.syntaxhighlighter.collapsed .toolbar span a {
- padding: 0 !important;
- display: none !important;
-}
-.syntaxhighlighter.collapsed .toolbar span a.expandSource {
- display: inline !important;
-}
-.syntaxhighlighter .toolbar {
- position: absolute !important;
- right: 1px !important;
- top: 1px !important;
- width: 11px !important;
- height: 11px !important;
- font-size: 10px !important;
- z-index: 10 !important;
-}
-.syntaxhighlighter .toolbar span.title {
- display: inline !important;
-}
-.syntaxhighlighter .toolbar a {
- display: block !important;
- text-align: center !important;
- text-decoration: none !important;
- padding-top: 1px !important;
-}
-.syntaxhighlighter .toolbar a.expandSource {
- display: none !important;
-}
-.syntaxhighlighter.ie {
- font-size: .9em !important;
- padding: 1px 0 1px 0 !important;
-}
-.syntaxhighlighter.ie .toolbar {
- line-height: 8px !important;
-}
-.syntaxhighlighter.ie .toolbar a {
- padding-top: 0px !important;
-}
-.syntaxhighlighter.printing .line.alt1 .content,
-.syntaxhighlighter.printing .line.alt2 .content,
-.syntaxhighlighter.printing .line.highlighted .number,
-.syntaxhighlighter.printing .line.highlighted.alt1 .content,
-.syntaxhighlighter.printing .line.highlighted.alt2 .content {
- background: none !important;
-}
-.syntaxhighlighter.printing .line .number {
- color: #bbbbbb !important;
-}
-.syntaxhighlighter.printing .line .content {
- color: black !important;
-}
-.syntaxhighlighter.printing .toolbar {
- display: none !important;
-}
-.syntaxhighlighter.printing a {
- text-decoration: none !important;
-}
-.syntaxhighlighter.printing .plain, .syntaxhighlighter.printing .plain a {
- color: black !important;
-}
-.syntaxhighlighter.printing .comments, .syntaxhighlighter.printing .comments a {
- color: #008200 !important;
-}
-.syntaxhighlighter.printing .string, .syntaxhighlighter.printing .string a {
- color: blue !important;
-}
-.syntaxhighlighter.printing .keyword {
- color: #006699 !important;
- font-weight: bold !important;
-}
-.syntaxhighlighter.printing .preprocessor {
- color: gray !important;
-}
-.syntaxhighlighter.printing .variable {
- color: #aa7700 !important;
-}
-.syntaxhighlighter.printing .value {
- color: #009900 !important;
-}
-.syntaxhighlighter.printing .functions {
- color: #ff1493 !important;
-}
-.syntaxhighlighter.printing .constants {
- color: #0066cc !important;
-}
-.syntaxhighlighter.printing .script {
- font-weight: bold !important;
-}
-.syntaxhighlighter.printing .color1, .syntaxhighlighter.printing .color1 a {
- color: gray !important;
-}
-.syntaxhighlighter.printing .color2, .syntaxhighlighter.printing .color2 a {
- color: #ff1493 !important;
-}
-.syntaxhighlighter.printing .color3, .syntaxhighlighter.printing .color3 a {
- color: red !important;
-}
-.syntaxhighlighter.printing .break, .syntaxhighlighter.printing .break a {
- color: black !important;
-}
-
-.syntaxhighlighter {
- background-color: #0a2b1d !important;
-}
-.syntaxhighlighter .line.alt1 {
- background-color: #0a2b1d !important;
-}
-.syntaxhighlighter .line.alt2 {
- background-color: #0a2b1d !important;
-}
-.syntaxhighlighter .line.highlighted.alt1, .syntaxhighlighter .line.highlighted.alt2 {
- background-color: #233729 !important;
-}
-.syntaxhighlighter .line.highlighted.number {
- color: white !important;
-}
-.syntaxhighlighter table caption {
- color: #f8f8f8 !important;
-}
-.syntaxhighlighter .gutter {
- color: #497958 !important;
-}
-.syntaxhighlighter .gutter .line {
- border-right: 3px solid #41a83e !important;
-}
-.syntaxhighlighter .gutter .line.highlighted {
- background-color: #41a83e !important;
- color: #0a2b1d !important;
-}
-.syntaxhighlighter.printing .line .content {
- border: none !important;
-}
-.syntaxhighlighter.collapsed {
- overflow: visible !important;
-}
-.syntaxhighlighter.collapsed .toolbar {
- color: #96dd3b !important;
- background: black !important;
- border: 1px solid #41a83e !important;
-}
-.syntaxhighlighter.collapsed .toolbar a {
- color: #96dd3b !important;
-}
-.syntaxhighlighter.collapsed .toolbar a:hover {
- color: white !important;
-}
-.syntaxhighlighter .toolbar {
- color: white !important;
- background: #41a83e !important;
- border: none !important;
-}
-.syntaxhighlighter .toolbar a {
- color: white !important;
-}
-.syntaxhighlighter .toolbar a:hover {
- color: #ffe862 !important;
-}
-.syntaxhighlighter .plain, .syntaxhighlighter .plain a {
- color: #f8f8f8 !important;
-}
-.syntaxhighlighter .comments, .syntaxhighlighter .comments a {
- color: #336442 !important;
-}
-.syntaxhighlighter .string, .syntaxhighlighter .string a {
- color: #9df39f !important;
-}
-.syntaxhighlighter .keyword {
- color: #96dd3b !important;
-}
-.syntaxhighlighter .preprocessor {
- color: #91bb9e !important;
-}
-.syntaxhighlighter .variable {
- color: #ffaa3e !important;
-}
-.syntaxhighlighter .value {
- color: #f7e741 !important;
-}
-.syntaxhighlighter .functions {
- color: #ffaa3e !important;
-}
-.syntaxhighlighter .constants {
- color: #e0e8ff !important;
-}
-.syntaxhighlighter .script {
- font-weight: bold !important;
- color: #96dd3b !important;
- background-color: none !important;
-}
-.syntaxhighlighter .color1, .syntaxhighlighter .color1 a {
- color: #eb939a !important;
-}
-.syntaxhighlighter .color2, .syntaxhighlighter .color2 a {
- color: #91bb9e !important;
-}
-.syntaxhighlighter .color3, .syntaxhighlighter .color3 a {
- color: #edef7d !important;
-}
-
-.syntaxhighlighter .comments {
- font-style: italic !important;
-}
-.syntaxhighlighter .keyword {
- font-weight: bold !important;
-}
diff --git a/guides/assets/stylesheets/syntaxhighlighter/shCoreEclipse.css b/guides/assets/stylesheets/syntaxhighlighter/shCoreEclipse.css
deleted file mode 100644
index a45de9fd8e..0000000000
--- a/guides/assets/stylesheets/syntaxhighlighter/shCoreEclipse.css
+++ /dev/null
@@ -1,339 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- *
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-.syntaxhighlighter a,
-.syntaxhighlighter div,
-.syntaxhighlighter code,
-.syntaxhighlighter table,
-.syntaxhighlighter table td,
-.syntaxhighlighter table tr,
-.syntaxhighlighter table tbody,
-.syntaxhighlighter table thead,
-.syntaxhighlighter table caption,
-.syntaxhighlighter textarea {
- -moz-border-radius: 0 0 0 0 !important;
- -webkit-border-radius: 0 0 0 0 !important;
- background: none !important;
- border: 0 !important;
- bottom: auto !important;
- float: none !important;
- height: auto !important;
- left: auto !important;
- line-height: 1.1em !important;
- margin: 0 !important;
- outline: 0 !important;
- overflow: visible !important;
- padding: 0 !important;
- position: static !important;
- right: auto !important;
- text-align: left !important;
- top: auto !important;
- vertical-align: baseline !important;
- width: auto !important;
- box-sizing: content-box !important;
- font-family: "Consolas", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace !important;
- font-weight: normal !important;
- font-style: normal !important;
- font-size: 1em !important;
- min-height: inherit !important;
- min-height: auto !important;
-}
-
-.syntaxhighlighter {
- width: 100% !important;
- margin: 1em 0 1em 0 !important;
- position: relative !important;
- overflow: auto !important;
- font-size: 1em !important;
-}
-.syntaxhighlighter.source {
- overflow: hidden !important;
-}
-.syntaxhighlighter .bold {
- font-weight: bold !important;
-}
-.syntaxhighlighter .italic {
- font-style: italic !important;
-}
-.syntaxhighlighter .line {
- white-space: pre !important;
-}
-.syntaxhighlighter table {
- width: 100% !important;
-}
-.syntaxhighlighter table caption {
- text-align: left !important;
- padding: .5em 0 0.5em 1em !important;
-}
-.syntaxhighlighter table td.code {
- width: 100% !important;
-}
-.syntaxhighlighter table td.code .container {
- position: relative !important;
-}
-.syntaxhighlighter table td.code .container textarea {
- box-sizing: border-box !important;
- position: absolute !important;
- left: 0 !important;
- top: 0 !important;
- width: 100% !important;
- height: 100% !important;
- border: none !important;
- background: white !important;
- padding-left: 1em !important;
- overflow: hidden !important;
- white-space: pre !important;
-}
-.syntaxhighlighter table td.gutter .line {
- text-align: right !important;
- padding: 0 0.5em 0 1em !important;
-}
-.syntaxhighlighter table td.code .line {
- padding: 0 1em !important;
-}
-.syntaxhighlighter.nogutter td.code .container textarea, .syntaxhighlighter.nogutter td.code .line {
- padding-left: 0em !important;
-}
-.syntaxhighlighter.show {
- display: block !important;
-}
-.syntaxhighlighter.collapsed table {
- display: none !important;
-}
-.syntaxhighlighter.collapsed .toolbar {
- padding: 0.1em 0.8em 0em 0.8em !important;
- font-size: 1em !important;
- position: static !important;
- width: auto !important;
- height: auto !important;
-}
-.syntaxhighlighter.collapsed .toolbar span {
- display: inline !important;
- margin-right: 1em !important;
-}
-.syntaxhighlighter.collapsed .toolbar span a {
- padding: 0 !important;
- display: none !important;
-}
-.syntaxhighlighter.collapsed .toolbar span a.expandSource {
- display: inline !important;
-}
-.syntaxhighlighter .toolbar {
- position: absolute !important;
- right: 1px !important;
- top: 1px !important;
- width: 11px !important;
- height: 11px !important;
- font-size: 10px !important;
- z-index: 10 !important;
-}
-.syntaxhighlighter .toolbar span.title {
- display: inline !important;
-}
-.syntaxhighlighter .toolbar a {
- display: block !important;
- text-align: center !important;
- text-decoration: none !important;
- padding-top: 1px !important;
-}
-.syntaxhighlighter .toolbar a.expandSource {
- display: none !important;
-}
-.syntaxhighlighter.ie {
- font-size: .9em !important;
- padding: 1px 0 1px 0 !important;
-}
-.syntaxhighlighter.ie .toolbar {
- line-height: 8px !important;
-}
-.syntaxhighlighter.ie .toolbar a {
- padding-top: 0px !important;
-}
-.syntaxhighlighter.printing .line.alt1 .content,
-.syntaxhighlighter.printing .line.alt2 .content,
-.syntaxhighlighter.printing .line.highlighted .number,
-.syntaxhighlighter.printing .line.highlighted.alt1 .content,
-.syntaxhighlighter.printing .line.highlighted.alt2 .content {
- background: none !important;
-}
-.syntaxhighlighter.printing .line .number {
- color: #bbbbbb !important;
-}
-.syntaxhighlighter.printing .line .content {
- color: black !important;
-}
-.syntaxhighlighter.printing .toolbar {
- display: none !important;
-}
-.syntaxhighlighter.printing a {
- text-decoration: none !important;
-}
-.syntaxhighlighter.printing .plain, .syntaxhighlighter.printing .plain a {
- color: black !important;
-}
-.syntaxhighlighter.printing .comments, .syntaxhighlighter.printing .comments a {
- color: #008200 !important;
-}
-.syntaxhighlighter.printing .string, .syntaxhighlighter.printing .string a {
- color: blue !important;
-}
-.syntaxhighlighter.printing .keyword {
- color: #006699 !important;
- font-weight: bold !important;
-}
-.syntaxhighlighter.printing .preprocessor {
- color: gray !important;
-}
-.syntaxhighlighter.printing .variable {
- color: #aa7700 !important;
-}
-.syntaxhighlighter.printing .value {
- color: #009900 !important;
-}
-.syntaxhighlighter.printing .functions {
- color: #ff1493 !important;
-}
-.syntaxhighlighter.printing .constants {
- color: #0066cc !important;
-}
-.syntaxhighlighter.printing .script {
- font-weight: bold !important;
-}
-.syntaxhighlighter.printing .color1, .syntaxhighlighter.printing .color1 a {
- color: gray !important;
-}
-.syntaxhighlighter.printing .color2, .syntaxhighlighter.printing .color2 a {
- color: #ff1493 !important;
-}
-.syntaxhighlighter.printing .color3, .syntaxhighlighter.printing .color3 a {
- color: red !important;
-}
-.syntaxhighlighter.printing .break, .syntaxhighlighter.printing .break a {
- color: black !important;
-}
-
-.syntaxhighlighter {
- background-color: white !important;
-}
-.syntaxhighlighter .line.alt1 {
- background-color: white !important;
-}
-.syntaxhighlighter .line.alt2 {
- background-color: white !important;
-}
-.syntaxhighlighter .line.highlighted.alt1, .syntaxhighlighter .line.highlighted.alt2 {
- background-color: #c3defe !important;
-}
-.syntaxhighlighter .line.highlighted.number {
- color: white !important;
-}
-.syntaxhighlighter table caption {
- color: black !important;
-}
-.syntaxhighlighter .gutter {
- color: #787878 !important;
-}
-.syntaxhighlighter .gutter .line {
- border-right: 3px solid #d4d0c8 !important;
-}
-.syntaxhighlighter .gutter .line.highlighted {
- background-color: #d4d0c8 !important;
- color: white !important;
-}
-.syntaxhighlighter.printing .line .content {
- border: none !important;
-}
-.syntaxhighlighter.collapsed {
- overflow: visible !important;
-}
-.syntaxhighlighter.collapsed .toolbar {
- color: #3f5fbf !important;
- background: white !important;
- border: 1px solid #d4d0c8 !important;
-}
-.syntaxhighlighter.collapsed .toolbar a {
- color: #3f5fbf !important;
-}
-.syntaxhighlighter.collapsed .toolbar a:hover {
- color: #aa7700 !important;
-}
-.syntaxhighlighter .toolbar {
- color: #a0a0a0 !important;
- background: #d4d0c8 !important;
- border: none !important;
-}
-.syntaxhighlighter .toolbar a {
- color: #a0a0a0 !important;
-}
-.syntaxhighlighter .toolbar a:hover {
- color: red !important;
-}
-.syntaxhighlighter .plain, .syntaxhighlighter .plain a {
- color: black !important;
-}
-.syntaxhighlighter .comments, .syntaxhighlighter .comments a {
- color: #3f5fbf !important;
-}
-.syntaxhighlighter .string, .syntaxhighlighter .string a {
- color: #2a00ff !important;
-}
-.syntaxhighlighter .keyword {
- color: #7f0055 !important;
-}
-.syntaxhighlighter .preprocessor {
- color: #646464 !important;
-}
-.syntaxhighlighter .variable {
- color: #aa7700 !important;
-}
-.syntaxhighlighter .value {
- color: #009900 !important;
-}
-.syntaxhighlighter .functions {
- color: #ff1493 !important;
-}
-.syntaxhighlighter .constants {
- color: #0066cc !important;
-}
-.syntaxhighlighter .script {
- font-weight: bold !important;
- color: #7f0055 !important;
- background-color: none !important;
-}
-.syntaxhighlighter .color1, .syntaxhighlighter .color1 a {
- color: gray !important;
-}
-.syntaxhighlighter .color2, .syntaxhighlighter .color2 a {
- color: #ff1493 !important;
-}
-.syntaxhighlighter .color3, .syntaxhighlighter .color3 a {
- color: red !important;
-}
-
-.syntaxhighlighter .keyword {
- font-weight: bold !important;
-}
-.syntaxhighlighter .xml .keyword {
- color: #3f7f7f !important;
- font-weight: normal !important;
-}
-.syntaxhighlighter .xml .color1, .syntaxhighlighter .xml .color1 a {
- color: #7f007f !important;
-}
-.syntaxhighlighter .xml .string {
- font-style: italic !important;
- color: #2a00ff !important;
-}
diff --git a/guides/assets/stylesheets/syntaxhighlighter/shCoreEmacs.css b/guides/assets/stylesheets/syntaxhighlighter/shCoreEmacs.css
deleted file mode 100644
index 706c77a0a8..0000000000
--- a/guides/assets/stylesheets/syntaxhighlighter/shCoreEmacs.css
+++ /dev/null
@@ -1,324 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- *
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-.syntaxhighlighter a,
-.syntaxhighlighter div,
-.syntaxhighlighter code,
-.syntaxhighlighter table,
-.syntaxhighlighter table td,
-.syntaxhighlighter table tr,
-.syntaxhighlighter table tbody,
-.syntaxhighlighter table thead,
-.syntaxhighlighter table caption,
-.syntaxhighlighter textarea {
- -moz-border-radius: 0 0 0 0 !important;
- -webkit-border-radius: 0 0 0 0 !important;
- background: none !important;
- border: 0 !important;
- bottom: auto !important;
- float: none !important;
- height: auto !important;
- left: auto !important;
- line-height: 1.1em !important;
- margin: 0 !important;
- outline: 0 !important;
- overflow: visible !important;
- padding: 0 !important;
- position: static !important;
- right: auto !important;
- text-align: left !important;
- top: auto !important;
- vertical-align: baseline !important;
- width: auto !important;
- box-sizing: content-box !important;
- font-family: "Consolas", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace !important;
- font-weight: normal !important;
- font-style: normal !important;
- font-size: 1em !important;
- min-height: inherit !important;
- min-height: auto !important;
-}
-
-.syntaxhighlighter {
- width: 100% !important;
- margin: 1em 0 1em 0 !important;
- position: relative !important;
- overflow: auto !important;
- font-size: 1em !important;
-}
-.syntaxhighlighter.source {
- overflow: hidden !important;
-}
-.syntaxhighlighter .bold {
- font-weight: bold !important;
-}
-.syntaxhighlighter .italic {
- font-style: italic !important;
-}
-.syntaxhighlighter .line {
- white-space: pre !important;
-}
-.syntaxhighlighter table {
- width: 100% !important;
-}
-.syntaxhighlighter table caption {
- text-align: left !important;
- padding: .5em 0 0.5em 1em !important;
-}
-.syntaxhighlighter table td.code {
- width: 100% !important;
-}
-.syntaxhighlighter table td.code .container {
- position: relative !important;
-}
-.syntaxhighlighter table td.code .container textarea {
- box-sizing: border-box !important;
- position: absolute !important;
- left: 0 !important;
- top: 0 !important;
- width: 100% !important;
- height: 100% !important;
- border: none !important;
- background: white !important;
- padding-left: 1em !important;
- overflow: hidden !important;
- white-space: pre !important;
-}
-.syntaxhighlighter table td.gutter .line {
- text-align: right !important;
- padding: 0 0.5em 0 1em !important;
-}
-.syntaxhighlighter table td.code .line {
- padding: 0 1em !important;
-}
-.syntaxhighlighter.nogutter td.code .container textarea, .syntaxhighlighter.nogutter td.code .line {
- padding-left: 0em !important;
-}
-.syntaxhighlighter.show {
- display: block !important;
-}
-.syntaxhighlighter.collapsed table {
- display: none !important;
-}
-.syntaxhighlighter.collapsed .toolbar {
- padding: 0.1em 0.8em 0em 0.8em !important;
- font-size: 1em !important;
- position: static !important;
- width: auto !important;
- height: auto !important;
-}
-.syntaxhighlighter.collapsed .toolbar span {
- display: inline !important;
- margin-right: 1em !important;
-}
-.syntaxhighlighter.collapsed .toolbar span a {
- padding: 0 !important;
- display: none !important;
-}
-.syntaxhighlighter.collapsed .toolbar span a.expandSource {
- display: inline !important;
-}
-.syntaxhighlighter .toolbar {
- position: absolute !important;
- right: 1px !important;
- top: 1px !important;
- width: 11px !important;
- height: 11px !important;
- font-size: 10px !important;
- z-index: 10 !important;
-}
-.syntaxhighlighter .toolbar span.title {
- display: inline !important;
-}
-.syntaxhighlighter .toolbar a {
- display: block !important;
- text-align: center !important;
- text-decoration: none !important;
- padding-top: 1px !important;
-}
-.syntaxhighlighter .toolbar a.expandSource {
- display: none !important;
-}
-.syntaxhighlighter.ie {
- font-size: .9em !important;
- padding: 1px 0 1px 0 !important;
-}
-.syntaxhighlighter.ie .toolbar {
- line-height: 8px !important;
-}
-.syntaxhighlighter.ie .toolbar a {
- padding-top: 0px !important;
-}
-.syntaxhighlighter.printing .line.alt1 .content,
-.syntaxhighlighter.printing .line.alt2 .content,
-.syntaxhighlighter.printing .line.highlighted .number,
-.syntaxhighlighter.printing .line.highlighted.alt1 .content,
-.syntaxhighlighter.printing .line.highlighted.alt2 .content {
- background: none !important;
-}
-.syntaxhighlighter.printing .line .number {
- color: #bbbbbb !important;
-}
-.syntaxhighlighter.printing .line .content {
- color: black !important;
-}
-.syntaxhighlighter.printing .toolbar {
- display: none !important;
-}
-.syntaxhighlighter.printing a {
- text-decoration: none !important;
-}
-.syntaxhighlighter.printing .plain, .syntaxhighlighter.printing .plain a {
- color: black !important;
-}
-.syntaxhighlighter.printing .comments, .syntaxhighlighter.printing .comments a {
- color: #008200 !important;
-}
-.syntaxhighlighter.printing .string, .syntaxhighlighter.printing .string a {
- color: blue !important;
-}
-.syntaxhighlighter.printing .keyword {
- color: #006699 !important;
- font-weight: bold !important;
-}
-.syntaxhighlighter.printing .preprocessor {
- color: gray !important;
-}
-.syntaxhighlighter.printing .variable {
- color: #aa7700 !important;
-}
-.syntaxhighlighter.printing .value {
- color: #009900 !important;
-}
-.syntaxhighlighter.printing .functions {
- color: #ff1493 !important;
-}
-.syntaxhighlighter.printing .constants {
- color: #0066cc !important;
-}
-.syntaxhighlighter.printing .script {
- font-weight: bold !important;
-}
-.syntaxhighlighter.printing .color1, .syntaxhighlighter.printing .color1 a {
- color: gray !important;
-}
-.syntaxhighlighter.printing .color2, .syntaxhighlighter.printing .color2 a {
- color: #ff1493 !important;
-}
-.syntaxhighlighter.printing .color3, .syntaxhighlighter.printing .color3 a {
- color: red !important;
-}
-.syntaxhighlighter.printing .break, .syntaxhighlighter.printing .break a {
- color: black !important;
-}
-
-.syntaxhighlighter {
- background-color: black !important;
-}
-.syntaxhighlighter .line.alt1 {
- background-color: black !important;
-}
-.syntaxhighlighter .line.alt2 {
- background-color: black !important;
-}
-.syntaxhighlighter .line.highlighted.alt1, .syntaxhighlighter .line.highlighted.alt2 {
- background-color: #2a3133 !important;
-}
-.syntaxhighlighter .line.highlighted.number {
- color: white !important;
-}
-.syntaxhighlighter table caption {
- color: #d3d3d3 !important;
-}
-.syntaxhighlighter .gutter {
- color: #d3d3d3 !important;
-}
-.syntaxhighlighter .gutter .line {
- border-right: 3px solid #990000 !important;
-}
-.syntaxhighlighter .gutter .line.highlighted {
- background-color: #990000 !important;
- color: black !important;
-}
-.syntaxhighlighter.printing .line .content {
- border: none !important;
-}
-.syntaxhighlighter.collapsed {
- overflow: visible !important;
-}
-.syntaxhighlighter.collapsed .toolbar {
- color: #ebdb8d !important;
- background: black !important;
- border: 1px solid #990000 !important;
-}
-.syntaxhighlighter.collapsed .toolbar a {
- color: #ebdb8d !important;
-}
-.syntaxhighlighter.collapsed .toolbar a:hover {
- color: #ff7d27 !important;
-}
-.syntaxhighlighter .toolbar {
- color: white !important;
- background: #990000 !important;
- border: none !important;
-}
-.syntaxhighlighter .toolbar a {
- color: white !important;
-}
-.syntaxhighlighter .toolbar a:hover {
- color: #9ccff4 !important;
-}
-.syntaxhighlighter .plain, .syntaxhighlighter .plain a {
- color: #d3d3d3 !important;
-}
-.syntaxhighlighter .comments, .syntaxhighlighter .comments a {
- color: #ff7d27 !important;
-}
-.syntaxhighlighter .string, .syntaxhighlighter .string a {
- color: #ff9e7b !important;
-}
-.syntaxhighlighter .keyword {
- color: aqua !important;
-}
-.syntaxhighlighter .preprocessor {
- color: #aec4de !important;
-}
-.syntaxhighlighter .variable {
- color: #ffaa3e !important;
-}
-.syntaxhighlighter .value {
- color: #009900 !important;
-}
-.syntaxhighlighter .functions {
- color: #81cef9 !important;
-}
-.syntaxhighlighter .constants {
- color: #ff9e7b !important;
-}
-.syntaxhighlighter .script {
- font-weight: bold !important;
- color: aqua !important;
- background-color: none !important;
-}
-.syntaxhighlighter .color1, .syntaxhighlighter .color1 a {
- color: #ebdb8d !important;
-}
-.syntaxhighlighter .color2, .syntaxhighlighter .color2 a {
- color: #ff7d27 !important;
-}
-.syntaxhighlighter .color3, .syntaxhighlighter .color3 a {
- color: #aec4de !important;
-}
diff --git a/guides/assets/stylesheets/syntaxhighlighter/shCoreFadeToGrey.css b/guides/assets/stylesheets/syntaxhighlighter/shCoreFadeToGrey.css
deleted file mode 100644
index 6101eba51f..0000000000
--- a/guides/assets/stylesheets/syntaxhighlighter/shCoreFadeToGrey.css
+++ /dev/null
@@ -1,328 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- *
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-.syntaxhighlighter a,
-.syntaxhighlighter div,
-.syntaxhighlighter code,
-.syntaxhighlighter table,
-.syntaxhighlighter table td,
-.syntaxhighlighter table tr,
-.syntaxhighlighter table tbody,
-.syntaxhighlighter table thead,
-.syntaxhighlighter table caption,
-.syntaxhighlighter textarea {
- -moz-border-radius: 0 0 0 0 !important;
- -webkit-border-radius: 0 0 0 0 !important;
- background: none !important;
- border: 0 !important;
- bottom: auto !important;
- float: none !important;
- height: auto !important;
- left: auto !important;
- line-height: 1.1em !important;
- margin: 0 !important;
- outline: 0 !important;
- overflow: visible !important;
- padding: 0 !important;
- position: static !important;
- right: auto !important;
- text-align: left !important;
- top: auto !important;
- vertical-align: baseline !important;
- width: auto !important;
- box-sizing: content-box !important;
- font-family: "Consolas", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace !important;
- font-weight: normal !important;
- font-style: normal !important;
- font-size: 1em !important;
- min-height: inherit !important;
- min-height: auto !important;
-}
-
-.syntaxhighlighter {
- width: 100% !important;
- margin: 1em 0 1em 0 !important;
- position: relative !important;
- overflow: auto !important;
- font-size: 1em !important;
-}
-.syntaxhighlighter.source {
- overflow: hidden !important;
-}
-.syntaxhighlighter .bold {
- font-weight: bold !important;
-}
-.syntaxhighlighter .italic {
- font-style: italic !important;
-}
-.syntaxhighlighter .line {
- white-space: pre !important;
-}
-.syntaxhighlighter table {
- width: 100% !important;
-}
-.syntaxhighlighter table caption {
- text-align: left !important;
- padding: .5em 0 0.5em 1em !important;
-}
-.syntaxhighlighter table td.code {
- width: 100% !important;
-}
-.syntaxhighlighter table td.code .container {
- position: relative !important;
-}
-.syntaxhighlighter table td.code .container textarea {
- box-sizing: border-box !important;
- position: absolute !important;
- left: 0 !important;
- top: 0 !important;
- width: 100% !important;
- height: 100% !important;
- border: none !important;
- background: white !important;
- padding-left: 1em !important;
- overflow: hidden !important;
- white-space: pre !important;
-}
-.syntaxhighlighter table td.gutter .line {
- text-align: right !important;
- padding: 0 0.5em 0 1em !important;
-}
-.syntaxhighlighter table td.code .line {
- padding: 0 1em !important;
-}
-.syntaxhighlighter.nogutter td.code .container textarea, .syntaxhighlighter.nogutter td.code .line {
- padding-left: 0em !important;
-}
-.syntaxhighlighter.show {
- display: block !important;
-}
-.syntaxhighlighter.collapsed table {
- display: none !important;
-}
-.syntaxhighlighter.collapsed .toolbar {
- padding: 0.1em 0.8em 0em 0.8em !important;
- font-size: 1em !important;
- position: static !important;
- width: auto !important;
- height: auto !important;
-}
-.syntaxhighlighter.collapsed .toolbar span {
- display: inline !important;
- margin-right: 1em !important;
-}
-.syntaxhighlighter.collapsed .toolbar span a {
- padding: 0 !important;
- display: none !important;
-}
-.syntaxhighlighter.collapsed .toolbar span a.expandSource {
- display: inline !important;
-}
-.syntaxhighlighter .toolbar {
- position: absolute !important;
- right: 1px !important;
- top: 1px !important;
- width: 11px !important;
- height: 11px !important;
- font-size: 10px !important;
- z-index: 10 !important;
-}
-.syntaxhighlighter .toolbar span.title {
- display: inline !important;
-}
-.syntaxhighlighter .toolbar a {
- display: block !important;
- text-align: center !important;
- text-decoration: none !important;
- padding-top: 1px !important;
-}
-.syntaxhighlighter .toolbar a.expandSource {
- display: none !important;
-}
-.syntaxhighlighter.ie {
- font-size: .9em !important;
- padding: 1px 0 1px 0 !important;
-}
-.syntaxhighlighter.ie .toolbar {
- line-height: 8px !important;
-}
-.syntaxhighlighter.ie .toolbar a {
- padding-top: 0px !important;
-}
-.syntaxhighlighter.printing .line.alt1 .content,
-.syntaxhighlighter.printing .line.alt2 .content,
-.syntaxhighlighter.printing .line.highlighted .number,
-.syntaxhighlighter.printing .line.highlighted.alt1 .content,
-.syntaxhighlighter.printing .line.highlighted.alt2 .content {
- background: none !important;
-}
-.syntaxhighlighter.printing .line .number {
- color: #bbbbbb !important;
-}
-.syntaxhighlighter.printing .line .content {
- color: black !important;
-}
-.syntaxhighlighter.printing .toolbar {
- display: none !important;
-}
-.syntaxhighlighter.printing a {
- text-decoration: none !important;
-}
-.syntaxhighlighter.printing .plain, .syntaxhighlighter.printing .plain a {
- color: black !important;
-}
-.syntaxhighlighter.printing .comments, .syntaxhighlighter.printing .comments a {
- color: #008200 !important;
-}
-.syntaxhighlighter.printing .string, .syntaxhighlighter.printing .string a {
- color: blue !important;
-}
-.syntaxhighlighter.printing .keyword {
- color: #006699 !important;
- font-weight: bold !important;
-}
-.syntaxhighlighter.printing .preprocessor {
- color: gray !important;
-}
-.syntaxhighlighter.printing .variable {
- color: #aa7700 !important;
-}
-.syntaxhighlighter.printing .value {
- color: #009900 !important;
-}
-.syntaxhighlighter.printing .functions {
- color: #ff1493 !important;
-}
-.syntaxhighlighter.printing .constants {
- color: #0066cc !important;
-}
-.syntaxhighlighter.printing .script {
- font-weight: bold !important;
-}
-.syntaxhighlighter.printing .color1, .syntaxhighlighter.printing .color1 a {
- color: gray !important;
-}
-.syntaxhighlighter.printing .color2, .syntaxhighlighter.printing .color2 a {
- color: #ff1493 !important;
-}
-.syntaxhighlighter.printing .color3, .syntaxhighlighter.printing .color3 a {
- color: red !important;
-}
-.syntaxhighlighter.printing .break, .syntaxhighlighter.printing .break a {
- color: black !important;
-}
-
-.syntaxhighlighter {
- background-color: #121212 !important;
-}
-.syntaxhighlighter .line.alt1 {
- background-color: #121212 !important;
-}
-.syntaxhighlighter .line.alt2 {
- background-color: #121212 !important;
-}
-.syntaxhighlighter .line.highlighted.alt1, .syntaxhighlighter .line.highlighted.alt2 {
- background-color: #2c2c29 !important;
-}
-.syntaxhighlighter .line.highlighted.number {
- color: white !important;
-}
-.syntaxhighlighter table caption {
- color: white !important;
-}
-.syntaxhighlighter .gutter {
- color: #afafaf !important;
-}
-.syntaxhighlighter .gutter .line {
- border-right: 3px solid #3185b9 !important;
-}
-.syntaxhighlighter .gutter .line.highlighted {
- background-color: #3185b9 !important;
- color: #121212 !important;
-}
-.syntaxhighlighter.printing .line .content {
- border: none !important;
-}
-.syntaxhighlighter.collapsed {
- overflow: visible !important;
-}
-.syntaxhighlighter.collapsed .toolbar {
- color: #3185b9 !important;
- background: black !important;
- border: 1px solid #3185b9 !important;
-}
-.syntaxhighlighter.collapsed .toolbar a {
- color: #3185b9 !important;
-}
-.syntaxhighlighter.collapsed .toolbar a:hover {
- color: #d01d33 !important;
-}
-.syntaxhighlighter .toolbar {
- color: white !important;
- background: #3185b9 !important;
- border: none !important;
-}
-.syntaxhighlighter .toolbar a {
- color: white !important;
-}
-.syntaxhighlighter .toolbar a:hover {
- color: #96daff !important;
-}
-.syntaxhighlighter .plain, .syntaxhighlighter .plain a {
- color: white !important;
-}
-.syntaxhighlighter .comments, .syntaxhighlighter .comments a {
- color: #696854 !important;
-}
-.syntaxhighlighter .string, .syntaxhighlighter .string a {
- color: #e3e658 !important;
-}
-.syntaxhighlighter .keyword {
- color: #d01d33 !important;
-}
-.syntaxhighlighter .preprocessor {
- color: #435a5f !important;
-}
-.syntaxhighlighter .variable {
- color: #898989 !important;
-}
-.syntaxhighlighter .value {
- color: #009900 !important;
-}
-.syntaxhighlighter .functions {
- color: #aaaaaa !important;
-}
-.syntaxhighlighter .constants {
- color: #96daff !important;
-}
-.syntaxhighlighter .script {
- font-weight: bold !important;
- color: #d01d33 !important;
- background-color: none !important;
-}
-.syntaxhighlighter .color1, .syntaxhighlighter .color1 a {
- color: #ffc074 !important;
-}
-.syntaxhighlighter .color2, .syntaxhighlighter .color2 a {
- color: #4a8cdb !important;
-}
-.syntaxhighlighter .color3, .syntaxhighlighter .color3 a {
- color: #96daff !important;
-}
-
-.syntaxhighlighter .functions {
- font-weight: bold !important;
-}
diff --git a/guides/assets/stylesheets/syntaxhighlighter/shCoreMDUltra.css b/guides/assets/stylesheets/syntaxhighlighter/shCoreMDUltra.css
deleted file mode 100644
index 2923ce7367..0000000000
--- a/guides/assets/stylesheets/syntaxhighlighter/shCoreMDUltra.css
+++ /dev/null
@@ -1,324 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- *
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-.syntaxhighlighter a,
-.syntaxhighlighter div,
-.syntaxhighlighter code,
-.syntaxhighlighter table,
-.syntaxhighlighter table td,
-.syntaxhighlighter table tr,
-.syntaxhighlighter table tbody,
-.syntaxhighlighter table thead,
-.syntaxhighlighter table caption,
-.syntaxhighlighter textarea {
- -moz-border-radius: 0 0 0 0 !important;
- -webkit-border-radius: 0 0 0 0 !important;
- background: none !important;
- border: 0 !important;
- bottom: auto !important;
- float: none !important;
- height: auto !important;
- left: auto !important;
- line-height: 1.1em !important;
- margin: 0 !important;
- outline: 0 !important;
- overflow: visible !important;
- padding: 0 !important;
- position: static !important;
- right: auto !important;
- text-align: left !important;
- top: auto !important;
- vertical-align: baseline !important;
- width: auto !important;
- box-sizing: content-box !important;
- font-family: "Consolas", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace !important;
- font-weight: normal !important;
- font-style: normal !important;
- font-size: 1em !important;
- min-height: inherit !important;
- min-height: auto !important;
-}
-
-.syntaxhighlighter {
- width: 100% !important;
- margin: 1em 0 1em 0 !important;
- position: relative !important;
- overflow: auto !important;
- font-size: 1em !important;
-}
-.syntaxhighlighter.source {
- overflow: hidden !important;
-}
-.syntaxhighlighter .bold {
- font-weight: bold !important;
-}
-.syntaxhighlighter .italic {
- font-style: italic !important;
-}
-.syntaxhighlighter .line {
- white-space: pre !important;
-}
-.syntaxhighlighter table {
- width: 100% !important;
-}
-.syntaxhighlighter table caption {
- text-align: left !important;
- padding: .5em 0 0.5em 1em !important;
-}
-.syntaxhighlighter table td.code {
- width: 100% !important;
-}
-.syntaxhighlighter table td.code .container {
- position: relative !important;
-}
-.syntaxhighlighter table td.code .container textarea {
- box-sizing: border-box !important;
- position: absolute !important;
- left: 0 !important;
- top: 0 !important;
- width: 100% !important;
- height: 100% !important;
- border: none !important;
- background: white !important;
- padding-left: 1em !important;
- overflow: hidden !important;
- white-space: pre !important;
-}
-.syntaxhighlighter table td.gutter .line {
- text-align: right !important;
- padding: 0 0.5em 0 1em !important;
-}
-.syntaxhighlighter table td.code .line {
- padding: 0 1em !important;
-}
-.syntaxhighlighter.nogutter td.code .container textarea, .syntaxhighlighter.nogutter td.code .line {
- padding-left: 0em !important;
-}
-.syntaxhighlighter.show {
- display: block !important;
-}
-.syntaxhighlighter.collapsed table {
- display: none !important;
-}
-.syntaxhighlighter.collapsed .toolbar {
- padding: 0.1em 0.8em 0em 0.8em !important;
- font-size: 1em !important;
- position: static !important;
- width: auto !important;
- height: auto !important;
-}
-.syntaxhighlighter.collapsed .toolbar span {
- display: inline !important;
- margin-right: 1em !important;
-}
-.syntaxhighlighter.collapsed .toolbar span a {
- padding: 0 !important;
- display: none !important;
-}
-.syntaxhighlighter.collapsed .toolbar span a.expandSource {
- display: inline !important;
-}
-.syntaxhighlighter .toolbar {
- position: absolute !important;
- right: 1px !important;
- top: 1px !important;
- width: 11px !important;
- height: 11px !important;
- font-size: 10px !important;
- z-index: 10 !important;
-}
-.syntaxhighlighter .toolbar span.title {
- display: inline !important;
-}
-.syntaxhighlighter .toolbar a {
- display: block !important;
- text-align: center !important;
- text-decoration: none !important;
- padding-top: 1px !important;
-}
-.syntaxhighlighter .toolbar a.expandSource {
- display: none !important;
-}
-.syntaxhighlighter.ie {
- font-size: .9em !important;
- padding: 1px 0 1px 0 !important;
-}
-.syntaxhighlighter.ie .toolbar {
- line-height: 8px !important;
-}
-.syntaxhighlighter.ie .toolbar a {
- padding-top: 0px !important;
-}
-.syntaxhighlighter.printing .line.alt1 .content,
-.syntaxhighlighter.printing .line.alt2 .content,
-.syntaxhighlighter.printing .line.highlighted .number,
-.syntaxhighlighter.printing .line.highlighted.alt1 .content,
-.syntaxhighlighter.printing .line.highlighted.alt2 .content {
- background: none !important;
-}
-.syntaxhighlighter.printing .line .number {
- color: #bbbbbb !important;
-}
-.syntaxhighlighter.printing .line .content {
- color: black !important;
-}
-.syntaxhighlighter.printing .toolbar {
- display: none !important;
-}
-.syntaxhighlighter.printing a {
- text-decoration: none !important;
-}
-.syntaxhighlighter.printing .plain, .syntaxhighlighter.printing .plain a {
- color: black !important;
-}
-.syntaxhighlighter.printing .comments, .syntaxhighlighter.printing .comments a {
- color: #008200 !important;
-}
-.syntaxhighlighter.printing .string, .syntaxhighlighter.printing .string a {
- color: blue !important;
-}
-.syntaxhighlighter.printing .keyword {
- color: #006699 !important;
- font-weight: bold !important;
-}
-.syntaxhighlighter.printing .preprocessor {
- color: gray !important;
-}
-.syntaxhighlighter.printing .variable {
- color: #aa7700 !important;
-}
-.syntaxhighlighter.printing .value {
- color: #009900 !important;
-}
-.syntaxhighlighter.printing .functions {
- color: #ff1493 !important;
-}
-.syntaxhighlighter.printing .constants {
- color: #0066cc !important;
-}
-.syntaxhighlighter.printing .script {
- font-weight: bold !important;
-}
-.syntaxhighlighter.printing .color1, .syntaxhighlighter.printing .color1 a {
- color: gray !important;
-}
-.syntaxhighlighter.printing .color2, .syntaxhighlighter.printing .color2 a {
- color: #ff1493 !important;
-}
-.syntaxhighlighter.printing .color3, .syntaxhighlighter.printing .color3 a {
- color: red !important;
-}
-.syntaxhighlighter.printing .break, .syntaxhighlighter.printing .break a {
- color: black !important;
-}
-
-.syntaxhighlighter {
- background-color: #222222 !important;
-}
-.syntaxhighlighter .line.alt1 {
- background-color: #222222 !important;
-}
-.syntaxhighlighter .line.alt2 {
- background-color: #222222 !important;
-}
-.syntaxhighlighter .line.highlighted.alt1, .syntaxhighlighter .line.highlighted.alt2 {
- background-color: #253e5a !important;
-}
-.syntaxhighlighter .line.highlighted.number {
- color: white !important;
-}
-.syntaxhighlighter table caption {
- color: lime !important;
-}
-.syntaxhighlighter .gutter {
- color: #38566f !important;
-}
-.syntaxhighlighter .gutter .line {
- border-right: 3px solid #435a5f !important;
-}
-.syntaxhighlighter .gutter .line.highlighted {
- background-color: #435a5f !important;
- color: #222222 !important;
-}
-.syntaxhighlighter.printing .line .content {
- border: none !important;
-}
-.syntaxhighlighter.collapsed {
- overflow: visible !important;
-}
-.syntaxhighlighter.collapsed .toolbar {
- color: #428bdd !important;
- background: black !important;
- border: 1px solid #435a5f !important;
-}
-.syntaxhighlighter.collapsed .toolbar a {
- color: #428bdd !important;
-}
-.syntaxhighlighter.collapsed .toolbar a:hover {
- color: lime !important;
-}
-.syntaxhighlighter .toolbar {
- color: #aaaaff !important;
- background: #435a5f !important;
- border: none !important;
-}
-.syntaxhighlighter .toolbar a {
- color: #aaaaff !important;
-}
-.syntaxhighlighter .toolbar a:hover {
- color: #9ccff4 !important;
-}
-.syntaxhighlighter .plain, .syntaxhighlighter .plain a {
- color: lime !important;
-}
-.syntaxhighlighter .comments, .syntaxhighlighter .comments a {
- color: #428bdd !important;
-}
-.syntaxhighlighter .string, .syntaxhighlighter .string a {
- color: lime !important;
-}
-.syntaxhighlighter .keyword {
- color: #aaaaff !important;
-}
-.syntaxhighlighter .preprocessor {
- color: #8aa6c1 !important;
-}
-.syntaxhighlighter .variable {
- color: aqua !important;
-}
-.syntaxhighlighter .value {
- color: #f7e741 !important;
-}
-.syntaxhighlighter .functions {
- color: #ff8000 !important;
-}
-.syntaxhighlighter .constants {
- color: yellow !important;
-}
-.syntaxhighlighter .script {
- font-weight: bold !important;
- color: #aaaaff !important;
- background-color: none !important;
-}
-.syntaxhighlighter .color1, .syntaxhighlighter .color1 a {
- color: red !important;
-}
-.syntaxhighlighter .color2, .syntaxhighlighter .color2 a {
- color: yellow !important;
-}
-.syntaxhighlighter .color3, .syntaxhighlighter .color3 a {
- color: #ffaa3e !important;
-}
diff --git a/guides/assets/stylesheets/syntaxhighlighter/shCoreMidnight.css b/guides/assets/stylesheets/syntaxhighlighter/shCoreMidnight.css
deleted file mode 100644
index e3733eed56..0000000000
--- a/guides/assets/stylesheets/syntaxhighlighter/shCoreMidnight.css
+++ /dev/null
@@ -1,324 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- *
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-.syntaxhighlighter a,
-.syntaxhighlighter div,
-.syntaxhighlighter code,
-.syntaxhighlighter table,
-.syntaxhighlighter table td,
-.syntaxhighlighter table tr,
-.syntaxhighlighter table tbody,
-.syntaxhighlighter table thead,
-.syntaxhighlighter table caption,
-.syntaxhighlighter textarea {
- -moz-border-radius: 0 0 0 0 !important;
- -webkit-border-radius: 0 0 0 0 !important;
- background: none !important;
- border: 0 !important;
- bottom: auto !important;
- float: none !important;
- height: auto !important;
- left: auto !important;
- line-height: 1.1em !important;
- margin: 0 !important;
- outline: 0 !important;
- overflow: visible !important;
- padding: 0 !important;
- position: static !important;
- right: auto !important;
- text-align: left !important;
- top: auto !important;
- vertical-align: baseline !important;
- width: auto !important;
- box-sizing: content-box !important;
- font-family: "Consolas", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace !important;
- font-weight: normal !important;
- font-style: normal !important;
- font-size: 1em !important;
- min-height: inherit !important;
- min-height: auto !important;
-}
-
-.syntaxhighlighter {
- width: 100% !important;
- margin: 1em 0 1em 0 !important;
- position: relative !important;
- overflow: auto !important;
- font-size: 1em !important;
-}
-.syntaxhighlighter.source {
- overflow: hidden !important;
-}
-.syntaxhighlighter .bold {
- font-weight: bold !important;
-}
-.syntaxhighlighter .italic {
- font-style: italic !important;
-}
-.syntaxhighlighter .line {
- white-space: pre !important;
-}
-.syntaxhighlighter table {
- width: 100% !important;
-}
-.syntaxhighlighter table caption {
- text-align: left !important;
- padding: .5em 0 0.5em 1em !important;
-}
-.syntaxhighlighter table td.code {
- width: 100% !important;
-}
-.syntaxhighlighter table td.code .container {
- position: relative !important;
-}
-.syntaxhighlighter table td.code .container textarea {
- box-sizing: border-box !important;
- position: absolute !important;
- left: 0 !important;
- top: 0 !important;
- width: 100% !important;
- height: 100% !important;
- border: none !important;
- background: white !important;
- padding-left: 1em !important;
- overflow: hidden !important;
- white-space: pre !important;
-}
-.syntaxhighlighter table td.gutter .line {
- text-align: right !important;
- padding: 0 0.5em 0 1em !important;
-}
-.syntaxhighlighter table td.code .line {
- padding: 0 1em !important;
-}
-.syntaxhighlighter.nogutter td.code .container textarea, .syntaxhighlighter.nogutter td.code .line {
- padding-left: 0em !important;
-}
-.syntaxhighlighter.show {
- display: block !important;
-}
-.syntaxhighlighter.collapsed table {
- display: none !important;
-}
-.syntaxhighlighter.collapsed .toolbar {
- padding: 0.1em 0.8em 0em 0.8em !important;
- font-size: 1em !important;
- position: static !important;
- width: auto !important;
- height: auto !important;
-}
-.syntaxhighlighter.collapsed .toolbar span {
- display: inline !important;
- margin-right: 1em !important;
-}
-.syntaxhighlighter.collapsed .toolbar span a {
- padding: 0 !important;
- display: none !important;
-}
-.syntaxhighlighter.collapsed .toolbar span a.expandSource {
- display: inline !important;
-}
-.syntaxhighlighter .toolbar {
- position: absolute !important;
- right: 1px !important;
- top: 1px !important;
- width: 11px !important;
- height: 11px !important;
- font-size: 10px !important;
- z-index: 10 !important;
-}
-.syntaxhighlighter .toolbar span.title {
- display: inline !important;
-}
-.syntaxhighlighter .toolbar a {
- display: block !important;
- text-align: center !important;
- text-decoration: none !important;
- padding-top: 1px !important;
-}
-.syntaxhighlighter .toolbar a.expandSource {
- display: none !important;
-}
-.syntaxhighlighter.ie {
- font-size: .9em !important;
- padding: 1px 0 1px 0 !important;
-}
-.syntaxhighlighter.ie .toolbar {
- line-height: 8px !important;
-}
-.syntaxhighlighter.ie .toolbar a {
- padding-top: 0px !important;
-}
-.syntaxhighlighter.printing .line.alt1 .content,
-.syntaxhighlighter.printing .line.alt2 .content,
-.syntaxhighlighter.printing .line.highlighted .number,
-.syntaxhighlighter.printing .line.highlighted.alt1 .content,
-.syntaxhighlighter.printing .line.highlighted.alt2 .content {
- background: none !important;
-}
-.syntaxhighlighter.printing .line .number {
- color: #bbbbbb !important;
-}
-.syntaxhighlighter.printing .line .content {
- color: black !important;
-}
-.syntaxhighlighter.printing .toolbar {
- display: none !important;
-}
-.syntaxhighlighter.printing a {
- text-decoration: none !important;
-}
-.syntaxhighlighter.printing .plain, .syntaxhighlighter.printing .plain a {
- color: black !important;
-}
-.syntaxhighlighter.printing .comments, .syntaxhighlighter.printing .comments a {
- color: #008200 !important;
-}
-.syntaxhighlighter.printing .string, .syntaxhighlighter.printing .string a {
- color: blue !important;
-}
-.syntaxhighlighter.printing .keyword {
- color: #006699 !important;
- font-weight: bold !important;
-}
-.syntaxhighlighter.printing .preprocessor {
- color: gray !important;
-}
-.syntaxhighlighter.printing .variable {
- color: #aa7700 !important;
-}
-.syntaxhighlighter.printing .value {
- color: #009900 !important;
-}
-.syntaxhighlighter.printing .functions {
- color: #ff1493 !important;
-}
-.syntaxhighlighter.printing .constants {
- color: #0066cc !important;
-}
-.syntaxhighlighter.printing .script {
- font-weight: bold !important;
-}
-.syntaxhighlighter.printing .color1, .syntaxhighlighter.printing .color1 a {
- color: gray !important;
-}
-.syntaxhighlighter.printing .color2, .syntaxhighlighter.printing .color2 a {
- color: #ff1493 !important;
-}
-.syntaxhighlighter.printing .color3, .syntaxhighlighter.printing .color3 a {
- color: red !important;
-}
-.syntaxhighlighter.printing .break, .syntaxhighlighter.printing .break a {
- color: black !important;
-}
-
-.syntaxhighlighter {
- background-color: #0f192a !important;
-}
-.syntaxhighlighter .line.alt1 {
- background-color: #0f192a !important;
-}
-.syntaxhighlighter .line.alt2 {
- background-color: #0f192a !important;
-}
-.syntaxhighlighter .line.highlighted.alt1, .syntaxhighlighter .line.highlighted.alt2 {
- background-color: #253e5a !important;
-}
-.syntaxhighlighter .line.highlighted.number {
- color: #38566f !important;
-}
-.syntaxhighlighter table caption {
- color: #d1edff !important;
-}
-.syntaxhighlighter .gutter {
- color: #afafaf !important;
-}
-.syntaxhighlighter .gutter .line {
- border-right: 3px solid #435a5f !important;
-}
-.syntaxhighlighter .gutter .line.highlighted {
- background-color: #435a5f !important;
- color: #0f192a !important;
-}
-.syntaxhighlighter.printing .line .content {
- border: none !important;
-}
-.syntaxhighlighter.collapsed {
- overflow: visible !important;
-}
-.syntaxhighlighter.collapsed .toolbar {
- color: #428bdd !important;
- background: black !important;
- border: 1px solid #435a5f !important;
-}
-.syntaxhighlighter.collapsed .toolbar a {
- color: #428bdd !important;
-}
-.syntaxhighlighter.collapsed .toolbar a:hover {
- color: #1dc116 !important;
-}
-.syntaxhighlighter .toolbar {
- color: #d1edff !important;
- background: #435a5f !important;
- border: none !important;
-}
-.syntaxhighlighter .toolbar a {
- color: #d1edff !important;
-}
-.syntaxhighlighter .toolbar a:hover {
- color: #8aa6c1 !important;
-}
-.syntaxhighlighter .plain, .syntaxhighlighter .plain a {
- color: #d1edff !important;
-}
-.syntaxhighlighter .comments, .syntaxhighlighter .comments a {
- color: #428bdd !important;
-}
-.syntaxhighlighter .string, .syntaxhighlighter .string a {
- color: #1dc116 !important;
-}
-.syntaxhighlighter .keyword {
- color: #b43d3d !important;
-}
-.syntaxhighlighter .preprocessor {
- color: #8aa6c1 !important;
-}
-.syntaxhighlighter .variable {
- color: #ffaa3e !important;
-}
-.syntaxhighlighter .value {
- color: #f7e741 !important;
-}
-.syntaxhighlighter .functions {
- color: #ffaa3e !important;
-}
-.syntaxhighlighter .constants {
- color: #e0e8ff !important;
-}
-.syntaxhighlighter .script {
- font-weight: bold !important;
- color: #b43d3d !important;
- background-color: none !important;
-}
-.syntaxhighlighter .color1, .syntaxhighlighter .color1 a {
- color: #f8bb00 !important;
-}
-.syntaxhighlighter .color2, .syntaxhighlighter .color2 a {
- color: white !important;
-}
-.syntaxhighlighter .color3, .syntaxhighlighter .color3 a {
- color: #ffaa3e !important;
-}
diff --git a/guides/assets/stylesheets/syntaxhighlighter/shCoreRDark.css b/guides/assets/stylesheets/syntaxhighlighter/shCoreRDark.css
deleted file mode 100644
index d09368384d..0000000000
--- a/guides/assets/stylesheets/syntaxhighlighter/shCoreRDark.css
+++ /dev/null
@@ -1,324 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- *
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-.syntaxhighlighter a,
-.syntaxhighlighter div,
-.syntaxhighlighter code,
-.syntaxhighlighter table,
-.syntaxhighlighter table td,
-.syntaxhighlighter table tr,
-.syntaxhighlighter table tbody,
-.syntaxhighlighter table thead,
-.syntaxhighlighter table caption,
-.syntaxhighlighter textarea {
- -moz-border-radius: 0 0 0 0 !important;
- -webkit-border-radius: 0 0 0 0 !important;
- background: none !important;
- border: 0 !important;
- bottom: auto !important;
- float: none !important;
- height: auto !important;
- left: auto !important;
- line-height: 1.1em !important;
- margin: 0 !important;
- outline: 0 !important;
- overflow: visible !important;
- padding: 0 !important;
- position: static !important;
- right: auto !important;
- text-align: left !important;
- top: auto !important;
- vertical-align: baseline !important;
- width: auto !important;
- box-sizing: content-box !important;
- font-family: "Consolas", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace !important;
- font-weight: normal !important;
- font-style: normal !important;
- font-size: 1em !important;
- min-height: inherit !important;
- min-height: auto !important;
-}
-
-.syntaxhighlighter {
- width: 100% !important;
- margin: 1em 0 1em 0 !important;
- position: relative !important;
- overflow: auto !important;
- font-size: 1em !important;
-}
-.syntaxhighlighter.source {
- overflow: hidden !important;
-}
-.syntaxhighlighter .bold {
- font-weight: bold !important;
-}
-.syntaxhighlighter .italic {
- font-style: italic !important;
-}
-.syntaxhighlighter .line {
- white-space: pre !important;
-}
-.syntaxhighlighter table {
- width: 100% !important;
-}
-.syntaxhighlighter table caption {
- text-align: left !important;
- padding: .5em 0 0.5em 1em !important;
-}
-.syntaxhighlighter table td.code {
- width: 100% !important;
-}
-.syntaxhighlighter table td.code .container {
- position: relative !important;
-}
-.syntaxhighlighter table td.code .container textarea {
- box-sizing: border-box !important;
- position: absolute !important;
- left: 0 !important;
- top: 0 !important;
- width: 100% !important;
- height: 100% !important;
- border: none !important;
- background: white !important;
- padding-left: 1em !important;
- overflow: hidden !important;
- white-space: pre !important;
-}
-.syntaxhighlighter table td.gutter .line {
- text-align: right !important;
- padding: 0 0.5em 0 1em !important;
-}
-.syntaxhighlighter table td.code .line {
- padding: 0 1em !important;
-}
-.syntaxhighlighter.nogutter td.code .container textarea, .syntaxhighlighter.nogutter td.code .line {
- padding-left: 0em !important;
-}
-.syntaxhighlighter.show {
- display: block !important;
-}
-.syntaxhighlighter.collapsed table {
- display: none !important;
-}
-.syntaxhighlighter.collapsed .toolbar {
- padding: 0.1em 0.8em 0em 0.8em !important;
- font-size: 1em !important;
- position: static !important;
- width: auto !important;
- height: auto !important;
-}
-.syntaxhighlighter.collapsed .toolbar span {
- display: inline !important;
- margin-right: 1em !important;
-}
-.syntaxhighlighter.collapsed .toolbar span a {
- padding: 0 !important;
- display: none !important;
-}
-.syntaxhighlighter.collapsed .toolbar span a.expandSource {
- display: inline !important;
-}
-.syntaxhighlighter .toolbar {
- position: absolute !important;
- right: 1px !important;
- top: 1px !important;
- width: 11px !important;
- height: 11px !important;
- font-size: 10px !important;
- z-index: 10 !important;
-}
-.syntaxhighlighter .toolbar span.title {
- display: inline !important;
-}
-.syntaxhighlighter .toolbar a {
- display: block !important;
- text-align: center !important;
- text-decoration: none !important;
- padding-top: 1px !important;
-}
-.syntaxhighlighter .toolbar a.expandSource {
- display: none !important;
-}
-.syntaxhighlighter.ie {
- font-size: .9em !important;
- padding: 1px 0 1px 0 !important;
-}
-.syntaxhighlighter.ie .toolbar {
- line-height: 8px !important;
-}
-.syntaxhighlighter.ie .toolbar a {
- padding-top: 0px !important;
-}
-.syntaxhighlighter.printing .line.alt1 .content,
-.syntaxhighlighter.printing .line.alt2 .content,
-.syntaxhighlighter.printing .line.highlighted .number,
-.syntaxhighlighter.printing .line.highlighted.alt1 .content,
-.syntaxhighlighter.printing .line.highlighted.alt2 .content {
- background: none !important;
-}
-.syntaxhighlighter.printing .line .number {
- color: #bbbbbb !important;
-}
-.syntaxhighlighter.printing .line .content {
- color: black !important;
-}
-.syntaxhighlighter.printing .toolbar {
- display: none !important;
-}
-.syntaxhighlighter.printing a {
- text-decoration: none !important;
-}
-.syntaxhighlighter.printing .plain, .syntaxhighlighter.printing .plain a {
- color: black !important;
-}
-.syntaxhighlighter.printing .comments, .syntaxhighlighter.printing .comments a {
- color: #008200 !important;
-}
-.syntaxhighlighter.printing .string, .syntaxhighlighter.printing .string a {
- color: blue !important;
-}
-.syntaxhighlighter.printing .keyword {
- color: #006699 !important;
- font-weight: bold !important;
-}
-.syntaxhighlighter.printing .preprocessor {
- color: gray !important;
-}
-.syntaxhighlighter.printing .variable {
- color: #aa7700 !important;
-}
-.syntaxhighlighter.printing .value {
- color: #009900 !important;
-}
-.syntaxhighlighter.printing .functions {
- color: #ff1493 !important;
-}
-.syntaxhighlighter.printing .constants {
- color: #0066cc !important;
-}
-.syntaxhighlighter.printing .script {
- font-weight: bold !important;
-}
-.syntaxhighlighter.printing .color1, .syntaxhighlighter.printing .color1 a {
- color: gray !important;
-}
-.syntaxhighlighter.printing .color2, .syntaxhighlighter.printing .color2 a {
- color: #ff1493 !important;
-}
-.syntaxhighlighter.printing .color3, .syntaxhighlighter.printing .color3 a {
- color: red !important;
-}
-.syntaxhighlighter.printing .break, .syntaxhighlighter.printing .break a {
- color: black !important;
-}
-
-.syntaxhighlighter {
- background-color: #1b2426 !important;
-}
-.syntaxhighlighter .line.alt1 {
- background-color: #1b2426 !important;
-}
-.syntaxhighlighter .line.alt2 {
- background-color: #1b2426 !important;
-}
-.syntaxhighlighter .line.highlighted.alt1, .syntaxhighlighter .line.highlighted.alt2 {
- background-color: #323e41 !important;
-}
-.syntaxhighlighter .line.highlighted.number {
- color: #b9bdb6 !important;
-}
-.syntaxhighlighter table caption {
- color: #b9bdb6 !important;
-}
-.syntaxhighlighter .gutter {
- color: #afafaf !important;
-}
-.syntaxhighlighter .gutter .line {
- border-right: 3px solid #435a5f !important;
-}
-.syntaxhighlighter .gutter .line.highlighted {
- background-color: #435a5f !important;
- color: #1b2426 !important;
-}
-.syntaxhighlighter.printing .line .content {
- border: none !important;
-}
-.syntaxhighlighter.collapsed {
- overflow: visible !important;
-}
-.syntaxhighlighter.collapsed .toolbar {
- color: #5ba1cf !important;
- background: black !important;
- border: 1px solid #435a5f !important;
-}
-.syntaxhighlighter.collapsed .toolbar a {
- color: #5ba1cf !important;
-}
-.syntaxhighlighter.collapsed .toolbar a:hover {
- color: #5ce638 !important;
-}
-.syntaxhighlighter .toolbar {
- color: white !important;
- background: #435a5f !important;
- border: none !important;
-}
-.syntaxhighlighter .toolbar a {
- color: white !important;
-}
-.syntaxhighlighter .toolbar a:hover {
- color: #e0e8ff !important;
-}
-.syntaxhighlighter .plain, .syntaxhighlighter .plain a {
- color: #b9bdb6 !important;
-}
-.syntaxhighlighter .comments, .syntaxhighlighter .comments a {
- color: #878a85 !important;
-}
-.syntaxhighlighter .string, .syntaxhighlighter .string a {
- color: #5ce638 !important;
-}
-.syntaxhighlighter .keyword {
- color: #5ba1cf !important;
-}
-.syntaxhighlighter .preprocessor {
- color: #435a5f !important;
-}
-.syntaxhighlighter .variable {
- color: #ffaa3e !important;
-}
-.syntaxhighlighter .value {
- color: #009900 !important;
-}
-.syntaxhighlighter .functions {
- color: #ffaa3e !important;
-}
-.syntaxhighlighter .constants {
- color: #e0e8ff !important;
-}
-.syntaxhighlighter .script {
- font-weight: bold !important;
- color: #5ba1cf !important;
- background-color: none !important;
-}
-.syntaxhighlighter .color1, .syntaxhighlighter .color1 a {
- color: #e0e8ff !important;
-}
-.syntaxhighlighter .color2, .syntaxhighlighter .color2 a {
- color: white !important;
-}
-.syntaxhighlighter .color3, .syntaxhighlighter .color3 a {
- color: #ffaa3e !important;
-}
diff --git a/guides/assets/stylesheets/syntaxhighlighter/shThemeDefault.css b/guides/assets/stylesheets/syntaxhighlighter/shThemeDefault.css
deleted file mode 100644
index 136541172d..0000000000
--- a/guides/assets/stylesheets/syntaxhighlighter/shThemeDefault.css
+++ /dev/null
@@ -1,117 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- *
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-.syntaxhighlighter {
- background-color: white !important;
-}
-.syntaxhighlighter .line.alt1 {
- background-color: white !important;
-}
-.syntaxhighlighter .line.alt2 {
- background-color: white !important;
-}
-.syntaxhighlighter .line.highlighted.alt1, .syntaxhighlighter .line.highlighted.alt2 {
- background-color: #e0e0e0 !important;
-}
-.syntaxhighlighter .line.highlighted.number {
- color: black !important;
-}
-.syntaxhighlighter table caption {
- color: black !important;
-}
-.syntaxhighlighter .gutter {
- color: #afafaf !important;
-}
-.syntaxhighlighter .gutter .line {
- border-right: 3px solid #6ce26c !important;
-}
-.syntaxhighlighter .gutter .line.highlighted {
- background-color: #6ce26c !important;
- color: white !important;
-}
-.syntaxhighlighter.printing .line .content {
- border: none !important;
-}
-.syntaxhighlighter.collapsed {
- overflow: visible !important;
-}
-.syntaxhighlighter.collapsed .toolbar {
- color: blue !important;
- background: white !important;
- border: 1px solid #6ce26c !important;
-}
-.syntaxhighlighter.collapsed .toolbar a {
- color: blue !important;
-}
-.syntaxhighlighter.collapsed .toolbar a:hover {
- color: red !important;
-}
-.syntaxhighlighter .toolbar {
- color: white !important;
- background: #6ce26c !important;
- border: none !important;
-}
-.syntaxhighlighter .toolbar a {
- color: white !important;
-}
-.syntaxhighlighter .toolbar a:hover {
- color: black !important;
-}
-.syntaxhighlighter .plain, .syntaxhighlighter .plain a {
- color: black !important;
-}
-.syntaxhighlighter .comments, .syntaxhighlighter .comments a {
- color: #008200 !important;
-}
-.syntaxhighlighter .string, .syntaxhighlighter .string a {
- color: blue !important;
-}
-.syntaxhighlighter .keyword {
- color: #006699 !important;
-}
-.syntaxhighlighter .preprocessor {
- color: gray !important;
-}
-.syntaxhighlighter .variable {
- color: #aa7700 !important;
-}
-.syntaxhighlighter .value {
- color: #009900 !important;
-}
-.syntaxhighlighter .functions {
- color: #ff1493 !important;
-}
-.syntaxhighlighter .constants {
- color: #0066cc !important;
-}
-.syntaxhighlighter .script {
- font-weight: bold !important;
- color: #006699 !important;
- background-color: none !important;
-}
-.syntaxhighlighter .color1, .syntaxhighlighter .color1 a {
- color: gray !important;
-}
-.syntaxhighlighter .color2, .syntaxhighlighter .color2 a {
- color: #ff1493 !important;
-}
-.syntaxhighlighter .color3, .syntaxhighlighter .color3 a {
- color: red !important;
-}
-
-.syntaxhighlighter .keyword {
- font-weight: bold !important;
-}
diff --git a/guides/assets/stylesheets/syntaxhighlighter/shThemeDjango.css b/guides/assets/stylesheets/syntaxhighlighter/shThemeDjango.css
deleted file mode 100644
index d8b4313433..0000000000
--- a/guides/assets/stylesheets/syntaxhighlighter/shThemeDjango.css
+++ /dev/null
@@ -1,120 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- *
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-.syntaxhighlighter {
- background-color: #0a2b1d !important;
-}
-.syntaxhighlighter .line.alt1 {
- background-color: #0a2b1d !important;
-}
-.syntaxhighlighter .line.alt2 {
- background-color: #0a2b1d !important;
-}
-.syntaxhighlighter .line.highlighted.alt1, .syntaxhighlighter .line.highlighted.alt2 {
- background-color: #233729 !important;
-}
-.syntaxhighlighter .line.highlighted.number {
- color: white !important;
-}
-.syntaxhighlighter table caption {
- color: #f8f8f8 !important;
-}
-.syntaxhighlighter .gutter {
- color: #497958 !important;
-}
-.syntaxhighlighter .gutter .line {
- border-right: 3px solid #41a83e !important;
-}
-.syntaxhighlighter .gutter .line.highlighted {
- background-color: #41a83e !important;
- color: #0a2b1d !important;
-}
-.syntaxhighlighter.printing .line .content {
- border: none !important;
-}
-.syntaxhighlighter.collapsed {
- overflow: visible !important;
-}
-.syntaxhighlighter.collapsed .toolbar {
- color: #96dd3b !important;
- background: black !important;
- border: 1px solid #41a83e !important;
-}
-.syntaxhighlighter.collapsed .toolbar a {
- color: #96dd3b !important;
-}
-.syntaxhighlighter.collapsed .toolbar a:hover {
- color: white !important;
-}
-.syntaxhighlighter .toolbar {
- color: white !important;
- background: #41a83e !important;
- border: none !important;
-}
-.syntaxhighlighter .toolbar a {
- color: white !important;
-}
-.syntaxhighlighter .toolbar a:hover {
- color: #ffe862 !important;
-}
-.syntaxhighlighter .plain, .syntaxhighlighter .plain a {
- color: #f8f8f8 !important;
-}
-.syntaxhighlighter .comments, .syntaxhighlighter .comments a {
- color: #336442 !important;
-}
-.syntaxhighlighter .string, .syntaxhighlighter .string a {
- color: #9df39f !important;
-}
-.syntaxhighlighter .keyword {
- color: #96dd3b !important;
-}
-.syntaxhighlighter .preprocessor {
- color: #91bb9e !important;
-}
-.syntaxhighlighter .variable {
- color: #ffaa3e !important;
-}
-.syntaxhighlighter .value {
- color: #f7e741 !important;
-}
-.syntaxhighlighter .functions {
- color: #ffaa3e !important;
-}
-.syntaxhighlighter .constants {
- color: #e0e8ff !important;
-}
-.syntaxhighlighter .script {
- font-weight: bold !important;
- color: #96dd3b !important;
- background-color: none !important;
-}
-.syntaxhighlighter .color1, .syntaxhighlighter .color1 a {
- color: #eb939a !important;
-}
-.syntaxhighlighter .color2, .syntaxhighlighter .color2 a {
- color: #91bb9e !important;
-}
-.syntaxhighlighter .color3, .syntaxhighlighter .color3 a {
- color: #edef7d !important;
-}
-
-.syntaxhighlighter .comments {
- font-style: italic !important;
-}
-.syntaxhighlighter .keyword {
- font-weight: bold !important;
-}
diff --git a/guides/assets/stylesheets/syntaxhighlighter/shThemeEclipse.css b/guides/assets/stylesheets/syntaxhighlighter/shThemeEclipse.css
deleted file mode 100644
index 77377d9533..0000000000
--- a/guides/assets/stylesheets/syntaxhighlighter/shThemeEclipse.css
+++ /dev/null
@@ -1,128 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- *
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-.syntaxhighlighter {
- background-color: white !important;
-}
-.syntaxhighlighter .line.alt1 {
- background-color: white !important;
-}
-.syntaxhighlighter .line.alt2 {
- background-color: white !important;
-}
-.syntaxhighlighter .line.highlighted.alt1, .syntaxhighlighter .line.highlighted.alt2 {
- background-color: #c3defe !important;
-}
-.syntaxhighlighter .line.highlighted.number {
- color: white !important;
-}
-.syntaxhighlighter table caption {
- color: black !important;
-}
-.syntaxhighlighter .gutter {
- color: #787878 !important;
-}
-.syntaxhighlighter .gutter .line {
- border-right: 3px solid #d4d0c8 !important;
-}
-.syntaxhighlighter .gutter .line.highlighted {
- background-color: #d4d0c8 !important;
- color: white !important;
-}
-.syntaxhighlighter.printing .line .content {
- border: none !important;
-}
-.syntaxhighlighter.collapsed {
- overflow: visible !important;
-}
-.syntaxhighlighter.collapsed .toolbar {
- color: #3f5fbf !important;
- background: white !important;
- border: 1px solid #d4d0c8 !important;
-}
-.syntaxhighlighter.collapsed .toolbar a {
- color: #3f5fbf !important;
-}
-.syntaxhighlighter.collapsed .toolbar a:hover {
- color: #aa7700 !important;
-}
-.syntaxhighlighter .toolbar {
- color: #a0a0a0 !important;
- background: #d4d0c8 !important;
- border: none !important;
-}
-.syntaxhighlighter .toolbar a {
- color: #a0a0a0 !important;
-}
-.syntaxhighlighter .toolbar a:hover {
- color: red !important;
-}
-.syntaxhighlighter .plain, .syntaxhighlighter .plain a {
- color: black !important;
-}
-.syntaxhighlighter .comments, .syntaxhighlighter .comments a {
- color: #3f5fbf !important;
-}
-.syntaxhighlighter .string, .syntaxhighlighter .string a {
- color: #2a00ff !important;
-}
-.syntaxhighlighter .keyword {
- color: #7f0055 !important;
-}
-.syntaxhighlighter .preprocessor {
- color: #646464 !important;
-}
-.syntaxhighlighter .variable {
- color: #aa7700 !important;
-}
-.syntaxhighlighter .value {
- color: #009900 !important;
-}
-.syntaxhighlighter .functions {
- color: #ff1493 !important;
-}
-.syntaxhighlighter .constants {
- color: #0066cc !important;
-}
-.syntaxhighlighter .script {
- font-weight: bold !important;
- color: #7f0055 !important;
- background-color: none !important;
-}
-.syntaxhighlighter .color1, .syntaxhighlighter .color1 a {
- color: gray !important;
-}
-.syntaxhighlighter .color2, .syntaxhighlighter .color2 a {
- color: #ff1493 !important;
-}
-.syntaxhighlighter .color3, .syntaxhighlighter .color3 a {
- color: red !important;
-}
-
-.syntaxhighlighter .keyword {
- font-weight: bold !important;
-}
-.syntaxhighlighter .xml .keyword {
- color: #3f7f7f !important;
- font-weight: normal !important;
-}
-.syntaxhighlighter .xml .color1, .syntaxhighlighter .xml .color1 a {
- color: #7f007f !important;
-}
-.syntaxhighlighter .xml .string {
- font-style: italic !important;
- color: #2a00ff !important;
-}
diff --git a/guides/assets/stylesheets/syntaxhighlighter/shThemeEmacs.css b/guides/assets/stylesheets/syntaxhighlighter/shThemeEmacs.css
deleted file mode 100644
index dae5053fea..0000000000
--- a/guides/assets/stylesheets/syntaxhighlighter/shThemeEmacs.css
+++ /dev/null
@@ -1,113 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- *
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-.syntaxhighlighter {
- background-color: black !important;
-}
-.syntaxhighlighter .line.alt1 {
- background-color: black !important;
-}
-.syntaxhighlighter .line.alt2 {
- background-color: black !important;
-}
-.syntaxhighlighter .line.highlighted.alt1, .syntaxhighlighter .line.highlighted.alt2 {
- background-color: #2a3133 !important;
-}
-.syntaxhighlighter .line.highlighted.number {
- color: white !important;
-}
-.syntaxhighlighter table caption {
- color: #d3d3d3 !important;
-}
-.syntaxhighlighter .gutter {
- color: #d3d3d3 !important;
-}
-.syntaxhighlighter .gutter .line {
- border-right: 3px solid #990000 !important;
-}
-.syntaxhighlighter .gutter .line.highlighted {
- background-color: #990000 !important;
- color: black !important;
-}
-.syntaxhighlighter.printing .line .content {
- border: none !important;
-}
-.syntaxhighlighter.collapsed {
- overflow: visible !important;
-}
-.syntaxhighlighter.collapsed .toolbar {
- color: #ebdb8d !important;
- background: black !important;
- border: 1px solid #990000 !important;
-}
-.syntaxhighlighter.collapsed .toolbar a {
- color: #ebdb8d !important;
-}
-.syntaxhighlighter.collapsed .toolbar a:hover {
- color: #ff7d27 !important;
-}
-.syntaxhighlighter .toolbar {
- color: white !important;
- background: #990000 !important;
- border: none !important;
-}
-.syntaxhighlighter .toolbar a {
- color: white !important;
-}
-.syntaxhighlighter .toolbar a:hover {
- color: #9ccff4 !important;
-}
-.syntaxhighlighter .plain, .syntaxhighlighter .plain a {
- color: #d3d3d3 !important;
-}
-.syntaxhighlighter .comments, .syntaxhighlighter .comments a {
- color: #ff7d27 !important;
-}
-.syntaxhighlighter .string, .syntaxhighlighter .string a {
- color: #ff9e7b !important;
-}
-.syntaxhighlighter .keyword {
- color: aqua !important;
-}
-.syntaxhighlighter .preprocessor {
- color: #aec4de !important;
-}
-.syntaxhighlighter .variable {
- color: #ffaa3e !important;
-}
-.syntaxhighlighter .value {
- color: #009900 !important;
-}
-.syntaxhighlighter .functions {
- color: #81cef9 !important;
-}
-.syntaxhighlighter .constants {
- color: #ff9e7b !important;
-}
-.syntaxhighlighter .script {
- font-weight: bold !important;
- color: aqua !important;
- background-color: none !important;
-}
-.syntaxhighlighter .color1, .syntaxhighlighter .color1 a {
- color: #ebdb8d !important;
-}
-.syntaxhighlighter .color2, .syntaxhighlighter .color2 a {
- color: #ff7d27 !important;
-}
-.syntaxhighlighter .color3, .syntaxhighlighter .color3 a {
- color: #aec4de !important;
-}
diff --git a/guides/assets/stylesheets/syntaxhighlighter/shThemeFadeToGrey.css b/guides/assets/stylesheets/syntaxhighlighter/shThemeFadeToGrey.css
deleted file mode 100644
index 8fbd871fb5..0000000000
--- a/guides/assets/stylesheets/syntaxhighlighter/shThemeFadeToGrey.css
+++ /dev/null
@@ -1,117 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- *
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-.syntaxhighlighter {
- background-color: #121212 !important;
-}
-.syntaxhighlighter .line.alt1 {
- background-color: #121212 !important;
-}
-.syntaxhighlighter .line.alt2 {
- background-color: #121212 !important;
-}
-.syntaxhighlighter .line.highlighted.alt1, .syntaxhighlighter .line.highlighted.alt2 {
- background-color: #2c2c29 !important;
-}
-.syntaxhighlighter .line.highlighted.number {
- color: white !important;
-}
-.syntaxhighlighter table caption {
- color: white !important;
-}
-.syntaxhighlighter .gutter {
- color: #afafaf !important;
-}
-.syntaxhighlighter .gutter .line {
- border-right: 3px solid #3185b9 !important;
-}
-.syntaxhighlighter .gutter .line.highlighted {
- background-color: #3185b9 !important;
- color: #121212 !important;
-}
-.syntaxhighlighter.printing .line .content {
- border: none !important;
-}
-.syntaxhighlighter.collapsed {
- overflow: visible !important;
-}
-.syntaxhighlighter.collapsed .toolbar {
- color: #3185b9 !important;
- background: black !important;
- border: 1px solid #3185b9 !important;
-}
-.syntaxhighlighter.collapsed .toolbar a {
- color: #3185b9 !important;
-}
-.syntaxhighlighter.collapsed .toolbar a:hover {
- color: #d01d33 !important;
-}
-.syntaxhighlighter .toolbar {
- color: white !important;
- background: #3185b9 !important;
- border: none !important;
-}
-.syntaxhighlighter .toolbar a {
- color: white !important;
-}
-.syntaxhighlighter .toolbar a:hover {
- color: #96daff !important;
-}
-.syntaxhighlighter .plain, .syntaxhighlighter .plain a {
- color: white !important;
-}
-.syntaxhighlighter .comments, .syntaxhighlighter .comments a {
- color: #696854 !important;
-}
-.syntaxhighlighter .string, .syntaxhighlighter .string a {
- color: #e3e658 !important;
-}
-.syntaxhighlighter .keyword {
- color: #d01d33 !important;
-}
-.syntaxhighlighter .preprocessor {
- color: #435a5f !important;
-}
-.syntaxhighlighter .variable {
- color: #898989 !important;
-}
-.syntaxhighlighter .value {
- color: #009900 !important;
-}
-.syntaxhighlighter .functions {
- color: #aaaaaa !important;
-}
-.syntaxhighlighter .constants {
- color: #96daff !important;
-}
-.syntaxhighlighter .script {
- font-weight: bold !important;
- color: #d01d33 !important;
- background-color: none !important;
-}
-.syntaxhighlighter .color1, .syntaxhighlighter .color1 a {
- color: #ffc074 !important;
-}
-.syntaxhighlighter .color2, .syntaxhighlighter .color2 a {
- color: #4a8cdb !important;
-}
-.syntaxhighlighter .color3, .syntaxhighlighter .color3 a {
- color: #96daff !important;
-}
-
-.syntaxhighlighter .functions {
- font-weight: bold !important;
-}
diff --git a/guides/assets/stylesheets/syntaxhighlighter/shThemeMDUltra.css b/guides/assets/stylesheets/syntaxhighlighter/shThemeMDUltra.css
deleted file mode 100755
index f4db39cd83..0000000000
--- a/guides/assets/stylesheets/syntaxhighlighter/shThemeMDUltra.css
+++ /dev/null
@@ -1,113 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- *
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-.syntaxhighlighter {
- background-color: #222222 !important;
-}
-.syntaxhighlighter .line.alt1 {
- background-color: #222222 !important;
-}
-.syntaxhighlighter .line.alt2 {
- background-color: #222222 !important;
-}
-.syntaxhighlighter .line.highlighted.alt1, .syntaxhighlighter .line.highlighted.alt2 {
- background-color: #253e5a !important;
-}
-.syntaxhighlighter .line.highlighted.number {
- color: white !important;
-}
-.syntaxhighlighter table caption {
- color: lime !important;
-}
-.syntaxhighlighter .gutter {
- color: #38566f !important;
-}
-.syntaxhighlighter .gutter .line {
- border-right: 3px solid #435a5f !important;
-}
-.syntaxhighlighter .gutter .line.highlighted {
- background-color: #435a5f !important;
- color: #222222 !important;
-}
-.syntaxhighlighter.printing .line .content {
- border: none !important;
-}
-.syntaxhighlighter.collapsed {
- overflow: visible !important;
-}
-.syntaxhighlighter.collapsed .toolbar {
- color: #428bdd !important;
- background: black !important;
- border: 1px solid #435a5f !important;
-}
-.syntaxhighlighter.collapsed .toolbar a {
- color: #428bdd !important;
-}
-.syntaxhighlighter.collapsed .toolbar a:hover {
- color: lime !important;
-}
-.syntaxhighlighter .toolbar {
- color: #aaaaff !important;
- background: #435a5f !important;
- border: none !important;
-}
-.syntaxhighlighter .toolbar a {
- color: #aaaaff !important;
-}
-.syntaxhighlighter .toolbar a:hover {
- color: #9ccff4 !important;
-}
-.syntaxhighlighter .plain, .syntaxhighlighter .plain a {
- color: lime !important;
-}
-.syntaxhighlighter .comments, .syntaxhighlighter .comments a {
- color: #428bdd !important;
-}
-.syntaxhighlighter .string, .syntaxhighlighter .string a {
- color: lime !important;
-}
-.syntaxhighlighter .keyword {
- color: #aaaaff !important;
-}
-.syntaxhighlighter .preprocessor {
- color: #8aa6c1 !important;
-}
-.syntaxhighlighter .variable {
- color: aqua !important;
-}
-.syntaxhighlighter .value {
- color: #f7e741 !important;
-}
-.syntaxhighlighter .functions {
- color: #ff8000 !important;
-}
-.syntaxhighlighter .constants {
- color: yellow !important;
-}
-.syntaxhighlighter .script {
- font-weight: bold !important;
- color: #aaaaff !important;
- background-color: none !important;
-}
-.syntaxhighlighter .color1, .syntaxhighlighter .color1 a {
- color: red !important;
-}
-.syntaxhighlighter .color2, .syntaxhighlighter .color2 a {
- color: yellow !important;
-}
-.syntaxhighlighter .color3, .syntaxhighlighter .color3 a {
- color: #ffaa3e !important;
-}
diff --git a/guides/assets/stylesheets/syntaxhighlighter/shThemeMidnight.css b/guides/assets/stylesheets/syntaxhighlighter/shThemeMidnight.css
deleted file mode 100644
index c49563cc9d..0000000000
--- a/guides/assets/stylesheets/syntaxhighlighter/shThemeMidnight.css
+++ /dev/null
@@ -1,113 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- *
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-.syntaxhighlighter {
- background-color: #0f192a !important;
-}
-.syntaxhighlighter .line.alt1 {
- background-color: #0f192a !important;
-}
-.syntaxhighlighter .line.alt2 {
- background-color: #0f192a !important;
-}
-.syntaxhighlighter .line.highlighted.alt1, .syntaxhighlighter .line.highlighted.alt2 {
- background-color: #253e5a !important;
-}
-.syntaxhighlighter .line.highlighted.number {
- color: #38566f !important;
-}
-.syntaxhighlighter table caption {
- color: #d1edff !important;
-}
-.syntaxhighlighter .gutter {
- color: #afafaf !important;
-}
-.syntaxhighlighter .gutter .line {
- border-right: 3px solid #435a5f !important;
-}
-.syntaxhighlighter .gutter .line.highlighted {
- background-color: #435a5f !important;
- color: #0f192a !important;
-}
-.syntaxhighlighter.printing .line .content {
- border: none !important;
-}
-.syntaxhighlighter.collapsed {
- overflow: visible !important;
-}
-.syntaxhighlighter.collapsed .toolbar {
- color: #428bdd !important;
- background: black !important;
- border: 1px solid #435a5f !important;
-}
-.syntaxhighlighter.collapsed .toolbar a {
- color: #428bdd !important;
-}
-.syntaxhighlighter.collapsed .toolbar a:hover {
- color: #1dc116 !important;
-}
-.syntaxhighlighter .toolbar {
- color: #d1edff !important;
- background: #435a5f !important;
- border: none !important;
-}
-.syntaxhighlighter .toolbar a {
- color: #d1edff !important;
-}
-.syntaxhighlighter .toolbar a:hover {
- color: #8aa6c1 !important;
-}
-.syntaxhighlighter .plain, .syntaxhighlighter .plain a {
- color: #d1edff !important;
-}
-.syntaxhighlighter .comments, .syntaxhighlighter .comments a {
- color: #428bdd !important;
-}
-.syntaxhighlighter .string, .syntaxhighlighter .string a {
- color: #1dc116 !important;
-}
-.syntaxhighlighter .keyword {
- color: #b43d3d !important;
-}
-.syntaxhighlighter .preprocessor {
- color: #8aa6c1 !important;
-}
-.syntaxhighlighter .variable {
- color: #ffaa3e !important;
-}
-.syntaxhighlighter .value {
- color: #f7e741 !important;
-}
-.syntaxhighlighter .functions {
- color: #ffaa3e !important;
-}
-.syntaxhighlighter .constants {
- color: #e0e8ff !important;
-}
-.syntaxhighlighter .script {
- font-weight: bold !important;
- color: #b43d3d !important;
- background-color: none !important;
-}
-.syntaxhighlighter .color1, .syntaxhighlighter .color1 a {
- color: #f8bb00 !important;
-}
-.syntaxhighlighter .color2, .syntaxhighlighter .color2 a {
- color: white !important;
-}
-.syntaxhighlighter .color3, .syntaxhighlighter .color3 a {
- color: #ffaa3e !important;
-}
diff --git a/guides/assets/stylesheets/syntaxhighlighter/shThemeRDark.css b/guides/assets/stylesheets/syntaxhighlighter/shThemeRDark.css
deleted file mode 100644
index 6305a10e4e..0000000000
--- a/guides/assets/stylesheets/syntaxhighlighter/shThemeRDark.css
+++ /dev/null
@@ -1,113 +0,0 @@
-/**
- * SyntaxHighlighter
- * http://alexgorbatchev.com/SyntaxHighlighter
- *
- * SyntaxHighlighter is donationware. If you are using it, please donate.
- * http://alexgorbatchev.com/SyntaxHighlighter/donate.html
- *
- * @version
- * 3.0.83 (July 02 2010)
- *
- * @copyright
- * Copyright (C) 2004-2010 Alex Gorbatchev.
- *
- * @license
- * Dual licensed under the MIT and GPL licenses.
- */
-.syntaxhighlighter {
- background-color: #1b2426 !important;
-}
-.syntaxhighlighter .line.alt1 {
- background-color: #1b2426 !important;
-}
-.syntaxhighlighter .line.alt2 {
- background-color: #1b2426 !important;
-}
-.syntaxhighlighter .line.highlighted.alt1, .syntaxhighlighter .line.highlighted.alt2 {
- background-color: #323e41 !important;
-}
-.syntaxhighlighter .line.highlighted.number {
- color: #b9bdb6 !important;
-}
-.syntaxhighlighter table caption {
- color: #b9bdb6 !important;
-}
-.syntaxhighlighter .gutter {
- color: #afafaf !important;
-}
-.syntaxhighlighter .gutter .line {
- border-right: 3px solid #435a5f !important;
-}
-.syntaxhighlighter .gutter .line.highlighted {
- background-color: #435a5f !important;
- color: #1b2426 !important;
-}
-.syntaxhighlighter.printing .line .content {
- border: none !important;
-}
-.syntaxhighlighter.collapsed {
- overflow: visible !important;
-}
-.syntaxhighlighter.collapsed .toolbar {
- color: #5ba1cf !important;
- background: black !important;
- border: 1px solid #435a5f !important;
-}
-.syntaxhighlighter.collapsed .toolbar a {
- color: #5ba1cf !important;
-}
-.syntaxhighlighter.collapsed .toolbar a:hover {
- color: #5ce638 !important;
-}
-.syntaxhighlighter .toolbar {
- color: white !important;
- background: #435a5f !important;
- border: none !important;
-}
-.syntaxhighlighter .toolbar a {
- color: white !important;
-}
-.syntaxhighlighter .toolbar a:hover {
- color: #e0e8ff !important;
-}
-.syntaxhighlighter .plain, .syntaxhighlighter .plain a {
- color: #b9bdb6 !important;
-}
-.syntaxhighlighter .comments, .syntaxhighlighter .comments a {
- color: #878a85 !important;
-}
-.syntaxhighlighter .string, .syntaxhighlighter .string a {
- color: #5ce638 !important;
-}
-.syntaxhighlighter .keyword {
- color: #5ba1cf !important;
-}
-.syntaxhighlighter .preprocessor {
- color: #435a5f !important;
-}
-.syntaxhighlighter .variable {
- color: #ffaa3e !important;
-}
-.syntaxhighlighter .value {
- color: #009900 !important;
-}
-.syntaxhighlighter .functions {
- color: #ffaa3e !important;
-}
-.syntaxhighlighter .constants {
- color: #e0e8ff !important;
-}
-.syntaxhighlighter .script {
- font-weight: bold !important;
- color: #5ba1cf !important;
- background-color: none !important;
-}
-.syntaxhighlighter .color1, .syntaxhighlighter .color1 a {
- color: #e0e8ff !important;
-}
-.syntaxhighlighter .color2, .syntaxhighlighter .color2 a {
- color: white !important;
-}
-.syntaxhighlighter .color3, .syntaxhighlighter .color3 a {
- color: #ffaa3e !important;
-}
diff --git a/guides/rails_guides/generator.rb b/guides/rails_guides/generator.rb
index 7618fce2c8..48ac90fca4 100644
--- a/guides/rails_guides/generator.rb
+++ b/guides/rails_guides/generator.rb
@@ -28,12 +28,12 @@
# enough:
#
# # generates only association_basics.html
-# ONLY=assoc ruby rails_guides.rb
+# ONLY=assoc rake guides:generate
#
# Separate many using commas:
#
-# # generates only association_basics.html and migrations.html
-# ONLY=assoc,migrations ruby rails_guides.rb
+# # generates only association_basics.html and command_line.html
+# ONLY=assoc,command rake guides:generate
#
# Note that if you are working on a guide generation will by default process
# only that one, so ONLY is rarely used nowadays.
diff --git a/guides/source/4_2_release_notes.md b/guides/source/4_2_release_notes.md
index 73e6c2c05b..a30bfc458a 100644
--- a/guides/source/4_2_release_notes.md
+++ b/guides/source/4_2_release_notes.md
@@ -871,7 +871,7 @@ Please refer to the [Changelog][active-support] for detailed changes.
`module Foo; extend ActiveSupport::Concern; end` boilerplate.
([Commit](https://github.com/rails/rails/commit/b16c36e688970df2f96f793a759365b248b582ad))
-* New [guide](constant_autoloading_and_reloading.html) about constant autoloading and reloading.
+* New [guide](autoloading_and_reloading_constants.html) about constant autoloading and reloading.
Credits
-------
diff --git a/guides/source/5_0_release_notes.md b/guides/source/5_0_release_notes.md
index 638547565c..b542005f52 100644
--- a/guides/source/5_0_release_notes.md
+++ b/guides/source/5_0_release_notes.md
@@ -37,23 +37,60 @@ Major Features
--------------
### Action Cable
-[Pull Request](https://github.com/rails/rails/pull/22586)
-ToDo...
+Action Cable is a new framework in Rails 5. It seamlessly integrates
+[WebSockets](https://en.wikipedia.org/wiki/WebSocket) with the rest of your
+Rails application.
-### Rails API
-[Pull Request](https://github.com/rails/rails/pull/19832)
+Action Cable allows for real-time features to be written in Ruby in the
+same style and form as the rest of your Rails application, while still being
+performant and scalable. It's a full-stack offering that provides both a
+client-side JavaScript framework and a server-side Ruby framework. You have
+access to your full domain model written with Active Record or your ORM of
+choice.
-ToDo...
+See the [Action Cable Overview](action_cable_overview.html) guide for more
+information.
+
+### API Applications
+
+Rails can now be used to create slimmed down API only applications.
+This is useful for creating and serving APIs similar to [Twitter](https://dev.twitter.com) or [GitHub](http://developer.github.com) API,
+that can be used to serve public facing, as well as, for custom applications.
+
+You can generate a new api Rails app using:
+
+```bash
+$ rails new my_api --api
+```
+
+This will do three main things:
+
+- Configure your application to start with a more limited set of middleware
+ than normal. Specifically, it will not include any middleware primarily useful
+ for browser applications (like cookies support) by default.
+- Make `ApplicationController` inherit from `ActionController::API` instead of
+ `ActionController::Base`. As with middleware, this will leave out any Action
+ Controller modules that provide functionalities primarily used by browser
+ applications.
+- Configure the generators to skip generating views, helpers and assets when
+ you generate a new resource.
+
+The application provides a base for APIs,
+that can then be [configured to pull in functionality](api_app.html) as suitable for the application's needs.
+
+See the [Using Rails for API-only Applications](api_app.html) guide for more
+information.
### Active Record attributes API
-Defines an attribute with a type on a model. It will override the type of existing attributes if needed.
+Defines an attribute with a type on a model. It will override the type of existing attributes if needed.
This allows control over how values are converted to and from SQL when assigned to a model.
-It also changes the behavior of values passed to ActiveRecord::Base.where, which lets use our domain objects across much of Active Record,
+It also changes the behavior of values passed to `ActiveRecord::Base.where`, which lets use our domain objects across much of Active Record,
without having to rely on implementation details or monkey patching.
Some things that you can achieve with this:
+
* The type detected by Active Record can be overridden.
* A default can also be provided.
* Attributes do not need to be backed by a database column.
@@ -80,7 +117,7 @@ class StoreListing < ActiveRecord::Base
attribute :price_in_cents, :integer # custom type
attribute :my_string, :string, default: "new default" # default value
attribute :my_default_proc, :datetime, default: -> { Time.now } # default value
- attribute :field_without_db_column, :integer, array: true
+ attribute :field_without_db_column, :integer, array: true
end
# after
@@ -94,34 +131,47 @@ model.attributes #=> {field_without_db_column: [1, 2, 3]}
**Creating Custom Types:**
You can define your own custom types, as long as they respond
-to the methods defined on the value type. The method +deserialize+ or
-+cast+ will be called on your type object, with raw input from the
-database or from your controllers. This is useful, for example, when doing custom conversion,
+to the methods defined on the value type. The method `deserialize` or
+`cast` will be called on your type object, with raw input from the
+database or from your controllers. This is useful, for example, when doing custom conversion,
like Money data.
**Querying:**
When `ActiveRecord::Base.where` is called, it will
use the type defined by the model class to convert the value to SQL,
-calling +serialize+ on your type object.
+calling `serialize` on your type object.
-This gives the objects ability to specify, how to convert values when performing SQL queries.
+This gives the objects ability to specify, how to convert values when performing SQL queries.
**Dirty Tracking:**
The type of an attribute is given the opportunity to change how dirty
-tracking is performed.
-
+tracking is performed.
+
See its
[documentation](http://api.rubyonrails.org/classes/ActiveRecord/Attributes/ClassMethods.html)
for a detailed write up.
### Test Runner
-[Pull Request](https://github.com/rails/rails/pull/19216)
-ToDo...
+A new test runner has been introduced to enhance the capabilities of running tests from Rails.
+To use this test runner simply type `bin/rails test`.
+
+Test Runner is inspired from `RSpec`, `minitest-reporters`, `maxitest` and others.
+It includes some of these notable advancements:
+- Run a single test using line number of test.
+- Run multiple tests pinpointing to line number of tests.
+- Improved failure messages, which also add ease of re-running failed tests.
+- Fail fast using `-f` option, to stop tests immediately on occurrence of failure,
+instead of waiting for the suite to complete.
+- Defer test output until the end of a full test run using the `-d` option.
+- Complete exception backtrace output using `-b` option.
+- Integration with `Minitest` to allow options like `-s` for test seed data,
+`-n` for running specific test by name, `-v` for better verbose output and so forth.
+- Colored test output
Railties
--------
@@ -208,6 +258,17 @@ Please refer to the [Changelog][railties] for detailed changes.
Spring to watch additional common files.
([commit](https://github.com/rails/rails/commit/b04d07337fd7bc17e88500e9d6bcd361885a45f8))
+* Added `--skip-action-mailer` to skip Action Mailer while generating new app.
+ ([Pull Request](https://github.com/rails/rails/pull/18288))
+
+* Removed `tmp/sessions` directory and the clear rake task associated with it.
+ ([Pull Request](https://github.com/rails/rails/pull/18314))
+
+* Changed `_form.html.erb` generated by scaffold generator to use local variables.
+ ([Pull Request](https://github.com/rails/rails/pull/13434))
+
+* Disabled autoloading of classes in production environment.
+ ([commit](https://github.com/rails/rails/commit/a71350cae0082193ad8c66d65ab62e8bb0b7853b))
Action Pack
-----------
@@ -300,6 +361,15 @@ Please refer to the [Changelog][action-pack] for detailed changes.
* Deprecated `:controller` and `:action` path parameters.
([Pull Request](https://github.com/rails/rails/pull/23980))
+* Deprecated env method on controller instances.
+ ([commit](https://github.com/rails/rails/commit/05934d24aff62d66fc62621aa38dae6456e276be))
+
+* `ActionDispatch::ParamsParser` is deprecated and was removed from the
+ middleware stack. To configure the parameter parsers use
+ `ActionDispatch::Request.parameter_parsers=`.
+ ([commit](https://github.com/rails/rails/commit/38d2bf5fd1f3e014f2397898d371c339baa627b1),
+ [commit](https://github.com/rails/rails/commit/5ed38014811d4ce6d6f957510b9153938370173b))
+
### Notable changes
* Added `ActionController::Renderer` to render arbitrary templates
@@ -371,6 +441,24 @@ Please refer to the [Changelog][action-pack] for detailed changes.
at the controller level.
([Pull Request](https://github.com/rails/rails/pull/24866))
+* Discarded flash messages get removed before storing into session.
+ ([Pull Request](https://github.com/rails/rails/pull/18721))
+
+* Added support for passing collection of records to `fresh_when` and
+ `stale?`.
+ ([Pull Request](https://github.com/rails/rails/pull/18374))
+
+* `ActionController::Live` became an `ActiveSupport::Concern`. That
+ means it can't be just included in other modules without extending
+ them with `ActiveSupport::Concern` or `ActionController::Live`
+ won't take effect in production. Some people may be using another
+ module to include some special `Warden`/`Devise` authentication
+ failure handling code as well since the middleware can't catch a
+ `:warden` thrown by a spawned thread which is the case when using
+ `ActionController::Live`.
+ ([More details in this issue](https://github.com/rails/rails/issues/25581))
+
+
Action View
-------------
@@ -390,13 +478,6 @@ Please refer to the [Changelog][action-view] for detailed changes.
supported by I18n.
([Pull Request](https://github.com/rails/rails/pull/20019))
-### Deprecations
-
-* Deprecated `datetime_field` and `datetime_field_tag` helpers.
- Datetime input type was removed from HTML specification.
- One can use `datetime_local_field` and `datetime_local_field_tag` instead.
- ([Pull Request](https://github.com/rails/rails/pull/24385))
-
### Notable Changes
* Changed the default template handler from `ERB` to `Raw`.
@@ -413,6 +494,13 @@ Please refer to the [Changelog][action-view] for detailed changes.
button on submit to prevent double submits.
([Pull Request](https://github.com/rails/rails/pull/21135))
+* Partial template name no longer has to be a valid Ruby identifier.
+ ([commit](https://github.com/rails/rails/commit/da9038e))
+
+* The `datetime_tag` helper now generates an input tag with the type of
+ `datetime-local`.
+ ([Pull Request](https://github.com/rails/rails/pull/25469))
+
Action Mailer
-------------
@@ -498,8 +586,10 @@ Please refer to the [Changelog][active-record] for detailed changes.
[activemodel-serializers-xml](https://github.com/rails/activemodel-serializers-xml)
gem. ([Pull Request](https://github.com/rails/rails/pull/21161))
-* Removed support for the legacy `mysql` database adapter from core. It will
- live on in a separate gem for now, but most users should just use `mysql2`.
+* Removed support for the legacy `mysql` database adapter from core. Most users should
+ be able to use `mysql2`. It will be converted to a separate gem when when we find someone
+ to maintain it. ([Pull Request 1](https://github.com/rails/rails/pull/22642)],
+ [Pull Request 2](https://github.com/rails/rails/pull/22715))
* Removed support for the `protected_attributes` gem.
([commit](https://github.com/rails/rails/commit/f4fbc0301021f13ae05c8e941c8efc4ae351fdf9))
@@ -507,6 +597,9 @@ Please refer to the [Changelog][active-record] for detailed changes.
* Removed support for PostgreSQL versions below 9.1.
([Pull Request](https://github.com/rails/rails/pull/23434))
+* Removed support for `activerecord-deprecated_finders` gem.
+ ([commit](https://github.com/rails/rails/commit/78dab2a8569408658542e462a957ea5a35aa4679))
+
### Deprecations
* Deprecated passing a class as a value in a query. Users should pass strings
@@ -568,6 +661,14 @@ Please refer to the [Changelog][active-record] for detailed changes.
`use_transactional_tests` for more clarity.
([Pull Request](https://github.com/rails/rails/pull/19282))
+* Deprecated passing a column to `ActiveRecord::Connection#quote`.
+ ([commit](https://github.com/rails/rails/commit/7bb620869725ad6de603f6a5393ee17df13aa96c))
+
+* Added an option `end` to `find_in_batches` that complements the `start`
+ parameter to specify where to stop batch processing.
+ ([Pull Request](https://github.com/rails/rails/pull/12257))
+
+
### Notable changes
* Added a `foreign_key` option to `references` while creating the table.
@@ -671,10 +772,38 @@ Please refer to the [Changelog][active-record] for detailed changes.
with comments stored in database metadata for PostgreSQL & MySQL.
([Pull Request](https://github.com/rails/rails/pull/22911))
-* Added prepared statements support to `mysql2` adapter, for mysql2 0.4.4+,
- Previously this was only supported on the deprecated `mysql` legacy adapter.
+* Added prepared statements support to `mysql2` adapter, for mysql2 0.4.4+,
+ Previously this was only supported on the deprecated `mysql` legacy adapter.
To enable, set `prepared_statements: true` in config/database.yml.
- ([Pull Request](https://github.com/rails/rails/pull/23461))
+ ([Pull Request](https://github.com/rails/rails/pull/23461))
+
+* Added ability to call `ActionRecord::Relation#update` on relation objects
+ which will run validations on callbacks on all objects in the relation.
+ ([Pull Request](https://github.com/rails/rails/pull/11898))
+
+* Added `:touch` option to the `save` method so that records can be saved without
+ updating timestamps.
+ ([Pull Request](https://github.com/rails/rails/pull/18225))
+
+* Added expression indexes and operator classes support for PostgreSQL.
+ ([commit](https://github.com/rails/rails/commit/edc2b7718725016e988089b5fb6d6fb9d6e16882))
+
+* Added `:index_errors` option to add indexes to errors of nested attributes.
+ ([Pull Request](https://github.com/rails/rails/pull/19686))
+
+* Added support for bidirectional destroy dependencies.
+ ([Pull Request](https://github.com/rails/rails/pull/18548))
+
+* Added support for `after_commit` callbacks in transactional tests.
+ ([Pull Request](https://github.com/rails/rails/pull/18458))
+
+* Added `foreign_key_exists?` method to see if a foreign key exists on a table
+ or not.
+ ([Pull Request](https://github.com/rails/rails/pull/18662))
+
+* Added `:time` option to `touch` method to touch records with different time
+ than the current time.
+ ([Pull Request](https://github.com/rails/rails/pull/18956))
Active Model
------------
@@ -691,6 +820,9 @@ Please refer to the [Changelog][active-model] for detailed changes.
[activemodel-serializers-xml](https://github.com/rails/activemodel-serializers-xml) gem.
([Pull Request](https://github.com/rails/rails/pull/21161))
+* Removed `ActionController::ModelNaming` module.
+ ([Pull Request](https://github.com/rails/rails/pull/18194))
+
### Deprecations
* Deprecated returning `false` as a way to halt Active Model and
@@ -726,6 +858,9 @@ Please refer to the [Changelog][active-model] for detailed changes.
* Validate multiple contexts on `valid?` and `invalid?` at once.
([Pull Request](https://github.com/rails/rails/pull/21069))
+* Change `validates_acceptance_of` to accept `true` as default value
+ apart from `1`.
+ ([Pull Request](https://github.com/rails/rails/pull/18439))
Active Job
-----------
@@ -797,6 +932,9 @@ Please refer to the [Changelog][active-support] for detailed changes.
* Removed deprecated `ThreadSafe::Cache`. Use `Concurrent::Map` instead.
([Pull Request](https://github.com/rails/rails/pull/21679))
+* Removed `Object#itself` as it is implemented in Ruby 2.2.
+ ([Pull Request](https://github.com/rails/rails/pull/18244))
+
### Deprecations
* Deprecated `MissingSourceFile` in favor of `LoadError`.
@@ -918,6 +1056,16 @@ Please refer to the [Changelog][active-support] for detailed changes.
* `ActiveSupport::Duration` now supports ISO8601 formatting and parsing.
([Pull Request](https://github.com/rails/rails/pull/16917))
+* `ActiveSupport::JSON.decode` now supports parsing ISO8601 local times when
+ `parse_json_times` is enabled.
+ ([Pull Request](https://github.com/rails/rails/pull/23011))
+
+* `ActiveSupport::JSON.decode` now return `Date` objects for date strings.
+ ([Pull Request](https://github.com/rails/rails/pull/23011))
+
+* Added ability to `TaggedLogging` to allow loggers to be instantiated multiple
+ times so that they don't share tags with each other.
+ ([Pull Request](https://github.com/rails/rails/pull/9065))
Credits
-------
diff --git a/guides/source/action_cable_overview.md b/guides/source/action_cable_overview.md
index c7770c16ea..0d00b7f07b 100644
--- a/guides/source/action_cable_overview.md
+++ b/guides/source/action_cable_overview.md
@@ -6,8 +6,12 @@ incorporate real-time features into your Rails application.
After reading this guide, you will know:
+* What Action Cable is and its integration on backend and frontend
* How to setup Action Cable
* How to setup channels
+* Deployment and Architecture setup for running Action Cable
+
+--------------------------------------------------------------------------------
Introduction
------------
@@ -82,7 +86,7 @@ The cookie is then automatically sent to the connection instance when a new conn
is attempted, and you use that to set the `current_user`. By identifying the connection
by this same current user, you're also ensuring that you can later retrieve all open
connections by a given user (and potentially disconnect them all if the user is deleted
-or deauthorized).
+or unauthorized).
### Channels
@@ -568,12 +572,13 @@ environment configuration files.
### Other Configurations
-The other common option to configure is the log tags applied to the
-per-connection logger. Here's close to what we're using in Basecamp:
+The other common option to configure, is the log tags applied to the
+per-connection logger. Here's an example that uses
+the user account id if available, else "no-account" while tagging:
```ruby
config.action_cable.log_tags = [
- -> request { request.env['bc.account_id'] || "no-account" },
+ -> request { request.env['user_account_id'] || "no-account" },
:action_cable,
-> request { request.uuid }
]
diff --git a/guides/source/action_controller_overview.md b/guides/source/action_controller_overview.md
index a906f64633..58362fea58 100644
--- a/guides/source/action_controller_overview.md
+++ b/guides/source/action_controller_overview.md
@@ -21,7 +21,7 @@ After reading this guide, you will know:
What Does a Controller Do?
--------------------------
-Action Controller is the C in MVC. After routing has determined which controller to use for a request, the controller is responsible for making sense of the request and producing the appropriate output. Luckily, Action Controller does most of the groundwork for you and uses smart conventions to make this as straightforward as possible.
+Action Controller is the C in MVC. After the router has determined which controller to use for a request, the controller is responsible for making sense of the request and producing the appropriate output. Luckily, Action Controller does most of the groundwork for you and uses smart conventions to make this as straightforward as possible.
For most conventional [RESTful](http://en.wikipedia.org/wiki/Representational_state_transfer) applications, the controller will receive the request (this is invisible to you as the developer), fetch or save data from a model and use a view to create HTML output. If your controller needs to do things a little differently, that's not a problem, this is just the most common way for a controller to work.
@@ -145,7 +145,7 @@ So for example, if you are sending this JSON content:
Your controller will receive `params[:company]` as `{ "name" => "acme", "address" => "123 Carrot Street" }`.
-Also, if you've turned on `config.wrap_parameters` in your initializer or called `wrap_parameters` in your controller, you can safely omit the root element in the JSON parameter. In this case, the parameters will be cloned and wrapped with a key chosen based on your controller's name. So the above JSON POST can be written as:
+Also, if you've turned on `config.wrap_parameters` in your initializer or called `wrap_parameters` in your controller, you can safely omit the root element in the JSON parameter. In this case, the parameters will be cloned and wrapped with a key chosen based on your controller's name. So the above JSON request can be written as:
```json
{ "name": "acme", "address": "123 Carrot Street" }
@@ -199,7 +199,8 @@ practice to help prevent accidentally allowing users to update sensitive
model attributes.
In addition, parameters can be marked as required and will flow through a
-predefined raise/rescue flow to end up as a 400 Bad Request.
+predefined raise/rescue flow that will result in a 400 Bad Request being
+returned if not all required parameters are passed in.
```ruby
class PeopleController < ActionController::Base
@@ -213,8 +214,8 @@ class PeopleController < ActionController::Base
# This will pass with flying colors as long as there's a person key
# in the parameters, otherwise it'll raise a
# ActionController::ParameterMissing exception, which will get
- # caught by ActionController::Base and turned into that 400 Bad
- # Request reply.
+ # caught by ActionController::Base and turned into a 400 Bad
+ # Request error.
def update
person = current_account.people.find(params[:id])
person.update!(person_params)
@@ -814,7 +815,7 @@ In every controller there are two accessor methods pointing to the request and t
### The `request` Object
-The request object contains a lot of useful information about the request coming in from the client. To get a full list of the available methods, refer to the [API documentation](http://api.rubyonrails.org/classes/ActionDispatch/Request.html). Among the properties that you can access on this object are:
+The request object contains a lot of useful information about the request coming in from the client. To get a full list of the available methods, refer to the [Rails API documentation](http://api.rubyonrails.org/classes/ActionDispatch/Request.html) and [Rack Documentation](http://www.rubydoc.info/github/rack/rack/Rack/Request). Among the properties that you can access on this object are:
| Property of `request` | Purpose |
| ----------------------------------------- | -------------------------------------------------------------------------------- |
@@ -836,7 +837,7 @@ Rails collects all of the parameters sent along with the request in the `params`
### The `response` Object
-The response object is not usually used directly, but is built up during the execution of the action and rendering of the data that is being sent back to the user, but sometimes - like in an after filter - it can be useful to access the response directly. Some of these accessor methods also have setters, allowing you to change their values.
+The response object is not usually used directly, but is built up during the execution of the action and rendering of the data that is being sent back to the user, but sometimes - like in an after filter - it can be useful to access the response directly. Some of these accessor methods also have setters, allowing you to change their values. To get a full list of the available methods, refer to the [Rails API documentation](http://api.rubyonrails.org/classes/ActionDispatch/Response.html) and [Rack Documentation](http://www.rubydoc.info/github/rack/rack/Rack/Response).
| Property of `response` | Purpose |
| ---------------------- | --------------------------------------------------------------------------------------------------- |
diff --git a/guides/source/action_mailer_basics.md b/guides/source/action_mailer_basics.md
index 5346b7c32b..7359438025 100644
--- a/guides/source/action_mailer_basics.md
+++ b/guides/source/action_mailer_basics.md
@@ -734,7 +734,7 @@ files (environment.rb, production.rb, etc...)
| Configuration | Description |
|---------------|-------------|
|`logger`|Generates information on the mailing run if available. Can be set to `nil` for no logging. Compatible with both Ruby's own `Logger` and `Log4r` loggers.|
-|`smtp_settings`|Allows detailed configuration for `:smtp` delivery method:<ul><li>`:address` - Allows you to use a remote mail server. Just change it from its default `"localhost"` setting.</li><li>`:port` - On the off chance that your mail server doesn't run on port 25, you can change it.</li><li>`:domain` - If you need to specify a HELO domain, you can do it here.</li><li>`:user_name` - If your mail server requires authentication, set the username in this setting.</li><li>`:password` - If your mail server requires authentication, set the password in this setting.</li><li>`:authentication` - If your mail server requires authentication, you need to specify the authentication type here. This is a symbol and one of `:plain` (will send the password in the clear), `:login` (will send password Base64 encoded) or `:cram_md5` (combines a Challenge/Response mechanism to exchange information and a cryptographic Message Digest 5 algorithm to hash important information)</li><li>`:enable_starttls_auto` - Detects if STARTTLS is enabled in your SMTP server and starts to use it. Defaults to `true`.</li><li>`:openssl_verify_mode` - When using TLS, you can set how OpenSSL checks the certificate. This is really useful if you need to validate a self-signed and/or a wildcard certificate. You can use the name of an OpenSSL verify constant ('none', 'peer', 'client_once', 'fail_if_no_peer_cert') or directly the constant (`OpenSSL::SSL::VERIFY_NONE`, `OpenSSL::SSL::VERIFY_PEER`, ...).</li></ul>|
+|`smtp_settings`|Allows detailed configuration for `:smtp` delivery method:<ul><li>`:address` - Allows you to use a remote mail server. Just change it from its default `"localhost"` setting.</li><li>`:port` - On the off chance that your mail server doesn't run on port 25, you can change it.</li><li>`:domain` - If you need to specify a HELO domain, you can do it here.</li><li>`:user_name` - If your mail server requires authentication, set the username in this setting.</li><li>`:password` - If your mail server requires authentication, set the password in this setting.</li><li>`:authentication` - If your mail server requires authentication, you need to specify the authentication type here. This is a symbol and one of `:plain` (will send the password in the clear), `:login` (will send password Base64 encoded) or `:cram_md5` (combines a Challenge/Response mechanism to exchange information and a cryptographic Message Digest 5 algorithm to hash important information)</li><li>`:enable_starttls_auto` - Detects if STARTTLS is enabled in your SMTP server and starts to use it. Defaults to `true`.</li><li>`:openssl_verify_mode` - When using TLS, you can set how OpenSSL checks the certificate. This is really useful if you need to validate a self-signed and/or a wildcard certificate. You can use the name of an OpenSSL verify constant ('none' or 'peer') or directly the constant (`OpenSSL::SSL::VERIFY_NONE` or `OpenSSL::SSL::VERIFY_PEER`).</li></ul>|
|`sendmail_settings`|Allows you to override options for the `:sendmail` delivery method.<ul><li>`:location` - The location of the sendmail executable. Defaults to `/usr/sbin/sendmail`.</li><li>`:arguments` - The command line arguments to be passed to sendmail. Defaults to `-i -t`.</li></ul>|
|`raise_delivery_errors`|Whether or not errors should be raised if the email fails to be delivered. This only works if the external email server is configured for immediate delivery.|
|`delivery_method`|Defines a delivery method. Possible values are:<ul><li>`:smtp` (default), can be configured by using `config.action_mailer.smtp_settings`.</li><li>`:sendmail`, can be configured by using `config.action_mailer.sendmail_settings`.</li><li>`:file`: save emails to files; can be configured by using `config.action_mailer.file_settings`.</li><li>`:test`: save emails to `ActionMailer::Base.deliveries` array.</li></ul>See [API docs](http://api.rubyonrails.org/classes/ActionMailer/Base.html) for more info.|
diff --git a/guides/source/action_view_overview.md b/guides/source/action_view_overview.md
index 0e6bb76101..f68abbae3c 100644
--- a/guides/source/action_view_overview.md
+++ b/guides/source/action_view_overview.md
@@ -15,7 +15,7 @@ After reading this guide, you will know:
What is Action View?
--------------------
-In Rails, web requests are handled by [Action Controller](action_controller_overview.html) and Action View. Typically, Action Controller will be concerned with communicating with the database and performing CRUD actions where necessary. Action View is then responsible for compiling the response.
+In Rails, web requests are handled by [Action Controller](action_controller_overview.html) and Action View. Typically, Action Controller is concerned with communicating with the database and performing CRUD actions where necessary. Action View is then responsible for compiling the response.
Action View templates are written using embedded Ruby in tags mingled with HTML. To avoid cluttering the templates with boilerplate code, a number of helper classes provide common behavior for forms, dates, and strings. It's also easy to add new helpers to your application as it evolves.
diff --git a/guides/source/active_job_basics.md b/guides/source/active_job_basics.md
index d6de92ace6..c9f70dc87b 100644
--- a/guides/source/active_job_basics.md
+++ b/guides/source/active_job_basics.md
@@ -62,12 +62,12 @@ $ bin/rails generate job guests_cleanup --queue urgent
```
If you don't want to use a generator, you could create your own file inside of
-`app/jobs`, just make sure that it inherits from `ActiveJob::Base`.
+`app/jobs`, just make sure that it inherits from `ApplicationJob`.
Here's what a job looks like:
```ruby
-class GuestsCleanupJob < ActiveJob::Base
+class GuestsCleanupJob < ApplicationJob
queue_as :default
def perform(*guests)
@@ -141,7 +141,7 @@ end
You can also configure your backend on a per job basis.
```ruby
-class GuestsCleanupJob < ActiveJob::Base
+class GuestsCleanupJob < ApplicationJob
self.queue_adapter = :resque
#....
end
@@ -171,7 +171,7 @@ Most of the adapters support multiple queues. With Active Job you can schedule
the job to run on a specific queue:
```ruby
-class GuestsCleanupJob < ActiveJob::Base
+class GuestsCleanupJob < ApplicationJob
queue_as :low_priority
#....
end
@@ -189,7 +189,7 @@ module YourApp
end
# app/jobs/guests_cleanup_job.rb
-class GuestsCleanupJob < ActiveJob::Base
+class GuestsCleanupJob < ApplicationJob
queue_as :low_priority
#....
end
@@ -212,7 +212,7 @@ module YourApp
end
# app/jobs/guests_cleanup_job.rb
-class GuestsCleanupJob < ActiveJob::Base
+class GuestsCleanupJob < ApplicationJob
queue_as :low_priority
#....
end
@@ -234,7 +234,7 @@ block will be executed in the job context (so you can access `self.arguments`)
and you must return the queue name:
```ruby
-class ProcessVideoJob < ActiveJob::Base
+class ProcessVideoJob < ApplicationJob
queue_as do
video = self.arguments.first
if video.owner.premium?
@@ -274,7 +274,7 @@ trigger logic during the life cycle of a job.
### Usage
```ruby
-class GuestsCleanupJob < ActiveJob::Base
+class GuestsCleanupJob < ApplicationJob
queue_as :default
before_enqueue do |job|
@@ -331,7 +331,7 @@ Active Record objects to your job instead of class/id pairs, which you then have
to manually deserialize. Before, jobs would look like this:
```ruby
-class TrashableCleanupJob < ActiveJob::Base
+class TrashableCleanupJob < ApplicationJob
def perform(trashable_class, trashable_id, depth)
trashable = trashable_class.constantize.find(trashable_id)
trashable.cleanup(depth)
@@ -342,7 +342,7 @@ end
Now you can simply do:
```ruby
-class TrashableCleanupJob < ActiveJob::Base
+class TrashableCleanupJob < ApplicationJob
def perform(trashable, depth)
trashable.cleanup(depth)
end
@@ -360,7 +360,7 @@ Active Job provides a way to catch exceptions raised during the execution of the
job:
```ruby
-class GuestsCleanupJob < ActiveJob::Base
+class GuestsCleanupJob < ApplicationJob
queue_as :default
rescue_from(ActiveRecord::RecordNotFound) do |exception|
diff --git a/guides/source/active_record_callbacks.md b/guides/source/active_record_callbacks.md
index fb5d2065d3..a7975c7772 100644
--- a/guides/source/active_record_callbacks.md
+++ b/guides/source/active_record_callbacks.md
@@ -399,7 +399,7 @@ By using the `after_commit` callback we can account for this case.
```ruby
class PictureFile < ApplicationRecord
- after_commit :delete_picture_file_from_disk, on: [:destroy]
+ after_commit :delete_picture_file_from_disk, on: :destroy
def delete_picture_file_from_disk
if File.exist?(filepath)
@@ -409,7 +409,7 @@ class PictureFile < ApplicationRecord
end
```
-NOTE: the `:on` option specifies when a callback will be fired. If you
+NOTE: The `:on` option specifies when a callback will be fired. If you
don't supply the `:on` option the callback will fire for every action.
Since using `after_commit` callback only on create, update or delete is
diff --git a/guides/source/active_record_postgresql.md b/guides/source/active_record_postgresql.md
index dee64e6439..d7e35490ef 100644
--- a/guides/source/active_record_postgresql.md
+++ b/guides/source/active_record_postgresql.md
@@ -503,9 +503,9 @@ second = Article.create! title: "Brace yourself",
status: "draft",
published_at: 1.month.ago
-Article.count # => 1
-first.archive!
Article.count # => 2
+first.archive!
+Article.count # => 1
```
NOTE: This application only cares about non-archived `Articles`. A view also
diff --git a/guides/source/active_record_validations.md b/guides/source/active_record_validations.md
index 936d6a30b8..2737237c1a 100644
--- a/guides/source/active_record_validations.md
+++ b/guides/source/active_record_validations.md
@@ -392,7 +392,8 @@ The `exclusion` helper has an option `:in` that receives the set of values that
will not be accepted for the validated attributes. The `:in` option has an
alias called `:within` that you can use for the same purpose, if you'd like to.
This example uses the `:message` option to show how you can include the
-attribute's value.
+attribute's value. For full options to the message argument please see the
+[message documentation](#message).
The default error message is _"is reserved"_.
@@ -427,7 +428,8 @@ end
The `inclusion` helper has an option `:in` that receives the set of values that
will be accepted. The `:in` option has an alias called `:within` that you can
use for the same purpose, if you'd like to. The previous example uses the
-`:message` option to show how you can include the attribute's value.
+`:message` option to show how you can include the attribute's value. For full
+options please see the [message documentation](#message).
The default error message for this helper is _"is not included in the list"_.
@@ -768,6 +770,9 @@ class Coffee < ApplicationRecord
end
```
+For full options to the message argument please see the
+[message documentation](#message).
+
### `:allow_blank`
The `:allow_blank` option is similar to the `:allow_nil` option. This option
@@ -792,7 +797,8 @@ for each validation helper. The `:message` option accepts a `String` or `Proc`.
A `String` `:message` value can optionally contain any/all of `%{value}`,
`%{attribute}`, and `%{model}` which will be dynamically replaced when
-validation fails.
+validation fails. This replacement is done using the I18n gem, and the
+placeholders must match exactly, no spaces are allowed.
A `Proc` `:message` value is given two arguments: the object being validated, and
a hash with `:model`, `:attribute`, and `:value` key-value pairs.
diff --git a/guides/source/active_support_core_extensions.md b/guides/source/active_support_core_extensions.md
index 565c87c4b5..e0b6f2f820 100644
--- a/guides/source/active_support_core_extensions.md
+++ b/guides/source/active_support_core_extensions.md
@@ -954,7 +954,8 @@ class A
class_attribute :x, instance_reader: false
end
-A.new.x = 1 # NoMethodError
+A.new.x = 1
+A.new.x # NoMethodError
```
For convenience `class_attribute` also defines an instance predicate which is the double negation of what the instance reader returns. In the examples above it would be called `x?`.
diff --git a/guides/source/api_app.md b/guides/source/api_app.md
index 485294dc02..f373d313cc 100644
--- a/guides/source/api_app.md
+++ b/guides/source/api_app.md
@@ -212,6 +212,7 @@ An API application comes with the following middleware by default:
- `ActionDispatch::RemoteIp`
- `ActionDispatch::Reloader`
- `ActionDispatch::Callbacks`
+- `ActiveRecord::Migration::CheckPending`
- `Rack::Head`
- `Rack::ConditionalGet`
- `Rack::ETag`
@@ -339,7 +340,7 @@ API application, especially if one of your API clients is the browser:
- `Rack::MethodOverride`
- `ActionDispatch::Cookies`
- `ActionDispatch::Flash`
-- For sessions management
+- For session management
* `ActionDispatch::Session::CacheStore`
* `ActionDispatch::Session::CookieStore`
* `ActionDispatch::Session::MemCacheStore`
@@ -373,10 +374,8 @@ controller modules by default:
- `AbstractController::Rendering` and `ActionController::ApiRendering`: Basic support for rendering.
- `ActionController::Renderers::All`: Support for `render :json` and friends.
- `ActionController::ConditionalGet`: Support for `stale?`.
-- `ActionController::BasicImplicitRender`: Makes sure to return an empty response
- if there's not an explicit one.
-- `ActionController::StrongParameters`: Support for parameters white-listing in
- combination with Active Model mass assignment.
+- `ActionController::BasicImplicitRender`: Makes sure to return an empty response, if there isn't an explicit one.
+- `ActionController::StrongParameters`: Support for parameters white-listing in combination with Active Model mass assignment.
- `ActionController::ForceSSL`: Support for `force_ssl`.
- `ActionController::DataStreaming`: Support for `send_file` and `send_data`.
- `AbstractController::Callbacks`: Support for `before_action` and
@@ -386,8 +385,8 @@ controller modules by default:
hooks defined by Action Controller (see [the instrumentation
guide](active_support_instrumentation.html#action-controller) for
more information regarding this).
-- `ActionController::ParamsWrapper`: Wraps the parameters hash into a nested hash
- so you don't have to specify root elements sending POST requests for instance.
+- `ActionController::ParamsWrapper`: Wraps the parameters hash into a nested hash,
+ so that you don't have to specify root elements sending POST requests for instance.
Other plugins may add additional modules. You can get a list of all modules
included into `ActionController::API` in the rails console:
diff --git a/guides/source/api_documentation_guidelines.md b/guides/source/api_documentation_guidelines.md
index 5b34330936..34b9c0d2ca 100644
--- a/guides/source/api_documentation_guidelines.md
+++ b/guides/source/api_documentation_guidelines.md
@@ -20,7 +20,7 @@ The [Rails API documentation](http://api.rubyonrails.org) is generated with
in the rails root directory, run `bundle install` and execute:
```bash
- ./bin/rails rdoc
+ bundle exec rake rdoc
```
Resulting HTML files can be found in the ./doc/rdoc directory.
diff --git a/guides/source/command_line.md b/guides/source/command_line.md
index 0e6d119681..f766403228 100644
--- a/guides/source/command_line.md
+++ b/guides/source/command_line.md
@@ -433,7 +433,7 @@ Ruby version 2.2.2 (x86_64-linux)
RubyGems version 2.4.6
Rack version 1.6
JavaScript Runtime Node.js (V8)
-Middleware Rack::Sendfile, ActionDispatch::Static, ActionDispatch::Executor, #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x007ffd131a7c88>, Rack::Runtime, Rack::MethodOverride, ActionDispatch::RequestId, Rails::Rack::Logger, ActionDispatch::ShowExceptions, ActionDispatch::DebugExceptions, ActionDispatch::RemoteIp, ActionDispatch::Reloader, ActionDispatch::Callbacks, ActiveRecord::Migration::CheckPending, ActiveRecord::ConnectionAdapters::ConnectionManagement, ActiveRecord::QueryCache, ActionDispatch::Cookies, ActionDispatch::Session::CookieStore, ActionDispatch::Flash, Rack::Head, Rack::ConditionalGet, Rack::ETag
+Middleware Rack::Sendfile, ActionDispatch::Static, ActionDispatch::Executor, #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x007ffd131a7c88>, Rack::Runtime, Rack::MethodOverride, ActionDispatch::RequestId, Rails::Rack::Logger, ActionDispatch::ShowExceptions, ActionDispatch::DebugExceptions, ActionDispatch::RemoteIp, ActionDispatch::Reloader, ActionDispatch::Callbacks, ActiveRecord::Migration::CheckPending, ActionDispatch::Cookies, ActionDispatch::Session::CookieStore, ActionDispatch::Flash, Rack::Head, Rack::ConditionalGet, Rack::ETag
Application root /home/foobar/commandsapp
Environment development
Database adapter sqlite3
diff --git a/guides/source/configuring.md b/guides/source/configuring.md
index 66aae112d8..59cf412c5f 100644
--- a/guides/source/configuring.md
+++ b/guides/source/configuring.md
@@ -94,6 +94,8 @@ application. Accepts a valid week day symbol (e.g. `:monday`).
* `config.eager_load_paths` accepts an array of paths from which Rails will eager load on boot if cache classes is enabled. Defaults to every folder in the `app` directory of the application.
+* `config.enable_dependency_loading`: when true, enables autoloading, even if the application is eager loaded and `config.cache_classes` is set as true. Defaults to false.
+
* `config.encoding` sets up the application-wide encoding. Defaults to UTF-8.
* `config.exceptions_app` sets the exceptions application invoked by the ShowException middleware when an exception happens. Defaults to `ActionDispatch::PublicExceptions.new(Rails.public_path)`.
@@ -224,8 +226,6 @@ Every Rails application comes with a standard set of middleware which it uses in
* `ActionDispatch::RemoteIp` checks for IP spoofing attacks and gets valid `client_ip` from request headers. Configurable with the `config.action_dispatch.ip_spoofing_check`, and `config.action_dispatch.trusted_proxies` options.
* `Rack::Sendfile` intercepts responses whose body is being served from a file and replaces it with a server specific X-Sendfile header. Configurable with `config.action_dispatch.x_sendfile_header`.
* `ActionDispatch::Callbacks` runs the prepare callbacks before serving the request.
-* `ActiveRecord::ConnectionAdapters::ConnectionManagement` cleans active connections after each request, unless the `rack.test` key in the request environment is set to `true`.
-* `ActiveRecord::QueryCache` caches all SELECT queries generated in a request. If any INSERT or UPDATE takes place then the cache is cleaned.
* `ActionDispatch::Cookies` sets cookies for the request.
* `ActionDispatch::Session::CookieStore` is responsible for storing the session in cookies. An alternate middleware can be used for this by changing the `config.action_controller.session_store` to an alternate value. Additionally, options passed to this can be configured by using `config.action_controller.session_options`.
* `ActionDispatch::Flash` sets up the `flash` keys. Only available if `config.action_controller.session_store` is set to a value.
@@ -244,6 +244,12 @@ This will put the `Magical::Unicorns` middleware on the end of the stack. You ca
config.middleware.insert_before Rack::Head, Magical::Unicorns
```
+Or you can insert a middleware to exact position by using indexes. For example, if you want to insert `Magical::Unicorns` middleware on top of the stack, you can do it, like so:
+
+```ruby
+config.middleware.insert_before 0, Magical::Unicorns
+```
+
There's also `insert_after` which will insert a middleware after another:
```ruby
@@ -274,6 +280,26 @@ All these configuration options are delegated to the `I18n` library.
* `config.i18n.load_path` sets the path Rails uses to look for locale files. Defaults to `config/locales/*.{yml,rb}`.
+* `config.i18n.fallbacks` sets fallback behavior for missing translations. Here are 3 usage examples for this option:
+
+ * You can set the option to `true` for using default locale as fallback, like so:
+
+ ```ruby
+ config.i18n.fallbacks = true
+ ```
+
+ * Or you can set an array of locales as fallback, like so:
+
+ ```ruby
+ config.i18n.fallbacks = [:tr, :en]
+ ```
+
+ * Or you can set different fallbacks for locales individually. For example, if you want to use `:tr` for `:az` and `:de`, `:en` for `:da` as fallbacks, you can do it, like so:
+
+ ```ruby
+ config.i18n.fallbacks = { az: :tr, da: [:de, :en] }
+ ```
+
### Configuring Active Record
`config.active_record` includes a variety of configuration options:
@@ -500,7 +526,7 @@ There are a number of settings available on `config.action_mailer`:
* `:password` - If your mail server requires authentication, set the password in this setting.
* `:authentication` - If your mail server requires authentication, you need to specify the authentication type here. This is a symbol and one of `:plain`, `:login`, `:cram_md5`.
* `:enable_starttls_auto` - Detects if STARTTLS is enabled in your SMTP server and starts to use it. It defaults to `true`.
- * `:openssl_verify_mode` - When using TLS, you can set how OpenSSL checks the certificate. This is useful if you need to validate a self-signed and/or a wildcard certificate. This can be one of the OpenSSL verify constants, `:none`, `:peer`, `:client_once`, `:fail_if_no_peer_cert`, or the constant directly `OpenSSL::SSL::VERIFY_NONE`.
+ * `:openssl_verify_mode` - When using TLS, you can set how OpenSSL checks the certificate. This is useful if you need to validate a self-signed and/or a wildcard certificate. This can be one of the OpenSSL verify constants, `:none` or `:peer` -- or the constant directly `OpenSSL::SSL::VERIFY_NONE` or `OpenSSL::SSL::VERIFY_PEER`, respectively.
* `:ssl/:tls` - Enables the SMTP connection to use SMTP/TLS (SMTPS: SMTP over direct TLS connection).
* `config.action_mailer.sendmail_settings` allows detailed configuration for the `sendmail` delivery method. It accepts a hash of options, which can include any of these options:
@@ -566,7 +592,7 @@ There are a few configuration options available in Active Support:
* `config.active_support.bare` enables or disables the loading of `active_support/all` when booting Rails. Defaults to `nil`, which means `active_support/all` is loaded.
-* `config.active_support.test_order` sets the order that test cases are executed. Possible values are `:random` and `:sorted`. This option is set to `:random` in `config/environments/test.rb` in newly-generated applications. If you have an application that does not specify a `test_order`, it will default to `:sorted`, *until* Rails 5.0, when the default will become `:random`.
+* `config.active_support.test_order` sets the order in which the test cases are executed. Possible values are `:random` and `:sorted`. Defaults to `:random`.
* `config.active_support.escape_html_entities_in_json` enables or disables the escaping of HTML entities in JSON serialization. Defaults to `true`.
diff --git a/guides/source/contributing_to_ruby_on_rails.md b/guides/source/contributing_to_ruby_on_rails.md
index 59c902e148..ba8d085f79 100644
--- a/guides/source/contributing_to_ruby_on_rails.md
+++ b/guides/source/contributing_to_ruby_on_rails.md
@@ -25,7 +25,7 @@ Reporting an Issue
Ruby on Rails uses [GitHub Issue Tracking](https://github.com/rails/rails/issues) to track issues (primarily bugs and contributions of new code). If you've found a bug in Ruby on Rails, this is the place to start. You'll need to create a (free) GitHub account in order to submit an issue, to comment on them or to create pull requests.
-NOTE: Bugs in the most recent released version of Ruby on Rails are likely to get the most attention. Also, the Rails core team is always interested in feedback from those who can take the time to test _edge Rails_ (the code for the version of Rails that is currently under development). Later in this guide you'll find out how to get edge Rails for testing.
+NOTE: Bugs in the most recent released version of Ruby on Rails are likely to get the most attention. Also, the Rails core team is always interested in feedback from those who can take the time to test _edge Rails_ (the code for the version of Rails that is currently under development). Later in this guide, you'll find out how to get edge Rails for testing.
### Creating a Bug Report
@@ -58,7 +58,7 @@ WARNING: Please do not report security vulnerabilities with public GitHub issue
Please don't put "feature request" items into GitHub Issues. If there's a new
feature that you want to see added to Ruby on Rails, you'll need to write the
code yourself - or convince someone else to partner with you to write the code.
-Later in this guide you'll find detailed instructions for proposing a patch to
+Later in this guide, you'll find detailed instructions for proposing a patch to
Ruby on Rails. If you enter a wish list item in GitHub Issues with no code, you
can expect it to be marked "invalid" as soon as it's reviewed.
@@ -131,7 +131,7 @@ learn about Ruby on Rails, and the API, which serves as a reference.
You can help improve the Rails guides by making them more coherent, consistent or readable, adding missing information, correcting factual errors, fixing typos, or bringing them up to date with the latest edge Rails.
You can either open a pull request to [Rails](https://github.com/rails/rails) or
-ask the [Rails core team](http://rubyonrails.org/core) for commit access on
+ask the [Rails core team](http://rubyonrails.org/community/#core) for commit access on
docrails if you contribute regularly.
Please do not open pull requests in docrails, if you'd like to get feedback on your
change, ask for it in [Rails](https://github.com/rails/rails) instead.
@@ -189,7 +189,7 @@ Contributing to the Rails Code
### Setting Up a Development Environment
-To move on from submitting bugs to helping resolve existing issues or contributing your own code to Ruby on Rails, you _must_ be able to run its test suite. In this section of the guide you'll learn how to setup the tests on your own computer.
+To move on from submitting bugs to helping resolve existing issues or contributing your own code to Ruby on Rails, you _must_ be able to run its test suite. In this section of the guide, you'll learn how to setup the tests on your own computer.
#### The Easy Way
@@ -299,9 +299,9 @@ Please see the benchmark/ips [README](https://github.com/evanphx/benchmark-ips/b
### Running Tests
It is not customary in Rails to run the full test suite before pushing
-changes. The railties test suite in particular takes a long time, and even
-more if the source code is mounted in `/vagrant` as happens in the recommended
-workflow with the [rails-dev-box](https://github.com/rails/rails-dev-box).
+changes. The railties test suite in particular takes a long time, and takes an
+especially long time if the source code is mounted in `/vagrant` as happens in
+the recommended workflow with the [rails-dev-box](https://github.com/rails/rails-dev-box).
As a compromise, test what your code obviously affects, and if the change is
not in railties, run the whole test suite of the affected component. If all
@@ -662,7 +662,7 @@ Changes that are merged into master are intended for the next major release of R
For simple fixes, the easiest way to backport your changes is to [extract a diff from your changes in master and apply them to the target branch](http://ariejan.net/2009/10/26/how-to-create-and-apply-a-patch-with-git).
-First make sure your changes are the only difference between your current branch and master:
+First, make sure your changes are the only difference between your current branch and master:
```bash
$ git log master..HEAD
diff --git a/guides/source/credits.html.erb b/guides/source/credits.html.erb
index 1d995581fa..511d76041b 100644
--- a/guides/source/credits.html.erb
+++ b/guides/source/credits.html.erb
@@ -64,7 +64,7 @@ Oscar Del Ben is a software engineer at <a href="http://www.wildfireapp.com/">Wi
<% end %>
<%= author('Pratik Naik', 'lifo') do %>
- Pratik Naik is a Ruby on Rails developer at <a href="https://basecamp.com/">Basecamp</a> and also a member of the <a href="http://rubyonrails.org/core">Rails core team</a>. He maintains a blog at <a href="http://m.onkey.org">has_many :bugs, :through =&gt; :rails</a> and has a semi-active <a href="http://twitter.com/lifo">twitter account</a>.
+ Pratik Naik is a Ruby on Rails developer at <a href="https://basecamp.com/">Basecamp</a> and maintains a blog at <a href="http://m.onkey.org">has_many :bugs, :through =&gt; :rails</a>. He also has a semi-active <a href="http://twitter.com/lifo">twitter account</a>.
<% end %>
<%= author('Emilio Tagua', 'miloops') do %>
diff --git a/guides/source/documents.yaml b/guides/source/documents.yaml
index a5b8a75509..627e23422d 100644
--- a/guides/source/documents.yaml
+++ b/guides/source/documents.yaml
@@ -85,9 +85,8 @@
description: This guide provides you with all you need to get started creating, enqueuing, and executing background jobs.
-
name: Testing Rails Applications
- work_in_progress: true
url: testing.html
- description: This is a rather comprehensive guide to the various testing facilities in Rails. It covers everything from 'What is a test?' to the testing APIs. Enjoy.
+ description: This is a rather comprehensive guide to the various testing facilities in Rails. It covers everything from 'What is a test?' to Integration Testing. Enjoy.
-
name: Securing Rails Applications
url: security.html
@@ -195,6 +194,10 @@
url: upgrading_ruby_on_rails.html
description: This guide helps in upgrading applications to latest Ruby on Rails versions.
-
+ name: Ruby on Rails 5.0 Release Notes
+ url: 5_0_release_notes.html
+ description: Release notes for Rails 5.0.
+ -
name: Ruby on Rails 4.2 Release Notes
url: 4_2_release_notes.html
description: Release notes for Rails 4.2.
diff --git a/guides/source/engines.md b/guides/source/engines.md
index eafac4828c..f9a37e45ac 100644
--- a/guides/source/engines.md
+++ b/guides/source/engines.md
@@ -11,9 +11,9 @@ After reading this guide, you will know:
* What makes an engine.
* How to generate an engine.
-* Building features for the engine.
-* Hooking the engine into an application.
-* Overriding engine functionality in the application.
+* How to build features for the engine.
+* How to hook the engine into an application.
+* How to override engine functionality in the application.
--------------------------------------------------------------------------------
@@ -25,7 +25,7 @@ their host applications. A Rails application is actually just a "supercharged"
engine, with the `Rails::Application` class inheriting a lot of its behavior
from `Rails::Engine`.
-Therefore, engines and applications can be thought of almost the same thing,
+Therefore, engines and applications can be thought of as almost the same thing,
just with subtle differences, as you'll see throughout this guide. Engines and
applications also share a common structure.
diff --git a/guides/source/getting_started.md b/guides/source/getting_started.md
index 65fdd7ca0d..b0d3953cbd 100644
--- a/guides/source/getting_started.md
+++ b/guides/source/getting_started.md
@@ -299,9 +299,6 @@ Rails.application.routes.draw do
get 'welcome/index'
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
-
- # Serve websocket cable requests in-process
- # mount ActionCable.server => '/cable'
end
```
@@ -316,10 +313,6 @@ It should look something like the following:
Rails.application.routes.draw do
get 'welcome/index'
- # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
-
- # Serve websocket cable requests in-process
- # mount ActionCable.server => '/cable'
root 'welcome#index'
end
```
@@ -462,7 +455,7 @@ available, Rails will raise an exception.
In the above image, the bottom line has been truncated. Let's see what the full
error message looks like:
->Missing template articles/new, application/new with {locale:[:en], formats:[:html], handlers:[:erb, :builder, :coffee]}. Searched in: * "/path/to/blog/app/views"
+>ArticlesController#new is missing a template for this request format and variant. request.formats: ["text/html"] request.variant: [] NOTE! For XHR/Ajax or API requests, this action would normally respond with 204 No Content: an empty white screen. Since you're loading it in a web browser, we assume that you expected to actually render a template, not… nothing, so we're showing an error to be extra-clear. If you expect 204 No Content, carry on. That's what you'll get from an XHR or API request. Give it a shot.
That's quite a lot of text! Let's quickly go through and understand what each
part of it means.
@@ -481,9 +474,9 @@ us what _template handlers_ could be used to render our template. `:erb` is most
commonly used for HTML templates, `:builder` is used for XML templates, and
`:coffee` uses CoffeeScript to build JavaScript templates.
-The final part of this message tells us where Rails has looked for the templates.
-Templates within a basic Rails application like this are kept in a single
-location, but in more complex applications it could be many different paths.
+The message also contains `request.formats` which specifies the format of template to be
+served in response. It is set to `text/html` as we requested this page via browser, so Rails
+is looking for an HTML template.
The simplest template that would work in this case would be one located at
`app/views/articles/new.html.erb`. The extension of this file name is important:
@@ -491,7 +484,9 @@ the first extension is the _format_ of the template, and the second extension
is the _handler_ that will be used. Rails is attempting to find a template
called `articles/new` within `app/views` for the application. The format for
this template can only be `html` and the handler must be one of `erb`,
-`builder` or `coffee`. Because you want to create a new HTML form, you will be
+`builder` or `coffee`. `:erb` is most commonly used for HTML templates, `:builder` is
+used for XML templates, and `:coffee` uses CoffeeScript to build JavaScript templates.
+Because you want to create a new HTML form, you will be
using the `ERB` language which is designed to embed Ruby in HTML.
Therefore the file should be called `articles/new.html.erb` and needs to be
@@ -611,9 +606,11 @@ class ArticlesController < ApplicationController
end
```
-If you re-submit the form now, you'll see another familiar error: a template is
-missing. That's ok, we can ignore that for now. What the `create` action should
-be doing is saving our new article to the database.
+If you re-submit the form now, you may not see any change on the page. Don't worry!
+This is because Rails by default returns `204 No Content` response for an action if
+we don't specify what the response should be. We just added the `create` action
+but didn't specify anything about how the response should be. In this case, the
+`create` action should save our new article to the database.
When a form is submitted, the fields of the form are sent to Rails as
_parameters_. These parameters can then be referenced inside the controller
diff --git a/guides/source/i18n.md b/guides/source/i18n.md
index 0edfa072f8..f3802a142f 100644
--- a/guides/source/i18n.md
+++ b/guides/source/i18n.md
@@ -109,12 +109,11 @@ The **translations load path** (`I18n.load_path`) is an array of paths to files
NOTE: The backend lazy-loads these translations when a translation is looked up for the first time. This backend can be swapped with something else even after translations have already been announced.
-The default `config/application.rb` file has instructions on how to add locales from another directory and how to set a different default locale.
+You can change the default locale as well as configure the translations load paths in `config/application.rb` as follows:
```ruby
-# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
-# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
-# config.i18n.default_locale = :de
+ config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
+ config.i18n.default_locale = :de
```
The load path must be specified before any translations are looked up. To change the default locale from an initializer instead of `config/application.rb`:
diff --git a/guides/source/layout.html.erb b/guides/source/layout.html.erb
index 6db76b528e..943fd3fd7f 100644
--- a/guides/source/layout.html.erb
+++ b/guides/source/layout.html.erb
@@ -111,7 +111,7 @@
<%= link_to 'open an issue', 'https://github.com/rails/rails/issues' %>.
</p>
<p>And last but not least, any kind of discussion regarding Ruby on Rails
- documentation is very welcome in the <%= link_to 'rubyonrails-docs mailing list', 'http://groups.google.com/group/rubyonrails-docs' %>.
+ documentation is very welcome in the <%= link_to 'rubyonrails-docs mailing list', 'https://groups.google.com/forum/#!forum/rubyonrails-docs' %>.
</p>
</div>
</div>
@@ -127,13 +127,11 @@
<script type="text/javascript" src="javascripts/jquery.min.js"></script>
<script type="text/javascript" src="javascripts/responsive-tables.js"></script>
<script type="text/javascript" src="javascripts/guides.js"></script>
- <script type="text/javascript" src="javascripts/syntaxhighlighter/shCore.js"></script>
- <script type="text/javascript" src="javascripts/syntaxhighlighter/shBrushRuby.js"></script>
- <script type="text/javascript" src="javascripts/syntaxhighlighter/shBrushXml.js"></script>
- <script type="text/javascript" src="javascripts/syntaxhighlighter/shBrushSql.js"></script>
- <script type="text/javascript" src="javascripts/syntaxhighlighter/shBrushPlain.js"></script>
+ <script type="text/javascript" src="javascripts/syntaxhighlighter.js"></script>
<script type="text/javascript">
- SyntaxHighlighter.all();
+ syntaxhighlighterConfig = {
+ autoLinks: false,
+ };
$(guidesIndex.bind);
</script>
</body>
diff --git a/guides/source/rails_application_templates.md b/guides/source/rails_application_templates.md
index 3b773d84f8..3e99ee7021 100644
--- a/guides/source/rails_application_templates.md
+++ b/guides/source/rails_application_templates.md
@@ -15,14 +15,14 @@ After reading this guide, you will know:
Usage
-----
-To apply a template, you need to provide the Rails generator with the location of the template you wish to apply using the -m option. This can either be a path to a file or a URL.
+To apply a template, you need to provide the Rails generator with the location of the template you wish to apply using the `-m` option. This can either be a path to a file or a URL.
```bash
$ rails new blog -m ~/template.rb
$ rails new blog -m http://example.com/template.rb
```
-You can use the task `app:template` to apply templates to an existing Rails application. The location of the template needs to be passed in to an environment variable named LOCATION. Again, this can either be path to a file or a URL.
+You can use the `app:template` Rake task to apply templates to an existing Rails application. The location of the template needs to be passed in via the LOCATION environment variable. Again, this can either be path to a file or a URL.
```bash
$ bin/rails app:template LOCATION=~/template.rb
diff --git a/guides/source/rails_on_rack.md b/guides/source/rails_on_rack.md
index d67702f52e..8148f70c31 100644
--- a/guides/source/rails_on_rack.md
+++ b/guides/source/rails_on_rack.md
@@ -105,19 +105,18 @@ For a freshly generated Rails application, this might produce something like:
use Rack::Sendfile
use ActionDispatch::Static
use ActionDispatch::Executor
-use #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x000000029a0838>
+use ActiveSupport::Cache::Strategy::LocalCache::Middleware
use Rack::Runtime
use Rack::MethodOverride
use ActionDispatch::RequestId
use Rails::Rack::Logger
use ActionDispatch::ShowExceptions
+use WebConsole::Middleware
use ActionDispatch::DebugExceptions
use ActionDispatch::RemoteIp
use ActionDispatch::Reloader
use ActionDispatch::Callbacks
use ActiveRecord::Migration::CheckPending
-use ActiveRecord::ConnectionAdapters::ConnectionManagement
-use ActiveRecord::QueryCache
use ActionDispatch::Cookies
use ActionDispatch::Session::CookieStore
use ActionDispatch::Flash
@@ -149,9 +148,9 @@ You can add a new middleware to the middleware stack using any of the following
# Push Rack::BounceFavicon at the bottom
config.middleware.use Rack::BounceFavicon
-# Add Lifo::Cache after ActiveRecord::QueryCache.
+# Add Lifo::Cache after ActionDispatch::Executor.
# Pass { page_cache: false } argument to Lifo::Cache.
-config.middleware.insert_after ActiveRecord::QueryCache, Lifo::Cache, page_cache: false
+config.middleware.insert_after ActionDispatch::Executor, Lifo::Cache, page_cache: false
```
#### Swapping a Middleware
@@ -267,14 +266,6 @@ Much of Action Controller's functionality is implemented as Middlewares. The fol
* Checks pending migrations and raises `ActiveRecord::PendingMigrationError` if any migrations are pending.
-**`ActiveRecord::ConnectionAdapters::ConnectionManagement`**
-
-* Cleans active connections after each request, unless the `rack.test` key in the request environment is set to `true`.
-
-**`ActiveRecord::QueryCache`**
-
-* Enables the Active Record query cache.
-
**`ActionDispatch::Cookies`**
* Sets cookies for the request.
diff --git a/guides/source/routing.md b/guides/source/routing.md
index 81321c7405..756e0fefd7 100644
--- a/guides/source/routing.md
+++ b/guides/source/routing.md
@@ -9,16 +9,16 @@ After reading this guide, you will know:
* How to interpret the code in `config/routes.rb`.
* How to construct your own routes, using either the preferred resourceful style or the `match` method.
-* What parameters to expect an action to receive.
+* How to declare route parameters, which are passed onto controller actions.
* How to automatically create paths and URLs using route helpers.
-* Advanced techniques such as constraints and Rack endpoints.
+* Advanced techniques such as creating constraints and mounting Rack endpoints.
--------------------------------------------------------------------------------
The Purpose of the Rails Router
-------------------------------
-The Rails router recognizes URLs and dispatches them to a controller's action. It can also generate paths and URLs, avoiding the need to hardcode strings in your views.
+The Rails router recognizes URLs and dispatches them to a controller's action, or to a Rack application. It can also generate paths and URLs, avoiding the need to hardcode strings in your views.
### Connecting URLs to Code
diff --git a/guides/source/testing.md b/guides/source/testing.md
index 050bdda9e3..e8dc6ffe2a 100644
--- a/guides/source/testing.md
+++ b/guides/source/testing.md
@@ -146,18 +146,28 @@ Let us run this newly added test (where `6` is the number of line where the test
```bash
$ bin/rails test test/models/article_test.rb:6
+Run options: --seed 44656
+
+# Running:
+
F
-Finished tests in 0.044632s, 22.4054 tests/s, 22.4054 assertions/s.
+Failure:
+ArticleTest#test_should_not_save_article_without_title [/path/to/blog/test/models/article_test.rb:6]:
+Expected true to be nil or false
+
+
+bin/rails test test/models/article_test.rb:6
- 1) Failure:
-test_should_not_save_article_without_title(ArticleTest) [test/models/article_test.rb:6]:
-Failed assertion, no message given.
-1 tests, 1 assertions, 1 failures, 0 errors, 0 skips
+
+Finished in 0.023918s, 41.8090 runs/s, 41.8090 assertions/s.
+
+1 runs, 1 assertions, 1 failures, 0 errors, 0 skips
+
```
-In the output, `F` denotes a failure. You can see the corresponding trace shown under `1)` along with the name of the failing test. The next few lines contain the stack trace followed by a message that mentions the actual value and the expected value by the assertion. The default assertion messages provide just enough information to help pinpoint the error. To make the assertion failure message more readable, every assertion provides an optional message parameter, as shown here:
+In the output, `F` denotes a failure. You can see the corresponding trace shown under `Failure` along with the name of the failing test. The next few lines contain the stack trace followed by a message that mentions the actual value and the expected value by the assertion. The default assertion messages provide just enough information to help pinpoint the error. To make the assertion failure message more readable, every assertion provides an optional message parameter, as shown here:
```ruby
test "should not save article without title" do
@@ -169,8 +179,8 @@ end
Running this test shows the friendlier assertion message:
```bash
- 1) Failure:
-test_should_not_save_article_without_title(ArticleTest) [test/models/article_test.rb:6]:
+Failure:
+ArticleTest#test_should_not_save_article_without_title [/path/to/blog/test/models/article_test.rb:6]:
Saved the article without a title
```
@@ -186,11 +196,15 @@ Now the test should pass. Let us verify by running the test again:
```bash
$ bin/rails test test/models/article_test.rb:6
+Run options: --seed 31252
+
+# Running:
+
.
-Finished tests in 0.047721s, 20.9551 tests/s, 20.9551 assertions/s.
+Finished in 0.027476s, 36.3952 runs/s, 36.3952 assertions/s.
-1 tests, 1 assertions, 0 failures, 0 errors, 0 skips
+1 runs, 1 assertions, 0 failures, 0 errors, 0 skips
```
Now, if you noticed, we first wrote a test which fails for a desired
@@ -215,16 +229,25 @@ Now you can see even more output in the console from running the tests:
```bash
$ bin/rails test test/models/article_test.rb
-E
+Run options: --seed 1808
+
+# Running:
+
+.E
+
+Error:
+ArticleTest#test_should_report_error:
+NameError: undefined local variable or method `some_undefined_variable' for #<ArticleTest:0x007fee3aa71798>
+ test/models/article_test.rb:11:in `block in <class:ArticleTest>'
+
+
+bin/rails test test/models/article_test.rb:9
+
-Finished tests in 0.030974s, 32.2851 tests/s, 0.0000 assertions/s.
- 1) Error:
-test_should_report_error(ArticleTest):
-NameError: undefined local variable or method `some_undefined_variable' for #<ArticleTest:0x007fe32e24afe0>
- test/models/article_test.rb:10:in `block in <class:ArticleTest>'
+Finished in 0.040609s, 49.2500 runs/s, 24.6250 assertions/s.
-1 tests, 0 assertions, 0 failures, 1 errors, 0 skips
+2 runs, 1 assertions, 0 failures, 1 errors, 0 skips
```
Notice the 'E' in the output. It denotes a test with error.
@@ -342,17 +365,21 @@ documentation](http://docs.seattlerb.org/minitest).
### The Rails Test Runner
-We can run all of our tests at once by using the `rails test` command.
+We can run all of our tests at once by using the `bin/rails test` command.
-Or we can run a single test by passing the `rails test` command the filename containing the test cases.
+Or we can run a single test by passing the `bin/rails test` command the filename containing the test cases.
```bash
$ bin/rails test test/models/article_test.rb
-.
+Run options: --seed 1559
-Finished tests in 0.009262s, 107.9680 tests/s, 107.9680 assertions/s.
+# Running:
-1 tests, 1 assertions, 0 failures, 0 errors, 0 skips
+..
+
+Finished in 0.027034s, 73.9810 runs/s, 110.9715 assertions/s.
+
+2 runs, 3 assertions, 0 failures, 0 errors, 0 skips
```
This will run all test methods from the test case.
@@ -362,6 +389,10 @@ You can also run a particular test method from the test case by providing the
```bash
$ bin/rails test test/models/article_test.rb -n test_the_truth
+Run options: -n test_the_truth --seed 43583
+
+# Running:
+
.
Finished tests in 0.009064s, 110.3266 tests/s, 110.3266 assertions/s.
@@ -372,7 +403,7 @@ Finished tests in 0.009064s, 110.3266 tests/s, 110.3266 assertions/s.
You can also run a test at a specific line by providing the line number.
```bash
-$ bin/rails test test/models/post_test.rb:44 # run specific test and line
+$ bin/rails test test/models/article_test.rb:6 # run specific test and line
```
You can also run an entire directory of tests by providing the path to the directory.
@@ -381,6 +412,38 @@ You can also run an entire directory of tests by providing the path to the direc
$ bin/rails test test/controllers # run all tests from specific directory
```
+The test runner provides lot of other features too like failing fast, deferring test output
+at the end of test run and so on. Check the documentation of the test runner as follows:
+
+```bash
+$ bin/rails test -h
+minitest options:
+ -h, --help Display this help.
+ -s, --seed SEED Sets random seed. Also via env. Eg: SEED=n rake
+ -v, --verbose Verbose. Show progress processing files.
+ -n, --name PATTERN Filter run on /regexp/ or string.
+ --exclude PATTERN Exclude /regexp/ or string from run.
+
+Known extensions: rails, pride
+
+Usage: bin/rails test [options] [files or directories]
+You can run a single test by appending a line number to a filename:
+
+ bin/rails test test/models/user_test.rb:27
+
+You can run multiple files and directories at the same time:
+
+ bin/rails test test/controllers test/integration/login_test.rb
+
+By default test failures and errors are reported inline during a run.
+
+Rails options:
+ -e, --environment ENV Run tests in the ENV environment
+ -b, --backtrace Show the complete backtrace
+ -d, --defer-output Output test failures and errors after the test run
+ -f, --fail-fast Abort test run on first failure or error
+ -c, --[no-]color Enable color in the output
+```
The Test Database
-----------------
@@ -529,7 +592,7 @@ Integration Testing
Integration tests are used to test how various parts of your application interact. They are generally used to test important workflows within our application.
-For creating Rails integration tests, we use the 'test/integration' directory for our application. Rails provides a generator to create an integration test skeleton for us.
+For creating Rails integration tests, we use the `test/integration` directory for our application. Rails provides a generator to create an integration test skeleton for us.
```bash
$ bin/rails generate integration_test user_flows
@@ -685,9 +748,8 @@ Let's take a look at one such test, `test_should_get_index` from the file `artic
# articles_controller_test.rb
class ArticlesControllerTest < ActionDispatch::IntegrationTest
test "should get index" do
- get '/articles'
+ get articles_url
assert_response :success
- assert_includes @response.body, 'Articles'
end
end
```
@@ -695,7 +757,7 @@ end
In the `test_should_get_index` test, Rails simulates a request on the action called `index`, making sure the request was successful
and also ensuring that the right response body has been generated.
-The `get` method kicks off the web request and populates the results into the `@response`. It accepts 4 arguments:
+The `get` method kicks off the web request and populates the results into the `@response`. It can accept up to 6 arguments:
* The action of the controller you are requesting.
This can be in the form of a string or a route (i.e. `articles_url`).
@@ -703,22 +765,26 @@ The `get` method kicks off the web request and populates the results into the `@
* `params`: option with a hash of request parameters to pass into the action
(e.g. query string parameters or article variables).
-* `session`: option with a hash of session variables to pass along with the request.
+* `headers`: for setting the headers that will be passed with the request.
+
+* `env`: for customizing the request environment as needed.
-* `flash`: option with a hash of flash values.
+* `xhr`: whether the request is Ajax request or not. Can be set to true for marking the request as Ajax.
+
+* `as`: for encoding the request with different content type. Supports `:json` by default.
All of these keyword arguments are optional.
-Example: Calling the `:show` action, passing an `id` of 12 as the `params` and setting a `user_id` of 5 in the session:
+Example: Calling the `:show` action, passing an `id` of 12 as the `params` and setting `HTTP_REFERER` header:
```ruby
-get(:show, params: { id: 12 }, session: { user_id: 5 })
+get :show, params: { id: 12 }, headers: { "HTTP_REFERER" => "http://example.com/home" }
```
-Another example: Calling the `:view` action, passing an `id` of 12 as the `params`, this time with no session, but with a flash message.
+Another example: Calling the `:update` action, passing an `id` of 12 as the `params` as an Ajax request.
```ruby
-get(view_url, params: { id: 12 }, flash: { message: 'booya!' })
+patch update_url, params: { id: 12 }, xhr: true
```
NOTE: If you try running `test_should_create_article` test from `articles_controller_test.rb` it will fail on account of the newly added model level validation and rightly so.
@@ -728,7 +794,7 @@ Let us modify `test_should_create_article` test in `articles_controller_test.rb`
```ruby
test "should create article" do
assert_difference('Article.count') do
- post '/article', params: { article: { title: 'Some title' } }
+ post articles_url, params: { article: { body: 'Rails is awesome!', title: 'Hello Rails' } }
end
assert_redirected_to article_path(Article.last)
@@ -759,7 +825,7 @@ To test AJAX requests, you can specify the `xhr: true` option to `get`, `post`,
```ruby
test "ajax request" do
- article = articles(:first)
+ article = articles(:one)
get article_url(article), xhr: true
assert_equal 'hello world', @response.body
@@ -796,16 +862,14 @@ You also have access to three instance variables in your functional tests:
[HTTP headers](http://tools.ietf.org/search/rfc2616#section-5.3)
and
[CGI variables](http://tools.ietf.org/search/rfc3875#section-4.1)
-can be set directly on the `@request` instance variable:
+can be passed as headers:
```ruby
# setting an HTTP Header
-@request.headers["Accept"] = "text/plain, text/html"
-get articles_url # simulate the request with custom header
+get articles_url, headers: "Content-Type" => "text/plain" # simulate the request with custom header
# setting a CGI variable
-@request.headers["HTTP_REFERER"] = "http://example.com/home"
-post article_url # simulate the request with custom env variable
+get articles_url, headers: "HTTP_REFERER" => "http://example.com/home" # simulate the request with custom env variable
```
### Testing `flash` notices
@@ -841,7 +905,7 @@ F
Finished in 0.114870s, 8.7055 runs/s, 34.8220 assertions/s.
1) Failure:
-ArticlesControllerTest#test_should_create_article [/Users/zzak/code/bench/sharedapp/test/controllers/articles_controller_test.rb:16]:
+ArticlesControllerTest#test_should_create_article [/test/controllers/articles_controller_test.rb:16]:
--- expected
+++ actual
@@ -1 +1 @@
@@ -890,7 +954,7 @@ Let's write a test for the `:show` action:
```ruby
test "should show article" do
article = articles(:one)
- get '/article', params: { id: article.id }
+ get article_url(article)
assert_response :success
end
```
@@ -916,7 +980,7 @@ We can also add a test for updating an existing Article.
test "should update article" do
article = articles(:one)
- patch '/article', params: { id: article.id, article: { title: "updated" } }
+ patch article_url(article), params: { article: { title: "updated" } }
assert_redirected_to article_path(article)
# Reload association to fetch updated data and assert that title is updated.
@@ -959,7 +1023,7 @@ class ArticlesControllerTest < ActionDispatch::IntegrationTest
end
test "should update article" do
- patch '/article', params: { id: @article.id, article: { title: "updated" } }
+ patch article_url(@article), params: { article: { title: "updated" } }
assert_redirected_to article_path(@article)
# Reload association to fetch updated data and assert that title is updated.
@@ -980,8 +1044,8 @@ Sign in helper can be a good example:
#test/test_helper.rb
module SignInHelper
- def sign_in(user)
- session[:user_id] = user.id
+ def sign_in_as(user)
+ post sign_in_url(email: user.email, password: user.password)
end
end
@@ -997,7 +1061,7 @@ class ProfileControllerTest < ActionDispatch::IntegrationTest
test "should show profile" do
# helper is now reusable from any controller test case
- sign_in users(:david)
+ sign_in_as users(:david)
get profile_url
assert_response :success
@@ -1243,8 +1307,8 @@ end
This test is pretty simple and only asserts that the job get the work done
as expected.
-By default, `ActiveJob::TestCase` will set the queue adapter to `:test` so that
-your jobs are performed inline. It will also ensure that all previously performed
+By default, `ActiveJob::TestCase` will set the queue adapter to `:async` so that
+your jobs are performed in an async fashion. It will also ensure that all previously performed
and enqueued jobs are cleared before any test run so you can safely assume that
no jobs have already been executed in the scope of each test.
diff --git a/guides/source/upgrading_ruby_on_rails.md b/guides/source/upgrading_ruby_on_rails.md
index 82080c4def..c41876cd28 100644
--- a/guides/source/upgrading_ruby_on_rails.md
+++ b/guides/source/upgrading_ruby_on_rails.md
@@ -68,14 +68,16 @@ Don't forget to review the difference, to see if there were any unexpected chang
Upgrading from Rails 4.2 to Rails 5.0
-------------------------------------
-### Ruby 2.2.2+
+For more information on changes made to Rails 5.0 please see the [release notes](5_0_release_notes.html).
-From Ruby on Rails 5.0 onwards, Ruby 2.2.2+ is the only supported version.
-Make sure you are on Ruby 2.2.2 version or greater, before you proceed.
+### Ruby 2.2.2+ required
-### Active Record models now inherit from ApplicationRecord by default
+From Ruby on Rails 5.0 onwards, Ruby 2.2.2+ is the only supported Ruby version.
+Make sure you are on Ruby 2.2.2 version or greater, before you proceed.
-In Rails 4.2 an Active Record model inherits from `ActiveRecord::Base`. In Rails 5.0,
+### Active Record Models Now Inherit from ApplicationRecord by Default
+
+In Rails 4.2, an Active Record model inherits from `ActiveRecord::Base`. In Rails 5.0,
all models inherit from `ApplicationRecord`.
`ApplicationRecord` is a new superclass for all app models, analogous to app
@@ -83,7 +85,7 @@ controllers subclassing `ApplicationController` instead of
`ActionController::Base`. This gives apps a single spot to configure app-wide
model behavior.
-When upgrading from Rails 4.2 to Rails 5.0 you need to create an
+When upgrading from Rails 4.2 to Rails 5.0, you need to create an
`application_record.rb` file in `app/models/` and add the following content:
```
@@ -92,7 +94,7 @@ class ApplicationRecord < ActiveRecord::Base
end
```
-### Halting callback chains via `throw(:abort)`
+### Halting Callback Chains via `throw(:abort)`
In Rails 4.2, when a 'before' callback returns `false` in Active Record
and Active Model, then the entire callback chain is halted. In other words,
@@ -117,12 +119,12 @@ halted the chain when any value was returned.
See [#17227](https://github.com/rails/rails/pull/17227) for more details.
-### ActiveJob jobs now inherit from ApplicationJob by default
+### ActiveJob Now Inherits from ApplicationJob by Default
-In Rails 4.2 an ActiveJob inherits from `ActiveJob::Base`. In Rails 5.0 this
+In Rails 4.2, an Active Job inherits from `ActiveJob::Base`. In Rails 5.0, this
behavior has changed to now inherit from `ApplicationJob`.
-When upgrading from Rails 4.2 to Rails 5.0 you need to create an
+When upgrading from Rails 4.2 to Rails 5.0, you need to create an
`application_job.rb` file in `app/jobs/` and add the following content:
```
@@ -134,6 +136,210 @@ Then make sure that all your job classes inherit from it.
See [#19034](https://github.com/rails/rails/pull/19034) for more details.
+### Rails Controller Testing
+
+`assigns` and `assert_template` have been extracted to the `rails-controller-testing` gem. To
+continue using these methods in your controller tests, add `gem 'rails-controller-testing'` to
+your Gemfile.
+
+If you are using Rspec for testing, please see the extra configuration required in the gem's
+documentation.
+
+### Autoloading is Disabled After Booting in the Production Environment
+
+Autoloading is now disabled after booting in the production environment by
+default.
+
+Eager loading the application is part of the boot process, so top-level
+constants are fine and are still autoloaded, no need to require their files.
+
+Constants in deeper places only executed at runtime, like regular method bodies,
+are also fine because the file defining them will have been eager loaded while booting.
+
+For the vast majority of applications this change needs no action. But in the
+very rare event that your application needs autoloading while running in
+production mode, set `Rails.application.config.enable_dependency_loading` to
+true.
+
+### XML Serialization
+
+`ActiveModel::Serializers::Xml` has been extracted from Rails to the `activemodel-serializers-xml`
+gem. To continue using XML serialization in your application, add `gem 'activemodel-serializers-xml'`
+to your Gemfile.
+
+### Removed Support for Legacy `mysql` Database Adapter
+
+Rails 5 removes support for the legacy `mysql` database adapter. Most users should be able to
+use `mysql2` instead. It will be converted to a separate gem when we find someone to maintain
+it.
+
+### Removed Support for Debugger
+
+`debugger` is not supported by Ruby 2.2 which is required by Rails 5. Use `byebug` instead.
+
+### Use bin/rails for running tasks and tests
+
+Rails 5 adds the ability to run tasks and tests through `bin/rails` instead of rake. Generally
+these changes are in parallel with rake, but some were ported over altogether.
+
+To use the new test runner simply type `bin/rails test`.
+
+`rake dev:cache` is now `rails dev:cache`.
+
+Run `bin/rails` to see the list of commands available.
+
+### `ActionController::Parameters` No Longer Inherits from `HashWithIndifferentAccess`
+
+Calling `params` in your application will now return an object instead of a hash. If your
+parameters are already permitted, then you will not need to make any changes. If you are using `slice`
+and other methods that depend on being able to read the hash regardless of `permitted?` you will
+need to upgrade your application to first permit and then convert to a hash.
+
+ params.permit([:proceed_to, :return_to]).to_h
+
+### `protect_from_forgery` Now Defaults to `prepend: false`
+
+`protect_from_forgery` defaults to `prepend: false` which means that it will be inserted into
+the callback chain at the point in which you call it in your application. If you want
+`protect_from_forgery` to always run first, then you should change your application to use
+`protect_from_forgery prepend: true`.
+
+### Default Template Handler is Now RAW
+
+Files without a template handler in their extension will be rendered using the raw handler.
+Previously Rails would render files using the ERB template handler.
+
+If you do not want your file to be handled via the raw handler, you should add an extension
+to your file that can be parsed by the appropriate template handler.
+
+### Added Wildcard Matching for Template Dependencies
+
+You can now use wildcard matching for your template dependencies. For example, if you were
+defining your templates as such:
+
+```erb
+<% # Template Dependency: recordings/threads/events/subscribers_changed %>
+<% # Template Dependency: recordings/threads/events/completed %>
+<% # Template Dependency: recordings/threads/events/uncompleted %>
+```
+
+You can now just call the dependency once with a wildcard.
+
+```erb
+<% # Template Dependency: recordings/threads/events/* %>
+```
+
+### Removed Support for `protected_attributes` Gem
+
+The `protected_attributes` gem is no longer supported in Rails 5.
+
+### Removed support for `activerecord-deprecated_finders` gem
+
+The `activerecord-deprecated_finders` gem is no longer supported in Rails 5.
+
+### `ActiveSupport::TestCase` Default Test Order is Now Random
+
+When tests are run in your application, the default order is now `:random`
+instead of `:sorted`. Use the following config option to set it back to `:sorted`.
+
+```ruby
+# config/environments/test.rb
+Rails.application.configure do
+ config.active_support.test_order = :sorted
+end
+```
+
+### `ActionController::Live` became a `Concern`
+
+If you include `ActionController::Live` in another module that is included in your controller, then you
+should also extend the module with `ActiveSupport::Concern`. Alternatively, you can use the `self.included` hook
+to include `ActionController::Live` directly to the controller once the `StreamingSupport` is included.
+
+This means that if your application used to have its own streaming module, the following code
+would break in production mode:
+
+```ruby
+# This is a work-around for streamed controllers performing authentication with Warden/Devise.
+# See https://github.com/plataformatec/devise/issues/2332
+# Authenticating in the router is another solution as suggested in that issue
+class StreamingSupport
+ include ActionController::Live # this won't work in production for Rails 5
+ # extend ActiveSupport::Concern # unless you uncomment this line.
+
+ def process(name)
+ super(name)
+ rescue ArgumentError => e
+ if e.message == 'uncaught throw :warden'
+ throw :warden
+ else
+ raise e
+ end
+ end
+end
+```
+
+### New Framework Defaults
+
+#### Active Record `belongs_to` Required by Default Option
+
+`belongs_to` will now trigger a validation error by default if the association is not present.
+
+This can be turned off per-association with `optional: true`.
+
+This default will be automatically configured in new applications. If existing application
+want to add this feature it will need to be turned on in an initializer.
+
+ config.active_record.belongs_to_required_by_default = true
+
+#### Per-form CSRF Tokens
+
+Rails 5 now supports per-form CSRF tokens to mitigate against code-injection attacks with forms
+created by JavaScript. With this option turned on, forms in your application will each have their
+own CSRF token that is specified to the action and method for that form.
+
+ config.action_controller.per_form_csrf_tokens = true
+
+#### Forgery Protection with Origin Check
+
+You can now configure your application to check if the HTTP `Origin` header should be checked
+against the site's origin as an additional CSRF defense. Set the following in your config to
+true:
+
+ config.action_controller.forgery_protection_origin_check = true
+
+#### Allow Configuration of Action Mailer Queue Name
+
+The default mailer queue name is `mailers`. This configuration option allows you to globally change
+the queue name. Set the following in your config:
+
+ config.action_mailer.deliver_later_queue_name = :new_queue_name
+
+#### Support Fragment Caching in Action Mailer Views
+
+Set `config.action_mailer.perform_caching` in your config to determine whether your Action Mailer views
+should support caching.
+
+ config.action_mailer.perform_caching = true
+
+#### Configure the Output of `db:structure:dump`
+
+If you're using `schema_search_path` or other PostgreSQL extentions, you can control how the schema is
+dumped. Set to `:all` to generate all dumps, or to `:schema_search_path` to generate from schema search path.
+
+ config.active_record.dump_schemas = :all
+
+#### Configure SSL Options to Enable HSTS with Subdomains
+
+Set the following in your config to enable HSTS when using subdomains:
+
+ config.ssl_options = { hsts: { subdomains: true } }
+
+#### Preserve Timezone of the Receiver
+
+When using Ruby 2.4, you can preserve the timezone of the receiver when calling `to_time`.
+
+ ActiveSupport.to_time_preserves_timezone = false
+
Upgrading from Rails 4.1 to Rails 4.2
-------------------------------------
diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md
index b8f1cda329..243f40a057 100644
--- a/railties/CHANGELOG.md
+++ b/railties/CHANGELOG.md
@@ -1,3 +1,20 @@
+* Do not run `bundle install` when generating a new plugin.
+
+ Since bundler 1.12.0, the gemspec is validated so the `bundle install`
+ command will fail just after the gem is created causing confusion to the
+ users. This change was a bug fix to correctly validate gemspecs.
+
+ *Rafael Mendonça França*
+
+* Default `config.assets.quiet = true` in the development environment. Suppress
+ logging of `sprockets-rails` requests by default.
+
+ *Kevin McPhillips*
+
+* Ensure `/rails/info` routes match in development for apps with a catch-all globbing route.
+
+ *Nicholas Firth-McCoy*
+
* Added a shared section to `config/secrets.yml` that will be loaded for all environments.
*DHH*
diff --git a/railties/lib/rails/application/configuration.rb b/railties/lib/rails/application/configuration.rb
index f415a20833..5ee08d96e1 100644
--- a/railties/lib/rails/application/configuration.rb
+++ b/railties/lib/rails/application/configuration.rb
@@ -16,7 +16,7 @@ module Rails
:railties_order, :relative_url_root, :secret_key_base, :secret_token,
:ssl_options, :public_file_server,
:session_options, :time_zone, :reload_classes_only_on_change,
- :beginning_of_week, :filter_redirect, :x
+ :beginning_of_week, :filter_redirect, :x, :enable_dependency_loading
attr_writer :log_level
attr_reader :encoding, :api_only, :static_cache_control
@@ -54,6 +54,7 @@ module Rails
@api_only = false
@debug_exception_response_format = nil
@x = Custom.new
+ @enable_dependency_loading = false
end
def static_cache_control=(value)
diff --git a/railties/lib/rails/application/finisher.rb b/railties/lib/rails/application/finisher.rb
index 0aed6c1351..daf3a24b16 100644
--- a/railties/lib/rails/application/finisher.rb
+++ b/railties/lib/rails/application/finisher.rb
@@ -21,10 +21,13 @@ module Rails
initializer :add_builtin_route do |app|
if Rails.env.development?
- app.routes.append do
+ app.routes.prepend do
get '/rails/info/properties' => "rails/info#properties", internal: true
get '/rails/info/routes' => "rails/info#routes", internal: true
get '/rails/info' => "rails/info#index", internal: true
+ end
+
+ app.routes.append do
get '/' => "rails/welcome#index", internal: true
end
end
@@ -95,7 +98,7 @@ module Rails
elsif config.allow_concurrency == :unsafe
# Do nothing, even if we know this is dangerous. This is the
- # historical behaviour for true.
+ # historical behavior for true.
else
# Default concurrency setting: enabled, but safe
@@ -173,7 +176,7 @@ module Rails
# Disable dependency loading during request cycle
initializer :disable_dependency_loading do
- if config.eager_load && config.cache_classes
+ if config.eager_load && config.cache_classes && !config.enable_dependency_loading
ActiveSupport::Dependencies.unhook!
end
end
diff --git a/railties/lib/rails/backtrace_cleaner.rb b/railties/lib/rails/backtrace_cleaner.rb
index 5276eb33c9..7b7036041e 100644
--- a/railties/lib/rails/backtrace_cleaner.rb
+++ b/railties/lib/rails/backtrace_cleaner.rb
@@ -2,7 +2,7 @@ require 'active_support/backtrace_cleaner'
module Rails
class BacktraceCleaner < ActiveSupport::BacktraceCleaner
- APP_DIRS_PATTERN = /^\/?(app|config|lib|test)/
+ APP_DIRS_PATTERN = /^\/?(app|config|lib|test|\(\w*\))/
RENDER_TEMPLATE_PATTERN = /:in `_render_template_\w*'/
EMPTY_STRING = ''.freeze
SLASH = '/'.freeze
diff --git a/railties/lib/rails/commands/console.rb b/railties/lib/rails/commands/console.rb
index ea5d20ea24..a4ab31f793 100644
--- a/railties/lib/rails/commands/console.rb
+++ b/railties/lib/rails/commands/console.rb
@@ -7,6 +7,14 @@ module Rails
class Console
include ConsoleHelper
+ module BacktraceCleaner
+ def filter_backtrace(bt)
+ if result = super
+ Rails.backtrace_cleaner.filter([result]).first
+ end
+ end
+ end
+
class << self
def parse_arguments(arguments)
options = {}
@@ -34,6 +42,10 @@ module Rails
app.load_console
@console = app.config.console || IRB
+
+ if @console == IRB
+ IRB::WorkSpace.prepend(BacktraceCleaner)
+ end
end
def sandbox?
diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb
index f0a3289563..af3c6dead3 100644
--- a/railties/lib/rails/generators/app_base.rb
+++ b/railties/lib/rails/generators/app_base.rb
@@ -242,7 +242,7 @@ module Rails
] + dev_edge_common
elsif options.edge?
[
- GemfileEntry.github('rails', 'rails/rails')
+ GemfileEntry.github('rails', 'rails/rails', '5-0-stable')
] + dev_edge_common
else
[GemfileEntry.version('rails',
@@ -312,7 +312,7 @@ module Rails
end
def coffee_gemfile_entry
- GemfileEntry.github 'coffee-rails', 'rails/coffee-rails', nil, 'Use CoffeeScript for .coffee assets and views'
+ GemfileEntry.version 'coffee-rails', '~> 4.2', 'Use CoffeeScript for .coffee assets and views'
end
def javascript_gemfile_entry
@@ -324,7 +324,7 @@ module Rails
"Use #{options[:javascript]} as the JavaScript library")
unless options[:skip_turbolinks]
- gems << GemfileEntry.version("turbolinks", "~> 5.x",
+ gems << GemfileEntry.version("turbolinks", "~> 5",
"Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks")
end
diff --git a/railties/lib/rails/generators/erb/mailer/mailer_generator.rb b/railties/lib/rails/generators/erb/mailer/mailer_generator.rb
index 7f00943d80..97f3657070 100644
--- a/railties/lib/rails/generators/erb/mailer/mailer_generator.rb
+++ b/railties/lib/rails/generators/erb/mailer/mailer_generator.rb
@@ -9,6 +9,13 @@ module Erb # :nodoc:
view_base_path = File.join("app/views", class_path, file_name + '_mailer')
empty_directory view_base_path
+ if self.behavior == :invoke
+ formats.each do |format|
+ layout_path = File.join('app/views/layouts', class_path, filename_with_extensions('mailer', format))
+ template filename_with_extensions(:layout, format), layout_path
+ end
+ end
+
actions.each do |action|
@action = action
diff --git a/railties/lib/rails/generators/erb/mailer/templates/layout.html.erb.tt b/railties/lib/rails/generators/erb/mailer/templates/layout.html.erb.tt
new file mode 100644
index 0000000000..55f3675d49
--- /dev/null
+++ b/railties/lib/rails/generators/erb/mailer/templates/layout.html.erb.tt
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <style>
+ /* Email styles need to be inline */
+ </style>
+ </head>
+
+ <body>
+ <%%= yield %>
+ </body>
+</html>
diff --git a/railties/lib/rails/generators/erb/mailer/templates/layout.text.erb.tt b/railties/lib/rails/generators/erb/mailer/templates/layout.text.erb.tt
new file mode 100644
index 0000000000..6363733e6e
--- /dev/null
+++ b/railties/lib/rails/generators/erb/mailer/templates/layout.text.erb.tt
@@ -0,0 +1 @@
+<%%= yield %>
diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb
index c288b3dfce..2879be5fa2 100644
--- a/railties/lib/rails/generators/rails/app/app_generator.rb
+++ b/railties/lib/rails/generators/rails/app/app_generator.rb
@@ -90,7 +90,6 @@ module Rails
def config_when_updating
cookie_serializer_config_exist = File.exist?('config/initializers/cookies_serializer.rb')
- new_framework_defaults_config_exist = File.exist?('config/initializers/new_framework_defaults.rb')
action_cable_config_exist = File.exist?('config/cable.yml')
rack_cors_config_exist = File.exist?('config/initializers/cors.rb')
@@ -102,10 +101,6 @@ module Rails
gsub_file 'config/initializers/cookies_serializer.rb', /json(?!,)/, 'marshal'
end
- unless new_framework_defaults_config_exist
- remove_file 'config/initializers/new_framework_defaults.rb'
- end
-
unless action_cable_config_exist
template 'config/cable.yml'
end
@@ -231,6 +226,11 @@ module Rails
end
remove_task :update_config_files
+ def display_upgrade_guide_info
+ say "\nAfter this, check Rails upgrade guide at http://guides.rubyonrails.org/upgrading_ruby_on_rails.html for more details about upgrading your app."
+ end
+ remove_task :display_upgrade_guide_info
+
def create_boot_file
template "config/boot.rb"
end
diff --git a/railties/lib/rails/generators/rails/app/templates/app/assets/config/manifest.js.tt b/railties/lib/rails/generators/rails/app/templates/app/assets/config/manifest.js.tt
index f4ee1409af..70b579d10e 100644
--- a/railties/lib/rails/generators/rails/app/templates/app/assets/config/manifest.js.tt
+++ b/railties/lib/rails/generators/rails/app/templates/app/assets/config/manifest.js.tt
@@ -1,6 +1,4 @@
-<% unless options.api? -%>
//= link_tree ../images
-<% end -%>
<% unless options.skip_javascript -%>
//= link_directory ../javascripts .js
<% end -%>
diff --git a/railties/lib/rails/generators/rails/app/templates/app/channels/application_cable/channel.rb b/railties/lib/rails/generators/rails/app/templates/app/channels/application_cable/channel.rb
index d56fa30f4d..d672697283 100644
--- a/railties/lib/rails/generators/rails/app/templates/app/channels/application_cable/channel.rb
+++ b/railties/lib/rails/generators/rails/app/templates/app/channels/application_cable/channel.rb
@@ -1,4 +1,3 @@
-# Be sure to restart your server when you modify this file. Action Cable runs in a loop that does not support auto reloading.
module ApplicationCable
class Channel < ActionCable::Channel::Base
end
diff --git a/railties/lib/rails/generators/rails/app/templates/app/channels/application_cable/connection.rb b/railties/lib/rails/generators/rails/app/templates/app/channels/application_cable/connection.rb
index b4f41389ad..0ff5442f47 100644
--- a/railties/lib/rails/generators/rails/app/templates/app/channels/application_cable/connection.rb
+++ b/railties/lib/rails/generators/rails/app/templates/app/channels/application_cable/connection.rb
@@ -1,4 +1,3 @@
-# Be sure to restart your server when you modify this file. Action Cable runs in a loop that does not support auto reloading.
module ApplicationCable
class Connection < ActionCable::Connection::Base
end
diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt
index 7a537610e9..f3ccf95045 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt
@@ -46,6 +46,9 @@ Rails.application.configure do
# This option may cause significant delays in view rendering with a large
# number of complex assets.
config.assets.debug = true
+
+ # Suppress logger output for asset requests.
+ config.assets.quiet = true
<%- end -%>
# Raises error for missing translations
diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults.rb.tt
index 730938a1ba..e539f4c457 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults.rb.tt
+++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/new_framework_defaults.rb.tt
@@ -1,37 +1,34 @@
# Be sure to restart your server when you modify this file.
-# This file contains all the new default configuration options from
-# Rails 5.0.
-<%- unless options[:skip_active_record] -%>
-
-# Require `belongs_to` associations by default. This is a new Rails 5.0
-# default, so it is introduced as a configuration option to ensure that apps
-# made on earlier versions of Rails are not affected when upgrading.
-Rails.application.config.active_record.belongs_to_required_by_default = true
+#
+# This file contains migration options to ease your Rails 5.0 upgrade.
+#
+<%- if options[:update] -%>
+# Once upgraded flip defaults one by one to migrate to the new default.
+#
<%- end -%>
-
-# Do not halt callback chains when a callback returns false. This is a new
-# Rails 5.0 default, so it is introduced as a configuration option to ensure
-# that apps made with earlier versions of Rails are not affected when upgrading.
-ActiveSupport.halt_callback_chains_on_return_false = false
+# Read the Guide for Upgrading Ruby on Rails for more info on each option.
<%- unless options[:api] -%>
-# Enable per-form CSRF tokens.
-Rails.application.config.action_controller.per_form_csrf_tokens = true
+# Enable per-form CSRF tokens. Previous versions had false.
+Rails.application.config.action_controller.per_form_csrf_tokens = <%= options[:update] ? false : true %>
-# Enable origin-checking CSRF mitigation.
-Rails.application.config.action_controller.forgery_protection_origin_check = true
+# Enable origin-checking CSRF mitigation. Previous versions had false.
+Rails.application.config.action_controller.forgery_protection_origin_check = <%= options[:update] ? false : true %>
<%- end -%>
-# Configure SSL options to enable HSTS with subdomains. This is a new
-# Rails 5.0 default, so it is introduced as a configuration option to ensure
-# that apps made on earlier versions of Rails are not affected when upgrading.
-Rails.application.config.ssl_options = { hsts: { subdomains: true } }
+# Make Ruby 2.4 preserve the timezone of the receiver when calling `to_time`.
+# Previous versions had false.
+ActiveSupport.to_time_preserves_timezone = <%= options[:update] ? false : true %>
+<%- unless options[:skip_active_record] -%>
-# Preserve the timezone of the receiver when calling to `to_time`.
-# Ruby 2.4 will change the behavior of `to_time` to preserve the timezone
-# when converting to an instance of `Time` instead of the previous behavior
-# of converting to the local system timezone.
-#
-# Rails 5.0 introduced this config option so that apps made with earlier
-# versions of Rails are not affected when upgrading.
-ActiveSupport.to_time_preserves_timezone = true
+# Require `belongs_to` associations by default. Previous versions had false.
+Rails.application.config.active_record.belongs_to_required_by_default = <%= options[:update] ? false : true %>
+<%- end -%>
+
+# Do not halt callback chains when a callback returns false. Previous versions had true.
+ActiveSupport.halt_callback_chains_on_return_false = <%= options[:update] ? true : false %>
+<%- unless options[:update] -%>
+
+# Configure SSL options to enable HSTS with subdomains. Previous versions had false.
+Rails.application.config.ssl_options = { hsts: { subdomains: true } }
+<%- end -%>
diff --git a/railties/lib/rails/generators/rails/app/templates/public/robots.txt b/railties/lib/rails/generators/rails/app/templates/public/robots.txt
index 3c9c7c01f3..37b576a4a0 100644
--- a/railties/lib/rails/generators/rails/app/templates/public/robots.txt
+++ b/railties/lib/rails/generators/rails/app/templates/public/robots.txt
@@ -1,5 +1 @@
# See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file
-#
-# To ban all spiders from the entire site uncomment the next two lines:
-# User-agent: *
-# Disallow: /
diff --git a/railties/lib/rails/generators/rails/plugin/plugin_generator.rb b/railties/lib/rails/generators/rails/plugin/plugin_generator.rb
index 56efd35a95..7f427947f5 100644
--- a/railties/lib/rails/generators/rails/plugin/plugin_generator.rb
+++ b/railties/lib/rails/generators/rails/plugin/plugin_generator.rb
@@ -258,7 +258,7 @@ task default: :test
build(:leftovers)
end
- public_task :apply_rails_template, :run_bundle
+ public_task :apply_rails_template
def run_after_bundle_callbacks
@after_bundle_callbacks.each do |callback|
diff --git a/railties/lib/rails/generators/test_unit/scaffold/templates/api_functional_test.rb b/railties/lib/rails/generators/test_unit/scaffold/templates/api_functional_test.rb
index 0d18478043..c469c188e6 100644
--- a/railties/lib/rails/generators/test_unit/scaffold/templates/api_functional_test.rb
+++ b/railties/lib/rails/generators/test_unit/scaffold/templates/api_functional_test.rb
@@ -11,31 +11,31 @@ class <%= controller_class_name %>ControllerTest < ActionDispatch::IntegrationTe
end
test "should get index" do
- get <%= index_helper %>_url
+ get <%= index_helper %>_url, as: :json
assert_response :success
end
test "should create <%= singular_table_name %>" do
assert_difference('<%= class_name %>.count') do
- post <%= index_helper %>_url, params: { <%= "#{singular_table_name}: { #{attributes_hash} }" %> }
+ post <%= index_helper %>_url, params: { <%= "#{singular_table_name}: { #{attributes_hash} }" %> }, as: :json
end
assert_response 201
end
test "should show <%= singular_table_name %>" do
- get <%= show_helper %>
+ get <%= show_helper %>, as: :json
assert_response :success
end
test "should update <%= singular_table_name %>" do
- patch <%= show_helper %>, params: { <%= "#{singular_table_name}: { #{attributes_hash} }" %> }
+ patch <%= show_helper %>, params: { <%= "#{singular_table_name}: { #{attributes_hash} }" %> }, as: :json
assert_response 200
end
test "should destroy <%= singular_table_name %>" do
assert_difference('<%= class_name %>.count', -1) do
- delete <%= show_helper %>
+ delete <%= show_helper %>, as: :json
end
assert_response 204
diff --git a/railties/lib/rails/source_annotation_extractor.rb b/railties/lib/rails/source_annotation_extractor.rb
index 8dd87b6cc5..ca195bd752 100644
--- a/railties/lib/rails/source_annotation_extractor.rb
+++ b/railties/lib/rails/source_annotation_extractor.rb
@@ -1,9 +1,9 @@
# Implements the logic behind the rake tasks for annotations like
#
-# rake notes
-# rake notes:optimize
+# rails notes
+# rails notes:optimize
#
-# and friends. See <tt>rake -T notes</tt> and <tt>railties/lib/rails/tasks/annotations.rake</tt>.
+# and friends. See <tt>rails -T notes</tt> and <tt>railties/lib/rails/tasks/annotations.rake</tt>.
#
# Annotation objects are triplets <tt>:line</tt>, <tt>:tag</tt>, <tt>:text</tt> that
# represent the line where the annotation lives, its tag, and its text. Note
diff --git a/railties/lib/rails/tasks/framework.rake b/railties/lib/rails/tasks/framework.rake
index 3e771167ee..255312493f 100644
--- a/railties/lib/rails/tasks/framework.rake
+++ b/railties/lib/rails/tasks/framework.rake
@@ -2,7 +2,7 @@ require 'active_support/deprecation'
namespace :app do
desc "Update configs and some other initially generated files (or use just update:configs or update:bin)"
- task update: [ "update:configs", "update:bin" ]
+ task update: [ "update:configs", "update:bin", "update:upgrade_guide_info" ]
desc "Applies the template supplied by LOCATION=(/path/to/template) or URL"
task template: :environment do
@@ -48,7 +48,7 @@ namespace :app do
require 'rails/generators'
require 'rails/generators/rails/app/app_generator'
gen = Rails::Generators::AppGenerator.new ["rails"],
- { api: !!Rails.application.config.api_only },
+ { api: !!Rails.application.config.api_only, update: true },
destination_root: Rails.root
File.exist?(Rails.root.join("config", "application.rb")) ?
gen.send(:app_const) : gen.send(:valid_const?)
@@ -67,6 +67,10 @@ namespace :app do
task :bin do
RailsUpdate.invoke_from_app_generator :create_bin_files
end
+
+ task :upgrade_guide_info do
+ RailsUpdate.invoke_from_app_generator :display_upgrade_guide_info
+ end
end
end
diff --git a/railties/test/application/assets_test.rb b/railties/test/application/assets_test.rb
index 9e8531b482..12bdbcf23e 100644
--- a/railties/test/application/assets_test.rb
+++ b/railties/test/application/assets_test.rb
@@ -188,7 +188,7 @@ module ApplicationTests
test 'sprockets cache is not shared between environments' do
app_file "app/assets/images/rails.png", "notactuallyapng"
- app_file "app/assets/stylesheets/application.css.erb", "<%= asset_path('rails.png') %>"
+ app_file "app/assets/stylesheets/application.css.erb", "body { background: '<%= asset_path('rails.png') %>'; }"
add_to_env_config 'production', 'config.assets.prefix = "production_assets"'
precompile!
diff --git a/railties/test/application/routing_test.rb b/railties/test/application/routing_test.rb
index e51f32aaed..93847c7aa9 100644
--- a/railties/test/application/routing_test.rb
+++ b/railties/test/application/routing_test.rb
@@ -39,6 +39,25 @@ module ApplicationTests
assert_equal 200, last_response.status
end
+ test "/rails/info routes are accessible with globbing route present" do
+ app("development")
+
+ app_file "config/routes.rb", <<-RUBY
+ Rails.application.routes.draw do
+ get '*foo', to: 'foo#index'
+ end
+ RUBY
+
+ get "/rails/info"
+ assert_equal 302, last_response.status
+
+ get "rails/info/routes"
+ assert_equal 200, last_response.status
+
+ get "rails/info/properties"
+ assert_equal 200, last_response.status
+ end
+
test "root takes precedence over internal welcome controller" do
app("development")
diff --git a/railties/test/backtrace_cleaner_test.rb b/railties/test/backtrace_cleaner_test.rb
index 2dd74f8fd1..1b23b0de91 100644
--- a/railties/test/backtrace_cleaner_test.rb
+++ b/railties/test/backtrace_cleaner_test.rb
@@ -1,24 +1,32 @@
require 'abstract_unit'
require 'rails/backtrace_cleaner'
-class BacktraceCleanerVendorGemTest < ActiveSupport::TestCase
+class BacktraceCleanerTest < ActiveSupport::TestCase
def setup
@cleaner = Rails::BacktraceCleaner.new
end
test "should format installed gems correctly" do
- @backtrace = [ "#{Gem.path[0]}/gems/nosuchgem-1.2.3/lib/foo.rb" ]
- @result = @cleaner.clean(@backtrace, :all)
- assert_equal "nosuchgem (1.2.3) lib/foo.rb", @result[0]
+ backtrace = [ "#{Gem.path[0]}/gems/nosuchgem-1.2.3/lib/foo.rb" ]
+ result = @cleaner.clean(backtrace, :all)
+ assert_equal "nosuchgem (1.2.3) lib/foo.rb", result[0]
end
test "should format installed gems not in Gem.default_dir correctly" do
- @target_dir = Gem.path.detect { |p| p != Gem.default_dir }
+ target_dir = Gem.path.detect { |p| p != Gem.default_dir }
# skip this test if default_dir is the only directory on Gem.path
if @target_dir
- @backtrace = [ "#{@target_dir}/gems/nosuchgem-1.2.3/lib/foo.rb" ]
- @result = @cleaner.clean(@backtrace, :all)
- assert_equal "nosuchgem (1.2.3) lib/foo.rb", @result[0]
+ backtrace = [ "#{target_dir}/gems/nosuchgem-1.2.3/lib/foo.rb" ]
+ result = @cleaner.clean(backtrace, :all)
+ assert_equal "nosuchgem (1.2.3) lib/foo.rb", result[0]
end
end
+
+ test "should consider traces from irb lines as User code" do
+ backtrace = [ "from (irb):1",
+ "from /Path/to/rails/railties/lib/rails/commands/console.rb:77:in `start'",
+ "from bin/rails:4:in `<main>'" ]
+ result = @cleaner.clean(backtrace, :all)
+ assert_equal "from (irb):1", result[0]
+ end
end
diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb
index bea8db087f..ac1488abb3 100644
--- a/railties/test/generators/app_generator_test.rb
+++ b/railties/test/generators/app_generator_test.rb
@@ -208,24 +208,15 @@ class AppGeneratorTest < Rails::Generators::TestCase
FileUtils.rm("#{app_root}/config/initializers/new_framework_defaults.rb")
stub_rails_application(app_root) do
- generator = Rails::Generators::AppGenerator.new ["rails"], [], destination_root: app_root, shell: @shell
+ generator = Rails::Generators::AppGenerator.new ["rails"], { update: true }, destination_root: app_root, shell: @shell
generator.send(:app_const)
quietly { generator.send(:update_config_files) }
- assert_no_file "#{app_root}/config/initializers/new_framework_defaults.rb"
- end
- end
-
- def test_rails_update_does_not_new_framework_defaults_if_already_present
- app_root = File.join(destination_root, 'myapp')
- run_generator [app_root]
- FileUtils.touch("#{app_root}/config/initializers/new_framework_defaults.rb")
-
- stub_rails_application(app_root) do
- generator = Rails::Generators::AppGenerator.new ["rails"], [], destination_root: app_root, shell: @shell
- generator.send(:app_const)
- quietly { generator.send(:update_config_files) }
- assert_file "#{app_root}/config/initializers/new_framework_defaults.rb"
+ assert_file "#{app_root}/config/initializers/new_framework_defaults.rb" do |content|
+ assert_match(/ActiveSupport\.halt_callback_chains_on_return_false = true/, content)
+ assert_match(/Rails\.application\.config.active_record\.belongs_to_required_by_default = false/, content)
+ assert_no_match(/Rails\.application\.config\.ssl_options/, content)
+ end
end
end
@@ -606,6 +597,21 @@ class AppGeneratorTest < Rails::Generators::TestCase
end
end
+ def test_generation_runs_bundle_install
+ assert_generates_with_bundler
+ end
+
+ def test_dev_option
+ assert_generates_with_bundler dev: true
+ rails_path = File.expand_path('../../..', Rails.root)
+ assert_file 'Gemfile', /^gem\s+["']rails["'],\s+path:\s+["']#{Regexp.escape(rails_path)}["']$/
+ end
+
+ def test_edge_option
+ assert_generates_with_bundler edge: true
+ assert_file 'Gemfile', %r{^gem\s+["']rails["'],\s+github:\s+["']#{Regexp.escape("rails/rails")}["'],\s+branch:\s+["']#{Regexp.escape("5-0-stable")}["']$}
+ end
+
def test_spring
run_generator
assert_gem 'spring'
@@ -763,41 +769,61 @@ class AppGeneratorTest < Rails::Generators::TestCase
protected
- def stub_rails_application(root)
- Rails.application.config.root = root
- Rails.application.class.stub(:name, "Myapp") do
- yield
+ def stub_rails_application(root)
+ Rails.application.config.root = root
+ Rails.application.class.stub(:name, "Myapp") do
+ yield
+ end
end
- end
- def action(*args, &block)
- capture(:stdout) { generator.send(*args, &block) }
- end
+ def action(*args, &block)
+ capture(:stdout) { generator.send(*args, &block) }
+ end
- def assert_gem(gem, constraint = nil)
- if constraint
- assert_file "Gemfile", /^\s*gem\s+["']#{gem}["'], #{constraint}$*/
- else
- assert_file "Gemfile", /^\s*gem\s+["']#{gem}["']$*/
+ def assert_gem(gem, constraint = nil)
+ if constraint
+ assert_file "Gemfile", /^\s*gem\s+["']#{gem}["'], #{constraint}$*/
+ else
+ assert_file "Gemfile", /^\s*gem\s+["']#{gem}["']$*/
+ end
end
- end
- def assert_listen_related_configuration
- assert_gem 'listen'
- assert_gem 'spring-watcher-listen'
+ def assert_listen_related_configuration
+ assert_gem 'listen'
+ assert_gem 'spring-watcher-listen'
- assert_file 'config/environments/development.rb' do |content|
- assert_match(/^\s*config.file_watcher = ActiveSupport::EventedFileUpdateChecker/, content)
+ assert_file 'config/environments/development.rb' do |content|
+ assert_match(/^\s*config.file_watcher = ActiveSupport::EventedFileUpdateChecker/, content)
+ end
end
- end
- def assert_no_listen_related_configuration
- assert_file 'Gemfile' do |content|
- assert_no_match(/listen/, content)
+ def assert_no_listen_related_configuration
+ assert_file 'Gemfile' do |content|
+ assert_no_match(/listen/, content)
+ end
+
+ assert_file 'config/environments/development.rb' do |content|
+ assert_match(/^\s*# config.file_watcher = ActiveSupport::EventedFileUpdateChecker/, content)
+ end
end
- assert_file 'config/environments/development.rb' do |content|
- assert_match(/^\s*# config.file_watcher = ActiveSupport::EventedFileUpdateChecker/, content)
+ def assert_generates_with_bundler(options = {})
+ generator([destination_root], options)
+
+ command_check = -> command do
+ @install_called ||= 0
+
+ case command
+ when 'install'
+ @install_called += 1
+ assert_equal 1, @install_called, "install expected to be called once, but was called #{@install_called} times"
+ when 'exec spring binstub --all'
+ # Called when running tests with spring, let through unscathed.
+ end
+ end
+
+ generator.stub :bundle_command, command_check do
+ quietly { generator.invoke_all }
+ end
end
- end
end
diff --git a/railties/test/generators/mailer_generator_test.rb b/railties/test/generators/mailer_generator_test.rb
index 8728b39dae..6a4951840d 100644
--- a/railties/test/generators/mailer_generator_test.rb
+++ b/railties/test/generators/mailer_generator_test.rb
@@ -84,6 +84,10 @@ class MailerGeneratorTest < Rails::Generators::TestCase
assert_match(%r(\sapp/views/notifier_mailer/bar\.text\.erb), view)
assert_match(/<%= @greeting %>/, view)
end
+
+ assert_file "app/views/layouts/mailer.text.erb" do |view|
+ assert_match(/<%= yield %>/, view)
+ end
end
def test_invokes_default_html_template_engine
@@ -97,6 +101,10 @@ class MailerGeneratorTest < Rails::Generators::TestCase
assert_match(%r(\sapp/views/notifier_mailer/bar\.html\.erb), view)
assert_match(/<%= @greeting %>/, view)
end
+
+ assert_file "app/views/layouts/mailer.html.erb" do |view|
+ assert_match(%r{<body>\n <%= yield %>\n </body>}, view)
+ end
end
def test_invokes_default_template_engine_even_with_no_action
diff --git a/railties/test/generators/model_generator_test.rb b/railties/test/generators/model_generator_test.rb
index ed6846abc3..6b30c40476 100644
--- a/railties/test/generators/model_generator_test.rb
+++ b/railties/test/generators/model_generator_test.rb
@@ -34,7 +34,7 @@ class ModelGeneratorTest < Rails::Generators::TestCase
def test_invokes_default_orm
run_generator
- assert_file "app/models/account.rb", /class Account < ActiveRecord::Base/
+ assert_file "app/models/account.rb", /class Account < ApplicationRecord/
end
def test_model_with_parent_option
@@ -56,7 +56,7 @@ class ModelGeneratorTest < Rails::Generators::TestCase
def test_plural_names_are_singularized
content = run_generator ["accounts".freeze]
- assert_file "app/models/account.rb", /class Account < ActiveRecord::Base/
+ assert_file "app/models/account.rb", /class Account < ApplicationRecord/
assert_file "test/models/account_test.rb", /class AccountTest/
assert_match(/\[WARNING\] The model name 'accounts' was recognized as a plural, using the singular 'account' instead\. Override with --force-plural or setup custom inflection rules for this noun before running the generator\./, content)
end
@@ -71,7 +71,7 @@ class ModelGeneratorTest < Rails::Generators::TestCase
assert_file "app/models/admin.rb", /module Admin/
assert_file "app/models/admin.rb", /def self\.table_name_prefix/
assert_file "app/models/admin.rb", /'admin_'/
- assert_file "app/models/admin/account.rb", /class Admin::Account < ActiveRecord::Base/
+ assert_file "app/models/admin/account.rb", /class Admin::Account < ApplicationRecord/
end
def test_migration
@@ -386,7 +386,7 @@ class ModelGeneratorTest < Rails::Generators::TestCase
run_generator ["account", "supplier:references{required}"]
expected_file = <<-FILE.strip_heredoc
- class Account < ActiveRecord::Base
+ class Account < ApplicationRecord
belongs_to :supplier, required: true
end
FILE
@@ -397,7 +397,7 @@ class ModelGeneratorTest < Rails::Generators::TestCase
run_generator ["account", "supplier:references{required,polymorphic}"]
expected_file = <<-FILE.strip_heredoc
- class Account < ActiveRecord::Base
+ class Account < ApplicationRecord
belongs_to :supplier, polymorphic: true, required: true
end
FILE
@@ -408,7 +408,7 @@ class ModelGeneratorTest < Rails::Generators::TestCase
run_generator ["account", "supplier:references{polymorphic.required}"]
expected_file = <<-FILE.strip_heredoc
- class Account < ActiveRecord::Base
+ class Account < ApplicationRecord
belongs_to :supplier, polymorphic: true, required: true
end
FILE
@@ -459,7 +459,7 @@ class ModelGeneratorTest < Rails::Generators::TestCase
def test_token_option_adds_has_secure_token
run_generator ["user", "token:token", "auth_token:token"]
expected_file = <<-FILE.strip_heredoc
- class User < ActiveRecord::Base
+ class User < ApplicationRecord
has_secure_token
has_secure_token :auth_token
end
diff --git a/railties/test/generators/namespaced_generators_test.rb b/railties/test/generators/namespaced_generators_test.rb
index d76759a7d1..902c340321 100644
--- a/railties/test/generators/namespaced_generators_test.rb
+++ b/railties/test/generators/namespaced_generators_test.rb
@@ -91,7 +91,7 @@ class NamespacedModelGeneratorTest < NamespacedGeneratorTestCase
def test_adds_namespace_to_model
run_generator
- assert_file "app/models/test_app/account.rb", /module TestApp/, / class Account < ActiveRecord::Base/
+ assert_file "app/models/test_app/account.rb", /module TestApp/, / class Account < ApplicationRecord/
end
def test_model_with_namespace
@@ -99,7 +99,7 @@ class NamespacedModelGeneratorTest < NamespacedGeneratorTestCase
assert_file "app/models/test_app/admin.rb", /module TestApp/, /module Admin/
assert_file "app/models/test_app/admin.rb", /def self\.table_name_prefix/
assert_file "app/models/test_app/admin.rb", /'test_app_admin_'/
- assert_file "app/models/test_app/admin/account.rb", /module TestApp/, /class Admin::Account < ActiveRecord::Base/
+ assert_file "app/models/test_app/admin/account.rb", /module TestApp/, /class Admin::Account < ApplicationRecord/
end
def test_migration
@@ -201,7 +201,7 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase
run_generator
# Model
- assert_file "app/models/test_app/product_line.rb", /module TestApp\n class ProductLine < ActiveRecord::Base/
+ assert_file "app/models/test_app/product_line.rb", /module TestApp\n class ProductLine < ApplicationRecord/
assert_file "test/models/test_app/product_line_test.rb", /module TestApp\n class ProductLineTest < ActiveSupport::TestCase/
assert_file "test/fixtures/test_app/product_lines.yml"
assert_migration "db/migrate/create_test_app_product_lines.rb"
@@ -268,7 +268,7 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase
# Model
assert_file "app/models/test_app/admin.rb", /module TestApp\n module Admin/
- assert_file "app/models/test_app/admin/role.rb", /module TestApp\n class Admin::Role < ActiveRecord::Base/
+ assert_file "app/models/test_app/admin/role.rb", /module TestApp\n class Admin::Role < ApplicationRecord/
assert_file "test/models/test_app/admin/role_test.rb", /module TestApp\n class Admin::RoleTest < ActiveSupport::TestCase/
assert_file "test/fixtures/test_app/admin/roles.yml"
assert_migration "db/migrate/create_test_app_admin_roles.rb"
@@ -336,7 +336,7 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase
# Model
assert_file "app/models/test_app/admin/user/special.rb", /module TestApp\n module Admin/
- assert_file "app/models/test_app/admin/user/special/role.rb", /module TestApp\n class Admin::User::Special::Role < ActiveRecord::Base/
+ assert_file "app/models/test_app/admin/user/special/role.rb", /module TestApp\n class Admin::User::Special::Role < ApplicationRecord/
assert_file "test/models/test_app/admin/user/special/role_test.rb", /module TestApp\n class Admin::User::Special::RoleTest < ActiveSupport::TestCase/
assert_file "test/fixtures/test_app/admin/user/special/roles.yml"
assert_migration "db/migrate/create_test_app_admin_user_special_roles.rb"
@@ -402,7 +402,7 @@ class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase
# Model
assert_file "app/models/test_app/admin.rb", /module TestApp\n module Admin/
- assert_file "app/models/test_app/admin/role.rb", /module TestApp\n class Admin::Role < ActiveRecord::Base/
+ assert_file "app/models/test_app/admin/role.rb", /module TestApp\n class Admin::Role < ApplicationRecord/
assert_file "test/models/test_app/admin/role_test.rb", /module TestApp\n class Admin::RoleTest < ActiveSupport::TestCase/
assert_file "test/fixtures/test_app/admin/roles.yml"
assert_migration "db/migrate/create_test_app_admin_roles.rb"
diff --git a/railties/test/generators/plugin_generator_test.rb b/railties/test/generators/plugin_generator_test.rb
index 3cc8e1de55..823dcc50ee 100644
--- a/railties/test/generators/plugin_generator_test.rb
+++ b/railties/test/generators/plugin_generator_test.rb
@@ -193,13 +193,24 @@ class PluginGeneratorTest < Rails::Generators::TestCase
assert_file "test/dummy/config/database.yml", /postgres/
end
- def test_generation_runs_bundle_install_with_full_and_mountable
- result = run_generator [destination_root, "--mountable", "--full", "--dev"]
- assert_match(/run bundle install/, result)
- assert $?.success?, "Command failed: #{result}"
- assert_file "#{destination_root}/Gemfile.lock" do |contents|
- assert_match(/bukkits/, contents)
- end
+ def test_generation_runs_bundle_install
+ assert_generates_without_bundler
+ end
+
+ def test_dev_option
+ assert_generates_without_bundler(dev: true)
+ rails_path = File.expand_path('../../..', Rails.root)
+ assert_file 'Gemfile', /^gem\s+["']rails["'],\s+path:\s+["']#{Regexp.escape(rails_path)}["']$/
+ end
+
+ def test_edge_option
+ assert_generates_without_bundler(edge: true)
+ assert_file 'Gemfile', %r{^gem\s+["']rails["'],\s+github:\s+["']#{Regexp.escape("rails/rails")}["'],\s+branch:\s+["']#{Regexp.escape("5-0-stable")}["']$}
+ end
+
+ def test_generation_does_not_run_bundle_install_with_full_and_mountable
+ assert_generates_without_bundler(mountable: true, full: true, dev: true)
+ assert_no_file "#{destination_root}/Gemfile.lock"
end
def test_skipping_javascripts_without_mountable_option
@@ -669,6 +680,21 @@ class PluginGeneratorTest < Rails::Generators::TestCase
end
end
+ def test_generate_mailer_layouts_when_does_not_exist_in_mountable_engine
+ run_generator [destination_root, '--mountable']
+ capture(:stdout) do
+ `#{destination_root}/bin/rails g mailer User`
+ end
+
+ assert_file "#{destination_root}/app/views/layouts/bukkits/mailer.text.erb" do |view|
+ assert_match(/<%= yield %>/, view)
+ end
+
+ assert_file "#{destination_root}/app/views/layouts/bukkits/mailer.html.erb" do |view|
+ assert_match(%r{<body>\n <%= yield %>\n </body>}, view)
+ end
+ end
+
def test_generate_application_job_when_does_not_exist_in_mountable_engine
run_generator [destination_root, '--mountable']
FileUtils.rm "#{destination_root}/app/jobs/bukkits/application_job.rb"
@@ -682,48 +708,38 @@ class PluginGeneratorTest < Rails::Generators::TestCase
end
end
- def test_after_bundle_callback
- path = 'http://example.org/rails_template'
- template = %{ after_bundle { run 'echo ran after_bundle' } }
- template.instance_eval "def read; self; end" # Make the string respond to read
+ protected
- check_open = -> *args do
- assert_equal [ path, 'Accept' => 'application/x-thor-template' ], args
- template
+ def action(*args, &block)
+ silence(:stdout){ generator.send(*args, &block) }
end
- sequence = ['install', 'echo ran after_bundle']
- @sequence_step ||= 0
- ensure_bundler_first = -> command do
- assert_equal sequence[@sequence_step], command, "commands should be called in sequence #{sequence}"
- @sequence_step += 1
+ def default_files
+ ::DEFAULT_PLUGIN_FILES
end
- generator([destination_root], template: path).stub(:open, check_open, template) do
- generator.stub(:bundle_command, ensure_bundler_first) do
- generator.stub(:run, ensure_bundler_first) do
- quietly { generator.invoke_all }
- end
+ def assert_match_sqlite3(contents)
+ if defined?(JRUBY_VERSION)
+ assert_match(/group :development do\n gem 'activerecord-jdbcsqlite3-adapter'\nend/, contents)
+ else
+ assert_match(/group :development do\n gem 'sqlite3'\nend/, contents)
end
end
- assert_equal 2, @sequence_step
- end
-
-protected
- def action(*args, &block)
- silence(:stdout){ generator.send(*args, &block) }
- end
+ def assert_generates_without_bundler(options = {})
+ generator([destination_root], options)
- def default_files
- ::DEFAULT_PLUGIN_FILES
- end
+ command_check = -> command do
+ case command
+ when 'install'
+ flunk "install expected to not be called"
+ when 'exec spring binstub --all'
+ # Called when running tests with spring, let through unscathed.
+ end
+ end
- def assert_match_sqlite3(contents)
- if defined?(JRUBY_VERSION)
- assert_match(/group :development do\n gem 'activerecord-jdbcsqlite3-adapter'\nend/, contents)
- else
- assert_match(/group :development do\n gem 'sqlite3'\nend/, contents)
+ generator.stub :bundle_command, command_check do
+ quietly { generator.invoke_all }
+ end
end
- end
end
diff --git a/railties/test/generators/resource_generator_test.rb b/railties/test/generators/resource_generator_test.rb
index addaf83bc8..53dcfc4024 100644
--- a/railties/test/generators/resource_generator_test.rb
+++ b/railties/test/generators/resource_generator_test.rb
@@ -60,14 +60,14 @@ class ResourceGeneratorTest < Rails::Generators::TestCase
def test_plural_names_are_singularized
content = run_generator ["accounts".freeze]
- assert_file "app/models/account.rb", /class Account < ActiveRecord::Base/
+ assert_file "app/models/account.rb", /class Account < ApplicationRecord/
assert_file "test/models/account_test.rb", /class AccountTest/
assert_match(/\[WARNING\] The model name 'accounts' was recognized as a plural, using the singular 'account' instead\. Override with --force-plural or setup custom inflection rules for this noun before running the generator\./, content)
end
def test_plural_names_can_be_forced
content = run_generator ["accounts", "--force-plural"]
- assert_file "app/models/accounts.rb", /class Accounts < ActiveRecord::Base/
+ assert_file "app/models/accounts.rb", /class Accounts < ApplicationRecord/
assert_file "test/models/accounts_test.rb", /class AccountsTest/
assert_no_match(/\[WARNING\]/, content)
end
diff --git a/railties/test/generators/scaffold_controller_generator_test.rb b/railties/test/generators/scaffold_controller_generator_test.rb
index c37e289f4b..736ff0b41f 100644
--- a/railties/test/generators/scaffold_controller_generator_test.rb
+++ b/railties/test/generators/scaffold_controller_generator_test.rb
@@ -238,8 +238,8 @@ class ScaffoldControllerGeneratorTest < Rails::Generators::TestCase
assert_file "test/controllers/users_controller_test.rb" do |content|
assert_match(/class UsersControllerTest < ActionDispatch::IntegrationTest/, content)
assert_match(/test "should get index"/, content)
- assert_match(/post users_url, params: \{ user: \{ age: @user\.age, name: @user\.name, organization_id: @user\.organization_id, organization_type: @user\.organization_type \} \}/, content)
- assert_match(/patch user_url\(@user\), params: \{ user: \{ age: @user\.age, name: @user\.name, organization_id: @user\.organization_id, organization_type: @user\.organization_type \} \}/, content)
+ assert_match(/post users_url, params: \{ user: \{ age: @user\.age, name: @user\.name, organization_id: @user\.organization_id, organization_type: @user\.organization_type \} \}, as: :json/, content)
+ assert_match(/patch user_url\(@user\), params: \{ user: \{ age: @user\.age, name: @user\.name, organization_id: @user\.organization_id, organization_type: @user\.organization_type \} \}, as: :json/, content)
assert_no_match(/assert_redirected_to/, content)
end
end
diff --git a/railties/test/generators/scaffold_generator_test.rb b/railties/test/generators/scaffold_generator_test.rb
index 146be5a85a..bd69906b9d 100644
--- a/railties/test/generators/scaffold_generator_test.rb
+++ b/railties/test/generators/scaffold_generator_test.rb
@@ -11,7 +11,7 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase
run_generator
# Model
- assert_file "app/models/product_line.rb", /class ProductLine < ActiveRecord::Base/
+ assert_file "app/models/product_line.rb", /class ProductLine < ApplicationRecord/
assert_file "test/models/product_line_test.rb", /class ProductLineTest < ActiveSupport::TestCase/
assert_file "test/fixtures/product_lines.yml"
assert_migration "db/migrate/create_product_lines.rb", /belongs_to :product/
@@ -91,7 +91,7 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase
run_generator %w(product_line title:string product:belongs_to user:references --api --no-template-engine --no-helper --no-assets)
# Model
- assert_file "app/models/product_line.rb", /class ProductLine < ActiveRecord::Base/
+ assert_file "app/models/product_line.rb", /class ProductLine < ApplicationRecord/
assert_file "test/models/product_line_test.rb", /class ProductLineTest < ActiveSupport::TestCase/
assert_file "test/fixtures/product_lines.yml"
assert_migration "db/migrate/create_product_lines.rb", /belongs_to :product/
@@ -205,7 +205,7 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase
# Model
assert_file "app/models/admin.rb", /module Admin/
- assert_file "app/models/admin/role.rb", /class Admin::Role < ActiveRecord::Base/
+ assert_file "app/models/admin/role.rb", /class Admin::Role < ApplicationRecord/
assert_file "test/models/admin/role_test.rb", /class Admin::RoleTest < ActiveSupport::TestCase/
assert_file "test/fixtures/admin/roles.yml"
assert_migration "db/migrate/create_admin_roles.rb"
diff --git a/railties/test/generators/shared_generator_tests.rb b/railties/test/generators/shared_generator_tests.rb
index e83d54890a..03ea521355 100644
--- a/railties/test/generators/shared_generator_tests.rb
+++ b/railties/test/generators/shared_generator_tests.rb
@@ -26,30 +26,6 @@ module SharedGeneratorTests
default_files.each { |path| assert_file path }
end
- def assert_generates_with_bundler(options = {})
- generator([destination_root], options)
-
- command_check = -> command do
- @install_called ||= 0
-
- case command
- when 'install'
- @install_called += 1
- assert_equal 1, @install_called, "install expected to be called once, but was called #{@install_called} times"
- when 'exec spring binstub --all'
- # Called when running tests with spring, let through unscathed.
- end
- end
-
- generator.stub :bundle_command, command_check do
- quietly { generator.invoke_all }
- end
- end
-
- def test_generation_runs_bundle_install
- assert_generates_with_bundler
- end
-
def test_plugin_new_generate_pretend
run_generator ["testapp", "--pretend"]
default_files.each{ |path| assert_no_file File.join("testapp",path) }
@@ -114,17 +90,6 @@ module SharedGeneratorTests
end
end
- def test_dev_option
- assert_generates_with_bundler dev: true
- rails_path = File.expand_path('../../..', Rails.root)
- assert_file 'Gemfile', /^gem\s+["']rails["'],\s+path:\s+["']#{Regexp.escape(rails_path)}["']$/
- end
-
- def test_edge_option
- assert_generates_with_bundler edge: true
- assert_file 'Gemfile', %r{^gem\s+["']rails["'],\s+github:\s+["']#{Regexp.escape("rails/rails")}["']$}
- end
-
def test_skip_gemfile
assert_not_called(generator([destination_root], skip_gemfile: true), :bundle_command) do
quietly { generator.invoke_all }
diff --git a/railties/test/isolation/abstract_unit.rb b/railties/test/isolation/abstract_unit.rb
index 9dac1008fa..e427614dfa 100644
--- a/railties/test/isolation/abstract_unit.rb
+++ b/railties/test/isolation/abstract_unit.rb
@@ -18,6 +18,7 @@ RAILS_FRAMEWORK_ROOT = File.expand_path("#{File.dirname(__FILE__)}/../../..")
# These files do not require any others and are needed
# to run the tests
+require "active_support/core_ext/object/blank"
require "active_support/testing/isolation"
require "active_support/core_ext/kernel/reporting"
require 'tmpdir'
diff --git a/railties/test/rails_info_controller_test.rb b/railties/test/rails_info_controller_test.rb
index c51503c2b7..2e10d63599 100644
--- a/railties/test/rails_info_controller_test.rb
+++ b/railties/test/rails_info_controller_test.rb
@@ -78,4 +78,10 @@ class InfoControllerTest < ActionController::TestCase
get :routes, params: { path: 'rails/info/routes.html' }
assert fuzzy_count.call == 0, 'should match optional parts of route literally'
end
+
+ test "internal routes do not have a default params[:internal] value" do
+ get :properties
+ assert_response :success
+ assert_nil @controller.params[:internal]
+ end
end
diff --git a/railties/test/railties/engine_test.rb b/railties/test/railties/engine_test.rb
index 4a47ab32b4..fb8a7656d0 100644
--- a/railties/test/railties/engine_test.rb
+++ b/railties/test/railties/engine_test.rb
@@ -481,7 +481,7 @@ YAML
end
RUBY
- add_to_config "config.middleware.use \"Bukkits\""
+ add_to_config "config.middleware.use Bukkits"
boot_rails
end
@@ -1155,10 +1155,10 @@ YAML
assert_equal "App's bar partial", last_response.body.strip
get("/assets/foo.js")
- assert_equal "// Bukkit's foo js", last_response.body.strip
+ assert_match "// Bukkit's foo js", last_response.body.strip
get("/assets/bar.js")
- assert_equal "// App's bar js", last_response.body.strip
+ assert_match "// App's bar js", last_response.body.strip
# ensure that railties are not added twice
railties = Rails.application.send(:ordered_railties).map(&:class)
diff --git a/tasks/release.rb b/tasks/release.rb
index 4a1ed04478..045bcc5b5f 100644
--- a/tasks/release.rb
+++ b/tasks/release.rb
@@ -43,7 +43,28 @@ directory "pkg"
raise "Could not insert PRE in #{file}" unless $1
File.open(file, 'w') { |f| f.write ruby }
+ end
+
+ task gem => %w(update_versions pkg) do
+ cmd = ""
+ cmd << "cd #{framework} && " unless framework == "rails"
+ cmd << "bundle exec rake package && " unless framework == "rails"
+ cmd << "gem build #{gemspec} && mv #{framework}-#{version}.gem #{root}/pkg/"
+ sh cmd
+ end
+
+ task :build => [:clean, gem]
+ task :install => :build do
+ sh "gem install --pre #{gem}"
+ end
+
+ task :push => :build do
+ sh "gem push #{gem}"
+ # When running the release task we usually run build first to check that the gem works properly.
+ # NPM will refuse to publish or rebuild the gem if the version is changed when the Rails gem
+ # versions are changed. This then causes the gem push to fail. Because of this we need to update
+ # the version and publish at the same time.
if File.exist?("#{framework}/package.json")
Dir.chdir("#{framework}") do
# This "npm-ifies" the current version
@@ -68,30 +89,13 @@ directory "pkg"
# Check if npm is installed, and raise an error if not
if sh 'which npm'
sh "npm version #{version} --no-git-tag-version"
+ sh "npm publish"
else
raise 'You must have npm installed to release Rails.'
end
end
end
end
-
- task gem => %w(update_versions pkg) do
- cmd = ""
- cmd << "cd #{framework} && " unless framework == "rails"
- cmd << "bundle exec rake package && " unless framework == "rails"
- cmd << "gem build #{gemspec} && mv #{framework}-#{version}.gem #{root}/pkg/"
- sh cmd
- end
-
- task :build => [:clean, gem]
- task :install => :build do
- sh "gem install --pre #{gem}"
- end
-
- task :push => :build do
- sh "gem push #{gem}"
- sh "npm publish" if File.exist?("#{framework}/package.json")
- end
end
end