aboutsummaryrefslogtreecommitdiffstats
path: root/railties
diff options
context:
space:
mode:
Diffstat (limited to 'railties')
-rw-r--r--railties/CHANGELOG10
-rwxr-xr-x[-rw-r--r--]railties/Rakefile7
-rw-r--r--railties/guides/assets/javascripts/code_highlighter.js188
-rw-r--r--railties/guides/assets/javascripts/highlighters.js90
-rw-r--r--railties/guides/assets/javascripts/syntaxhighlighter/shBrushAS3.js59
-rw-r--r--railties/guides/assets/javascripts/syntaxhighlighter/shBrushAppleScript.js75
-rw-r--r--railties/guides/assets/javascripts/syntaxhighlighter/shBrushBash.js59
-rw-r--r--railties/guides/assets/javascripts/syntaxhighlighter/shBrushCSharp.js65
-rw-r--r--railties/guides/assets/javascripts/syntaxhighlighter/shBrushColdFusion.js100
-rw-r--r--railties/guides/assets/javascripts/syntaxhighlighter/shBrushCpp.js97
-rw-r--r--railties/guides/assets/javascripts/syntaxhighlighter/shBrushCss.js91
-rw-r--r--railties/guides/assets/javascripts/syntaxhighlighter/shBrushDelphi.js55
-rw-r--r--railties/guides/assets/javascripts/syntaxhighlighter/shBrushDiff.js41
-rw-r--r--railties/guides/assets/javascripts/syntaxhighlighter/shBrushErlang.js52
-rw-r--r--railties/guides/assets/javascripts/syntaxhighlighter/shBrushGroovy.js67
-rw-r--r--railties/guides/assets/javascripts/syntaxhighlighter/shBrushJScript.js52
-rw-r--r--railties/guides/assets/javascripts/syntaxhighlighter/shBrushJava.js57
-rw-r--r--railties/guides/assets/javascripts/syntaxhighlighter/shBrushJavaFX.js58
-rw-r--r--railties/guides/assets/javascripts/syntaxhighlighter/shBrushPerl.js72
-rw-r--r--railties/guides/assets/javascripts/syntaxhighlighter/shBrushPhp.js88
-rw-r--r--railties/guides/assets/javascripts/syntaxhighlighter/shBrushPlain.js33
-rw-r--r--railties/guides/assets/javascripts/syntaxhighlighter/shBrushPowerShell.js74
-rw-r--r--railties/guides/assets/javascripts/syntaxhighlighter/shBrushPython.js64
-rw-r--r--railties/guides/assets/javascripts/syntaxhighlighter/shBrushRuby.js55
-rw-r--r--railties/guides/assets/javascripts/syntaxhighlighter/shBrushSass.js94
-rw-r--r--railties/guides/assets/javascripts/syntaxhighlighter/shBrushScala.js51
-rw-r--r--railties/guides/assets/javascripts/syntaxhighlighter/shBrushSql.js66
-rw-r--r--railties/guides/assets/javascripts/syntaxhighlighter/shBrushVb.js56
-rw-r--r--railties/guides/assets/javascripts/syntaxhighlighter/shBrushXml.js69
-rw-r--r--railties/guides/assets/javascripts/syntaxhighlighter/shCore.js17
-rw-r--r--railties/guides/assets/stylesheets/main.css21
-rw-r--r--railties/guides/assets/stylesheets/syntax.css31
-rw-r--r--railties/guides/assets/stylesheets/syntaxhighlighter/shCore.css226
-rw-r--r--railties/guides/assets/stylesheets/syntaxhighlighter/shCoreDefault.css328
-rw-r--r--railties/guides/assets/stylesheets/syntaxhighlighter/shCoreDjango.css331
-rw-r--r--railties/guides/assets/stylesheets/syntaxhighlighter/shCoreEclipse.css339
-rw-r--r--railties/guides/assets/stylesheets/syntaxhighlighter/shCoreEmacs.css324
-rw-r--r--railties/guides/assets/stylesheets/syntaxhighlighter/shCoreFadeToGrey.css328
-rw-r--r--railties/guides/assets/stylesheets/syntaxhighlighter/shCoreMDUltra.css324
-rw-r--r--railties/guides/assets/stylesheets/syntaxhighlighter/shCoreMidnight.css324
-rw-r--r--railties/guides/assets/stylesheets/syntaxhighlighter/shCoreRDark.css324
-rw-r--r--railties/guides/assets/stylesheets/syntaxhighlighter/shThemeDefault.css117
-rw-r--r--railties/guides/assets/stylesheets/syntaxhighlighter/shThemeDjango.css120
-rw-r--r--railties/guides/assets/stylesheets/syntaxhighlighter/shThemeEclipse.css128
-rw-r--r--railties/guides/assets/stylesheets/syntaxhighlighter/shThemeEmacs.css113
-rw-r--r--railties/guides/assets/stylesheets/syntaxhighlighter/shThemeFadeToGrey.css117
-rwxr-xr-xrailties/guides/assets/stylesheets/syntaxhighlighter/shThemeMDUltra.css113
-rw-r--r--railties/guides/assets/stylesheets/syntaxhighlighter/shThemeMidnight.css113
-rw-r--r--railties/guides/assets/stylesheets/syntaxhighlighter/shThemeRDark.css113
-rw-r--r--railties/guides/assets/stylesheets/syntaxhighlighter/shThemeRailsGuides.css116
-rw-r--r--railties/guides/rails_guides/generator.rb24
-rw-r--r--railties/guides/rails_guides/helpers.rb9
-rw-r--r--railties/guides/source/3_0_release_notes.textile4
-rw-r--r--railties/guides/source/action_controller_overview.textile11
-rw-r--r--railties/guides/source/action_mailer_basics.textile8
-rw-r--r--railties/guides/source/action_view_overview.textile4
-rw-r--r--railties/guides/source/active_record_querying.textile64
-rw-r--r--railties/guides/source/active_record_validations_callbacks.textile34
-rw-r--r--railties/guides/source/active_support_core_extensions.textile72
-rw-r--r--railties/guides/source/api_documentation_guidelines.textile16
-rw-r--r--railties/guides/source/association_basics.textile2
-rw-r--r--railties/guides/source/caching_with_rails.textile1
-rw-r--r--railties/guides/source/command_line.textile3
-rw-r--r--railties/guides/source/configuring.textile209
-rw-r--r--railties/guides/source/contribute.textile2
-rw-r--r--railties/guides/source/contributing_to_rails.textile13
-rw-r--r--railties/guides/source/debugging_rails_applications.textile16
-rw-r--r--railties/guides/source/form_helpers.textile48
-rw-r--r--railties/guides/source/generators.textile8
-rw-r--r--railties/guides/source/getting_started.textile13
-rw-r--r--railties/guides/source/i18n.textile79
-rw-r--r--railties/guides/source/index.html.erb14
-rw-r--r--railties/guides/source/initialization.textile12
-rw-r--r--railties/guides/source/layout.html.erb42
-rw-r--r--railties/guides/source/layouts_and_rendering.textile24
-rw-r--r--railties/guides/source/migrations.textile6
-rw-r--r--railties/guides/source/performance_testing.textile2
-rw-r--r--railties/guides/source/plugins.textile20
-rw-r--r--railties/guides/source/rails_application_templates.textile2
-rw-r--r--railties/guides/source/rails_on_rack.textile2
-rw-r--r--railties/guides/source/routing.textile28
-rw-r--r--railties/guides/source/security.textile6
-rw-r--r--railties/guides/source/testing.textile4
-rw-r--r--railties/lib/rails/application.rb3
-rw-r--r--railties/lib/rails/backtrace_cleaner.rb2
-rw-r--r--railties/lib/rails/cli.rb10
-rw-r--r--railties/lib/rails/commands.rb17
-rw-r--r--railties/lib/rails/commands/plugin_new.rb10
-rw-r--r--railties/lib/rails/configuration.rb8
-rw-r--r--railties/lib/rails/engine.rb61
-rw-r--r--railties/lib/rails/engine/configuration.rb1
-rw-r--r--railties/lib/rails/generators.rb2
-rw-r--r--railties/lib/rails/generators/app_base.rb176
-rw-r--r--railties/lib/rails/generators/named_base.rb39
-rw-r--r--railties/lib/rails/generators/rails/app/app_generator.rb157
-rw-r--r--railties/lib/rails/generators/rails/app/templates/Gemfile21
-rwxr-xr-x[-rw-r--r--]railties/lib/rails/generators/rails/app/templates/Rakefile2
-rw-r--r--railties/lib/rails/generators/rails/app/templates/config/application.rb8
-rw-r--r--railties/lib/rails/generators/rails/app/templates/public/javascripts/jquery.js7179
-rw-r--r--railties/lib/rails/generators/rails/app/templates/public/javascripts/jquery_ujs.js132
-rw-r--r--railties/lib/rails/generators/rails/app/templates/public/javascripts/prototype.js733
-rw-r--r--railties/lib/rails/generators/rails/app/templates/public/javascripts/prototype_ujs.js (renamed from railties/lib/rails/generators/rails/app/templates/public/javascripts/rails.js)85
-rw-r--r--railties/lib/rails/generators/rails/plugin/plugin_generator.rb7
-rw-r--r--railties/lib/rails/generators/rails/plugin/templates/Rakefile.tt2
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/USAGE10
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb249
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/%name%.gemspec9
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/Gemfile11
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/MIT-LICENSE20
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/README.rdoc3
-rwxr-xr-xrailties/lib/rails/generators/rails/plugin_new/templates/Rakefile16
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/app/controllers/%name%/application_controller.rb.tt4
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/app/helpers/%name%/application_helper.rb.tt4
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/config/routes.rb3
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/gitignore6
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/lib/%name%.rb6
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/lib/%name%/engine.rb7
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/lib/tasks/%name%_tasks.rake4
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/rails/application.rb16
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/rails/boot.rb10
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/rails/routes.rb4
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/script/rails.tt5
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/test/%name%_test.rb7
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/test/integration/navigation_test.rb11
-rw-r--r--railties/lib/rails/generators/rails/plugin_new/templates/test/test_helper.rb15
-rw-r--r--railties/lib/rails/generators/rails/resource/resource_generator.rb4
-rw-r--r--railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb2
-rw-r--r--railties/lib/rails/generators/resource_helpers.rb6
-rw-r--r--railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb2
-rw-r--r--railties/lib/rails/info.rb1
-rw-r--r--railties/lib/rails/rack/log_tailer.rb2
-rw-r--r--railties/lib/rails/railtie.rb4
-rw-r--r--railties/lib/rails/tasks/framework.rake2
-rw-r--r--railties/lib/rails/tasks/railties.rake33
-rw-r--r--railties/lib/rails/test_help.rb11
-rw-r--r--railties/lib/rails/version.rb4
-rw-r--r--railties/railties.gemspec2
-rw-r--r--railties/test/application/generators_test.rb5
-rw-r--r--railties/test/application/initializers/frameworks_test.rb60
-rw-r--r--railties/test/application/rake_test.rb25
-rw-r--r--railties/test/fixtures/lib/app_builders/empty_builder.rb (renamed from railties/test/fixtures/lib/empty_builder.rb)0
-rw-r--r--railties/test/fixtures/lib/app_builders/simple_builder.rb7
-rw-r--r--railties/test/fixtures/lib/app_builders/tweak_builder.rb7
-rw-r--r--railties/test/fixtures/lib/create_test_dummy_template.rb1
-rw-r--r--railties/test/fixtures/lib/plugin_builders/empty_builder.rb2
-rw-r--r--railties/test/fixtures/lib/plugin_builders/simple_builder.rb7
-rw-r--r--railties/test/fixtures/lib/plugin_builders/spec_builder.rb19
-rw-r--r--railties/test/fixtures/lib/plugin_builders/tweak_builder.rb7
-rw-r--r--railties/test/fixtures/lib/simple_builder.rb7
-rw-r--r--railties/test/fixtures/lib/tweak_builder.rb7
-rw-r--r--railties/test/generators/app_generator_test.rb173
-rw-r--r--railties/test/generators/migration_generator_test.rb12
-rw-r--r--railties/test/generators/model_generator_test.rb6
-rw-r--r--railties/test/generators/namespaced_generators_test.rb153
-rw-r--r--railties/test/generators/plugin_generator_test.rb18
-rw-r--r--railties/test/generators/plugin_new_generator_test.rb196
-rw-r--r--railties/test/generators/resource_generator_test.rb5
-rw-r--r--railties/test/generators/shared_generator_tests.rb187
-rw-r--r--railties/test/generators_test.rb6
-rw-r--r--railties/test/railties/engine_test.rb132
-rw-r--r--railties/test/railties/shared_tests.rb48
161 files changed, 15375 insertions, 1577 deletions
diff --git a/railties/CHANGELOG b/railties/CHANGELOG
index b38a9ce750..75f1df44e7 100644
--- a/railties/CHANGELOG
+++ b/railties/CHANGELOG
@@ -1,5 +1,9 @@
*Rails 3.1.0 (unreleased)*
+* Added `rails plugin new` command which generates rails plugin with gemspec, tests and dummy application for testing [Piotr Sarnacki]
+
+* Added -j parameter with jquery/prototype as options. Now you can create your apps with jQuery using `rails new myapp -j jquery`. The default is still Prototype. [siong1987]
+
* Added Rack::Etag and Rack::ConditionalGet to the default middleware stack [José Valim]
* Added Rack::Cache to the default middleware stack [Yehuda Katz and Carl Lerche]
@@ -18,10 +22,14 @@
* Changed ActionDispatch::Static to allow handling multiple directories [Piotr Sarnacki]
-* Added namespace() method to Engine, which sets Engine as isolated [Piotr Sarnacki]
+* Added isolate_namespace() method to Engine, which sets Engine as isolated [Piotr Sarnacki]
* Include all helpers from plugins and shared engines in application [Piotr Sarnacki]
+*Rails 3.0.1 (October 15, 2010)*
+
+* No Changes, just a version bump.
+
*Rails 3.0.0 (August 29, 2010)*
* Application generation: --skip-testunit and --skip-activerecord become --skip-test-unit and --skip-active-record respectively. [fxn]
diff --git a/railties/Rakefile b/railties/Rakefile
index 9ef6637c1e..5137bee761 100644..100755
--- a/railties/Rakefile
+++ b/railties/Rakefile
@@ -1,4 +1,4 @@
-require 'rake'
+#!/usr/bin/env rake
require 'rake/testtask'
require 'rake/gempackagetask'
@@ -45,8 +45,9 @@ task :generate_guides do
ruby "guides/rails_guides.rb"
end
-task :update_prototype_ujs do
- system "curl http://github.com/rails/prototype-ujs/raw/master/src/rails.js > lib/rails/generators/rails/app/templates/public/javascripts/rails.js"
+task :update_ujs do
+ system "curl http://github.com/rails/prototype-ujs/raw/master/src/rails.js > lib/rails/generators/rails/app/templates/public/javascripts/prototype_ujs.js"
+ system "curl http://github.com/rails/jquery-ujs/raw/master/src/rails.js > lib/rails/generators/rails/app/templates/public/javascripts/jquery_ujs.js"
end
# Validate guides -------------------------------------------------------------------------
diff --git a/railties/guides/assets/javascripts/code_highlighter.js b/railties/guides/assets/javascripts/code_highlighter.js
deleted file mode 100644
index ce983dad52..0000000000
--- a/railties/guides/assets/javascripts/code_highlighter.js
+++ /dev/null
@@ -1,188 +0,0 @@
-/* Unobtrustive Code Highlighter By Dan Webb 11/2005
- Version: 0.4
-
- Usage:
- Add a script tag for this script and any stylesets you need to use
- to the page in question, add correct class names to CODE elements,
- define CSS styles for elements. That's it!
-
- Known to work on:
- IE 5.5+ PC
- Firefox/Mozilla PC/Mac
- Opera 7.23 + PC
- Safari 2
-
- Known to degrade gracefully on:
- IE5.0 PC
-
- Note: IE5.0 fails due to the use of lookahead in some stylesets. To avoid script errors
- in older browsers use expressions that use lookahead in string format when defining stylesets.
-
- This script is inspired by star-light by entirely cunning Dean Edwards
- http://dean.edwards.name/star-light/.
-*/
-
-// replace callback support for safari.
-if ("a".replace(/a/, function() {return "b"}) != "b") (function(){
- var default_replace = String.prototype.replace;
- String.prototype.replace = function(search,replace){
- // replace is not function
- if(typeof replace != "function"){
- return default_replace.apply(this,arguments)
- }
- var str = "" + this;
- var callback = replace;
- // search string is not RegExp
- if(!(search instanceof RegExp)){
- var idx = str.indexOf(search);
- return (
- idx == -1 ? str :
- default_replace.apply(str,[search,callback(search, idx, str)])
- )
- }
- var reg = search;
- var result = [];
- var lastidx = reg.lastIndex;
- var re;
- while((re = reg.exec(str)) != null){
- var idx = re.index;
- var args = re.concat(idx, str);
- result.push(
- str.slice(lastidx,idx),
- callback.apply(null,args).toString()
- );
- if(!reg.global){
- lastidx += RegExp.lastMatch.length;
- break
- }else{
- lastidx = reg.lastIndex;
- }
- }
- result.push(str.slice(lastidx));
- return result.join("")
- }
-})();
-
-var CodeHighlighter = { styleSets : new Array };
-
-CodeHighlighter.addStyle = function(name, rules) {
- // using push test to disallow older browsers from adding styleSets
- if ([].push) this.styleSets.push({
- name : name,
- rules : rules,
- ignoreCase : arguments[2] || false
- })
-
- function setEvent() {
- // set highlighter to run on load (use LowPro if present)
- if (typeof Event != 'undefined' && typeof Event.onReady == 'function')
- return Event.onReady(CodeHighlighter.init.bind(CodeHighlighter));
-
- var old = window.onload;
-
- if (typeof window.onload != 'function') {
- window.onload = function() { CodeHighlighter.init() };
- } else {
- window.onload = function() {
- old();
- CodeHighlighter.init();
- }
- }
- }
-
- // only set the event when the first style is added
- if (this.styleSets.length==1) setEvent();
-}
-
-CodeHighlighter.init = function() {
- if (!document.getElementsByTagName) return;
- if ("a".replace(/a/, function() {return "b"}) != "b") return; // throw out Safari versions that don't support replace function
- // throw out older browsers
-
- var codeEls = document.getElementsByTagName("CODE");
- // collect array of all pre elements
- codeEls.filter = function(f) {
- var a = new Array;
- for (var i = 0; i < this.length; i++) if (f(this[i])) a[a.length] = this[i];
- return a;
- }
-
- var rules = new Array;
- rules.toString = function() {
- // joins regexes into one big parallel regex
- var exps = new Array;
- for (var i = 0; i < this.length; i++) exps.push(this[i].exp);
- return exps.join("|");
- }
-
- function addRule(className, rule) {
- // add a replace rule
- var exp = (typeof rule.exp != "string")?String(rule.exp).substr(1, String(rule.exp).length-2):rule.exp;
- // converts regex rules to strings and chops of the slashes
- rules.push({
- className : className,
- exp : "(" + exp + ")",
- length : (exp.match(/(^|[^\\])\([^?]/g) || "").length + 1, // number of subexps in rule
- replacement : rule.replacement || null
- });
- }
-
- function parse(text, ignoreCase) {
- // main text parsing and replacement
- return text.replace(new RegExp(rules, (ignoreCase)?"gi":"g"), function() {
- var i = 0, j = 1, rule;
- while (rule = rules[i++]) {
- if (arguments[j]) {
- // if no custom replacement defined do the simple replacement
- if (!rule.replacement) return "<span class=\"" + rule.className + "\">" + arguments[0] + "</span>";
- else {
- // replace $0 with the className then do normal replaces
- var str = rule.replacement.replace("$0", rule.className);
- for (var k = 1; k <= rule.length - 1; k++) str = str.replace("$" + k, arguments[j + k]);
- return str;
- }
- } else j+= rule.length;
- }
- });
- }
-
- function highlightCode(styleSet) {
- // clear rules array
- var parsed, clsRx = new RegExp("(\\s|^)" + styleSet.name + "(\\s|$)");
- rules.length = 0;
-
- // get stylable elements by filtering out all code elements without the correct className
- var stylableEls = codeEls.filter(function(item) { return clsRx.test(item.className) });
-
- // add style rules to parser
- for (var className in styleSet.rules) addRule(className, styleSet.rules[className]);
-
-
- // replace for all elements
- for (var i = 0; i < stylableEls.length; i++) {
- // EVIL hack to fix IE whitespace badness if it's inside a <pre>
- if (/MSIE/.test(navigator.appVersion) && stylableEls[i].parentNode.nodeName == 'PRE') {
- stylableEls[i] = stylableEls[i].parentNode;
-
- parsed = stylableEls[i].innerHTML.replace(/(<code[^>]*>)([^<]*)<\/code>/i, function() {
- return arguments[1] + parse(arguments[2], styleSet.ignoreCase) + "</code>"
- });
- parsed = parsed.replace(/\n( *)/g, function() {
- var spaces = "";
- for (var i = 0; i < arguments[1].length; i++) spaces+= "&nbsp;";
- return "\n" + spaces;
- });
- parsed = parsed.replace(/\t/g, "&nbsp;&nbsp;&nbsp;&nbsp;");
- parsed = parsed.replace(/\n(<\/\w+>)?/g, "<br />$1").replace(/<br \/>[\n\r\s]*<br \/>/g, "<p><br></p>");
-
- } else parsed = parse(stylableEls[i].innerHTML, styleSet.ignoreCase);
-
- stylableEls[i].innerHTML = parsed;
- }
- }
-
- // run highlighter on all stylesets
- for (var i=0; i < this.styleSets.length; i++) {
- highlightCode(this.styleSets[i]);
- }
-}
diff --git a/railties/guides/assets/javascripts/highlighters.js b/railties/guides/assets/javascripts/highlighters.js
deleted file mode 100644
index 4f5f0779d7..0000000000
--- a/railties/guides/assets/javascripts/highlighters.js
+++ /dev/null
@@ -1,90 +0,0 @@
-CodeHighlighter.addStyle("css", {
- comment : {
- exp : /\/\*[^*]*\*+([^\/][^*]*\*+)*\//
- },
- keywords : {
- exp : /@\w[\w\s]*/
- },
- selectors : {
- exp : "([\\w-:\\[.#][^{};>]*)(?={)"
- },
- properties : {
- exp : "([\\w-]+)(?=\\s*:)"
- },
- units : {
- exp : /([0-9])(em|en|px|%|pt)\b/,
- replacement : "$1<span class=\"$0\">$2</span>"
- },
- urls : {
- exp : /url\([^\)]*\)/
- }
- });
-
-CodeHighlighter.addStyle("ruby",{
- comment : {
- exp : /#[^\n]+/
- },
- brackets : {
- exp : /\(|\)/
- },
- string : {
- exp : /'[^']*'|"[^"]*"/
- },
- keywords : {
- exp : /\b(do|end|self|class|def|if|module|yield|then|else|for|until|unless|while|elsif|case|when|break|retry|redo|rescue|require|raise)\b/
- },
- /* Added by Shelly Fisher (shelly@agileevolved.com) */
- symbol : {
- exp : /([^:])(:[A-Za-z0-9_!?]+)/
- },
- ivar : {
- exp : /\@[A-Za-z0-9_!?]+/
- }
-});
-
-CodeHighlighter.addStyle("html", {
- comment : {
- exp: /&lt;!\s*(--([^-]|[\r\n]|-[^-])*--\s*)&gt;/
- },
- tag : {
- exp: /(&lt;\/?)([a-zA-Z1-9]+\s?)/,
- replacement: "$1<span class=\"$0\">$2</span>"
- },
- string : {
- exp : /'[^']*'|"[^"]*"/
- },
- attribute : {
- exp: /\b([a-zA-Z-:]+)(=)/,
- replacement: "<span class=\"$0\">$1</span>$2"
- },
- doctype : {
- exp: /&lt;!DOCTYPE([^&]|&[^g]|&g[^t])*&gt;/
- }
-});
-
-CodeHighlighter.addStyle("javascript",{
- comment : {
- exp : /(\/\/[^\n]*(\n|$))|(\/\*[^*]*\*+([^\/][^*]*\*+)*\/)/
- },
- brackets : {
- exp : /\(|\)/
- },
- string : {
- exp : /'[^']*'|"[^"]*"/
- },
- keywords : {
- exp : /\b(arguments|break|case|continue|default|delete|do|else|false|for|function|if|in|instanceof|new|null|return|switch|this|true|typeof|var|void|while|with)\b/
- },
- global : {
- exp : /\b(toString|valueOf|window|element|prototype|constructor|document|escape|unescape|parseInt|parseFloat|setTimeout|clearTimeout|setInterval|clearInterval|NaN|isNaN|Infinity)\b/
- }
-});
-
-CodeHighlighter.addStyle("yaml", {
- keyword : {
- exp : /\/\*[^*]*\*+([^\/][^*]*\*+)*\//
- },
- value : {
- exp : /@\w[\w\s]*/
- },
-});
diff --git a/railties/guides/assets/javascripts/syntaxhighlighter/shBrushAS3.js b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushAS3.js
new file mode 100644
index 0000000000..8aa3ed2732
--- /dev/null
+++ b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushAS3.js
@@ -0,0 +1,59 @@
+/**
+ * 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/railties/guides/assets/javascripts/syntaxhighlighter/shBrushAppleScript.js b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushAppleScript.js
new file mode 100644
index 0000000000..d40bbd7dd2
--- /dev/null
+++ b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushAppleScript.js
@@ -0,0 +1,75 @@
+/**
+ * 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/railties/guides/assets/javascripts/syntaxhighlighter/shBrushBash.js b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushBash.js
new file mode 100644
index 0000000000..8c296969ff
--- /dev/null
+++ b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushBash.js
@@ -0,0 +1,59 @@
+/**
+ * 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/railties/guides/assets/javascripts/syntaxhighlighter/shBrushCSharp.js b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushCSharp.js
new file mode 100644
index 0000000000..079214efe1
--- /dev/null
+++ b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushCSharp.js
@@ -0,0 +1,65 @@
+/**
+ * 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/railties/guides/assets/javascripts/syntaxhighlighter/shBrushColdFusion.js b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushColdFusion.js
new file mode 100644
index 0000000000..627dbb9b76
--- /dev/null
+++ b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushColdFusion.js
@@ -0,0 +1,100 @@
+/**
+ * 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/railties/guides/assets/javascripts/syntaxhighlighter/shBrushCpp.js b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushCpp.js
new file mode 100644
index 0000000000..9f70d3aed6
--- /dev/null
+++ b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushCpp.js
@@ -0,0 +1,97 @@
+/**
+ * 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/railties/guides/assets/javascripts/syntaxhighlighter/shBrushCss.js b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushCss.js
new file mode 100644
index 0000000000..4297a9a648
--- /dev/null
+++ b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushCss.js
@@ -0,0 +1,91 @@
+/**
+ * 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/railties/guides/assets/javascripts/syntaxhighlighter/shBrushDelphi.js b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushDelphi.js
new file mode 100644
index 0000000000..e1060d4468
--- /dev/null
+++ b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushDelphi.js
@@ -0,0 +1,55 @@
+/**
+ * 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/railties/guides/assets/javascripts/syntaxhighlighter/shBrushDiff.js b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushDiff.js
new file mode 100644
index 0000000000..e9b14fc580
--- /dev/null
+++ b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushDiff.js
@@ -0,0 +1,41 @@
+/**
+ * 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/railties/guides/assets/javascripts/syntaxhighlighter/shBrushErlang.js b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushErlang.js
new file mode 100644
index 0000000000..6ba7d9da87
--- /dev/null
+++ b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushErlang.js
@@ -0,0 +1,52 @@
+/**
+ * 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/railties/guides/assets/javascripts/syntaxhighlighter/shBrushGroovy.js b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushGroovy.js
new file mode 100644
index 0000000000..6ec5c18521
--- /dev/null
+++ b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushGroovy.js
@@ -0,0 +1,67 @@
+/**
+ * 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/railties/guides/assets/javascripts/syntaxhighlighter/shBrushJScript.js b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushJScript.js
new file mode 100644
index 0000000000..ff98daba16
--- /dev/null
+++ b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushJScript.js
@@ -0,0 +1,52 @@
+/**
+ * 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/railties/guides/assets/javascripts/syntaxhighlighter/shBrushJava.js b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushJava.js
new file mode 100644
index 0000000000..d692fd6382
--- /dev/null
+++ b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushJava.js
@@ -0,0 +1,57 @@
+/**
+ * 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/railties/guides/assets/javascripts/syntaxhighlighter/shBrushJavaFX.js b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushJavaFX.js
new file mode 100644
index 0000000000..1a150a6ad3
--- /dev/null
+++ b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushJavaFX.js
@@ -0,0 +1,58 @@
+/**
+ * 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/railties/guides/assets/javascripts/syntaxhighlighter/shBrushPerl.js b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushPerl.js
new file mode 100644
index 0000000000..d94a2e0ec5
--- /dev/null
+++ b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushPerl.js
@@ -0,0 +1,72 @@
+/**
+ * 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/railties/guides/assets/javascripts/syntaxhighlighter/shBrushPhp.js b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushPhp.js
new file mode 100644
index 0000000000..95e6e4325b
--- /dev/null
+++ b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushPhp.js
@@ -0,0 +1,88 @@
+/**
+ * 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/railties/guides/assets/javascripts/syntaxhighlighter/shBrushPlain.js b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushPlain.js
new file mode 100644
index 0000000000..9f7d9e90c3
--- /dev/null
+++ b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushPlain.js
@@ -0,0 +1,33 @@
+/**
+ * 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/railties/guides/assets/javascripts/syntaxhighlighter/shBrushPowerShell.js b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushPowerShell.js
new file mode 100644
index 0000000000..0be1752968
--- /dev/null
+++ b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushPowerShell.js
@@ -0,0 +1,74 @@
+/**
+ * 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/railties/guides/assets/javascripts/syntaxhighlighter/shBrushPython.js b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushPython.js
new file mode 100644
index 0000000000..ce77462975
--- /dev/null
+++ b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushPython.js
@@ -0,0 +1,64 @@
+/**
+ * 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/railties/guides/assets/javascripts/syntaxhighlighter/shBrushRuby.js b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushRuby.js
new file mode 100644
index 0000000000..ff82130a7a
--- /dev/null
+++ b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushRuby.js
@@ -0,0 +1,55 @@
+/**
+ * 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/railties/guides/assets/javascripts/syntaxhighlighter/shBrushSass.js b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushSass.js
new file mode 100644
index 0000000000..aa04da0996
--- /dev/null
+++ b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushSass.js
@@ -0,0 +1,94 @@
+/**
+ * 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/railties/guides/assets/javascripts/syntaxhighlighter/shBrushScala.js b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushScala.js
new file mode 100644
index 0000000000..4b0b6f04d2
--- /dev/null
+++ b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushScala.js
@@ -0,0 +1,51 @@
+/**
+ * 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/railties/guides/assets/javascripts/syntaxhighlighter/shBrushSql.js b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushSql.js
new file mode 100644
index 0000000000..5c2cd8806f
--- /dev/null
+++ b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushSql.js
@@ -0,0 +1,66 @@
+/**
+ * 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/railties/guides/assets/javascripts/syntaxhighlighter/shBrushVb.js b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushVb.js
new file mode 100644
index 0000000000..be845dc0b3
--- /dev/null
+++ b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushVb.js
@@ -0,0 +1,56 @@
+/**
+ * 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/railties/guides/assets/javascripts/syntaxhighlighter/shBrushXml.js b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushXml.js
new file mode 100644
index 0000000000..69d9fd0b1f
--- /dev/null
+++ b/railties/guides/assets/javascripts/syntaxhighlighter/shBrushXml.js
@@ -0,0 +1,69 @@
+/**
+ * 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/railties/guides/assets/javascripts/syntaxhighlighter/shCore.js b/railties/guides/assets/javascripts/syntaxhighlighter/shCore.js
new file mode 100644
index 0000000000..b47b645472
--- /dev/null
+++ b/railties/guides/assets/javascripts/syntaxhighlighter/shCore.js
@@ -0,0 +1,17 @@
+/**
+ * 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/railties/guides/assets/stylesheets/main.css b/railties/guides/assets/stylesheets/main.css
index 7e6dfbdb51..cf6e9e5cc8 100644
--- a/railties/guides/assets/stylesheets/main.css
+++ b/railties/guides/assets/stylesheets/main.css
@@ -23,8 +23,12 @@ dl { margin: 0 0 1.5em 0; }
dl dt { font-weight: bold; }
dd { margin-left: 1.5em;}
-pre,code { margin: 1.5em 0; white-space: pre; overflow: auto; }
-pre,code,tt { font: 1em 'andale mono', 'lucida console', monospace; line-height: 1.5; }
+pre,code { margin: 1.5em 0; overflow: auto; color: #222;}
+pre,code,tt {
+ font-size: 1em;
+ font-family: "Anonymous Pro", "Inconsolata", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace;
+ line-height: 1.5;
+}
abbr, acronym { border-bottom: 1px dotted #666; }
address { margin: 0 0 1.5em; font-style: italic; }
@@ -329,7 +333,7 @@ h6 {
padding: 0.125em 0 0.25em 28px;*/
}
-#mainCol dd.ticket, #subCol dd.ticket {
+#mainCol dd.work-in-progress, #subCol dd.work-in-progress {
background: #fff9d8 url(../images/tab_yellow.gif) no-repeat left top;
border: none;
padding: 1.25em 1em 1.25em 48px;
@@ -361,22 +365,11 @@ h6 {
font-weight: normal;
}
-tt {
- font-family: monaco, "Bitstream Vera Sans Mono", "Courier New", courier, monospace;
-}
-
div.code_container {
background: #EEE url(../images/tab_grey.gif) no-repeat left top;
padding: 0.25em 1em 0.5em 48px;
}
-code {
- font-family: monaco, "Bitstream Vera Sans Mono", "Courier New", courier, monospace;
- border: none;
- margin: 0.25em 0 1.5em 0;
- display: block;
-}
-
.note {
background: #fff9d8 url(../images/tab_note.gif) no-repeat left top;
border: none;
diff --git a/railties/guides/assets/stylesheets/syntax.css b/railties/guides/assets/stylesheets/syntax.css
deleted file mode 100644
index 55fc5b209f..0000000000
--- a/railties/guides/assets/stylesheets/syntax.css
+++ /dev/null
@@ -1,31 +0,0 @@
-.html .tag {
- color : green;
-}
-
-.html .doctype {
- color: #708090;
-}
-
-.erb .tag {
- color : green;
-}
-
-.erb .doctype {
- color: #708090;
-}
-
-.ruby .keywords {
- color : red;
-}
-
-.ruby .ivar {
- color : blue;
-}
-
-.ruby .comment {
- color: #708090;
-}
-
-.ruby .symbol {
- color: green;
-}
diff --git a/railties/guides/assets/stylesheets/syntaxhighlighter/shCore.css b/railties/guides/assets/stylesheets/syntaxhighlighter/shCore.css
new file mode 100644
index 0000000000..34f6864a15
--- /dev/null
+++ b/railties/guides/assets/stylesheets/syntaxhighlighter/shCore.css
@@ -0,0 +1,226 @@
+/**
+ * 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;
+}
diff --git a/railties/guides/assets/stylesheets/syntaxhighlighter/shCoreDefault.css b/railties/guides/assets/stylesheets/syntaxhighlighter/shCoreDefault.css
new file mode 100644
index 0000000000..08f9e10e4e
--- /dev/null
+++ b/railties/guides/assets/stylesheets/syntaxhighlighter/shCoreDefault.css
@@ -0,0 +1,328 @@
+/**
+ * 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/railties/guides/assets/stylesheets/syntaxhighlighter/shCoreDjango.css b/railties/guides/assets/stylesheets/syntaxhighlighter/shCoreDjango.css
new file mode 100644
index 0000000000..1db1f70cb0
--- /dev/null
+++ b/railties/guides/assets/stylesheets/syntaxhighlighter/shCoreDjango.css
@@ -0,0 +1,331 @@
+/**
+ * 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/railties/guides/assets/stylesheets/syntaxhighlighter/shCoreEclipse.css b/railties/guides/assets/stylesheets/syntaxhighlighter/shCoreEclipse.css
new file mode 100644
index 0000000000..a45de9fd8e
--- /dev/null
+++ b/railties/guides/assets/stylesheets/syntaxhighlighter/shCoreEclipse.css
@@ -0,0 +1,339 @@
+/**
+ * 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/railties/guides/assets/stylesheets/syntaxhighlighter/shCoreEmacs.css b/railties/guides/assets/stylesheets/syntaxhighlighter/shCoreEmacs.css
new file mode 100644
index 0000000000..706c77a0a8
--- /dev/null
+++ b/railties/guides/assets/stylesheets/syntaxhighlighter/shCoreEmacs.css
@@ -0,0 +1,324 @@
+/**
+ * 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/railties/guides/assets/stylesheets/syntaxhighlighter/shCoreFadeToGrey.css b/railties/guides/assets/stylesheets/syntaxhighlighter/shCoreFadeToGrey.css
new file mode 100644
index 0000000000..6101eba51f
--- /dev/null
+++ b/railties/guides/assets/stylesheets/syntaxhighlighter/shCoreFadeToGrey.css
@@ -0,0 +1,328 @@
+/**
+ * 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/railties/guides/assets/stylesheets/syntaxhighlighter/shCoreMDUltra.css b/railties/guides/assets/stylesheets/syntaxhighlighter/shCoreMDUltra.css
new file mode 100644
index 0000000000..2923ce7367
--- /dev/null
+++ b/railties/guides/assets/stylesheets/syntaxhighlighter/shCoreMDUltra.css
@@ -0,0 +1,324 @@
+/**
+ * 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/railties/guides/assets/stylesheets/syntaxhighlighter/shCoreMidnight.css b/railties/guides/assets/stylesheets/syntaxhighlighter/shCoreMidnight.css
new file mode 100644
index 0000000000..e3733eed56
--- /dev/null
+++ b/railties/guides/assets/stylesheets/syntaxhighlighter/shCoreMidnight.css
@@ -0,0 +1,324 @@
+/**
+ * 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/railties/guides/assets/stylesheets/syntaxhighlighter/shCoreRDark.css b/railties/guides/assets/stylesheets/syntaxhighlighter/shCoreRDark.css
new file mode 100644
index 0000000000..d09368384d
--- /dev/null
+++ b/railties/guides/assets/stylesheets/syntaxhighlighter/shCoreRDark.css
@@ -0,0 +1,324 @@
+/**
+ * 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/railties/guides/assets/stylesheets/syntaxhighlighter/shThemeDefault.css b/railties/guides/assets/stylesheets/syntaxhighlighter/shThemeDefault.css
new file mode 100644
index 0000000000..136541172d
--- /dev/null
+++ b/railties/guides/assets/stylesheets/syntaxhighlighter/shThemeDefault.css
@@ -0,0 +1,117 @@
+/**
+ * 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/railties/guides/assets/stylesheets/syntaxhighlighter/shThemeDjango.css b/railties/guides/assets/stylesheets/syntaxhighlighter/shThemeDjango.css
new file mode 100644
index 0000000000..d8b4313433
--- /dev/null
+++ b/railties/guides/assets/stylesheets/syntaxhighlighter/shThemeDjango.css
@@ -0,0 +1,120 @@
+/**
+ * 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/railties/guides/assets/stylesheets/syntaxhighlighter/shThemeEclipse.css b/railties/guides/assets/stylesheets/syntaxhighlighter/shThemeEclipse.css
new file mode 100644
index 0000000000..77377d9533
--- /dev/null
+++ b/railties/guides/assets/stylesheets/syntaxhighlighter/shThemeEclipse.css
@@ -0,0 +1,128 @@
+/**
+ * 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/railties/guides/assets/stylesheets/syntaxhighlighter/shThemeEmacs.css b/railties/guides/assets/stylesheets/syntaxhighlighter/shThemeEmacs.css
new file mode 100644
index 0000000000..dae5053fea
--- /dev/null
+++ b/railties/guides/assets/stylesheets/syntaxhighlighter/shThemeEmacs.css
@@ -0,0 +1,113 @@
+/**
+ * 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/railties/guides/assets/stylesheets/syntaxhighlighter/shThemeFadeToGrey.css b/railties/guides/assets/stylesheets/syntaxhighlighter/shThemeFadeToGrey.css
new file mode 100644
index 0000000000..8fbd871fb5
--- /dev/null
+++ b/railties/guides/assets/stylesheets/syntaxhighlighter/shThemeFadeToGrey.css
@@ -0,0 +1,117 @@
+/**
+ * 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/railties/guides/assets/stylesheets/syntaxhighlighter/shThemeMDUltra.css b/railties/guides/assets/stylesheets/syntaxhighlighter/shThemeMDUltra.css
new file mode 100755
index 0000000000..f4db39cd83
--- /dev/null
+++ b/railties/guides/assets/stylesheets/syntaxhighlighter/shThemeMDUltra.css
@@ -0,0 +1,113 @@
+/**
+ * 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/railties/guides/assets/stylesheets/syntaxhighlighter/shThemeMidnight.css b/railties/guides/assets/stylesheets/syntaxhighlighter/shThemeMidnight.css
new file mode 100644
index 0000000000..c49563cc9d
--- /dev/null
+++ b/railties/guides/assets/stylesheets/syntaxhighlighter/shThemeMidnight.css
@@ -0,0 +1,113 @@
+/**
+ * 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/railties/guides/assets/stylesheets/syntaxhighlighter/shThemeRDark.css b/railties/guides/assets/stylesheets/syntaxhighlighter/shThemeRDark.css
new file mode 100644
index 0000000000..6305a10e4e
--- /dev/null
+++ b/railties/guides/assets/stylesheets/syntaxhighlighter/shThemeRDark.css
@@ -0,0 +1,113 @@
+/**
+ * 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/railties/guides/assets/stylesheets/syntaxhighlighter/shThemeRailsGuides.css b/railties/guides/assets/stylesheets/syntaxhighlighter/shThemeRailsGuides.css
new file mode 100644
index 0000000000..6d2edb2eb8
--- /dev/null
+++ b/railties/guides/assets/stylesheets/syntaxhighlighter/shThemeRailsGuides.css
@@ -0,0 +1,116 @@
+/**
+ * Theme by fxn, took shThemeEclipse.css as starting point.
+ */
+.syntaxhighlighter {
+ background-color: #eee !important;
+ font-family: "Anonymous Pro", "Inconsolata", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace !important;
+ overflow-y: hidden !important;
+ overflow-x: auto !important;
+}
+.syntaxhighlighter .line.alt1 {
+ background-color: #eee !important;
+}
+.syntaxhighlighter .line.alt2 {
+ background-color: #eee !important;
+}
+.syntaxhighlighter .line.highlighted.alt1, .syntaxhighlighter .line.highlighted.alt2 {
+ background-color: #c3defe !important;
+}
+.syntaxhighlighter .line.highlighted.number {
+ color: #eee !important;
+}
+.syntaxhighlighter table caption {
+ color: #222 !important;
+}
+.syntaxhighlighter .gutter {
+ color: #787878 !important;
+}
+.syntaxhighlighter .gutter .line {
+ border-right: 3px solid #d4d0c8 !important;
+}
+.syntaxhighlighter .gutter .line.highlighted {
+ background-color: #d4d0c8 !important;
+ color: #eee !important;
+}
+.syntaxhighlighter.printing .line .content {
+ border: none !important;
+}
+.syntaxhighlighter.collapsed {
+ overflow: visible !important;
+}
+.syntaxhighlighter.collapsed .toolbar {
+ color: #3f5fbf !important;
+ background: #eee !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: #222 !important;
+}
+.syntaxhighlighter .comments, .syntaxhighlighter .comments a {
+ color: #708090 !important;
+}
+.syntaxhighlighter .string, .syntaxhighlighter .string a {
+ font-style: italic !important;
+ color: #6588A8 !important;
+}
+.syntaxhighlighter .keyword {
+ color: #64434d !important;
+}
+.syntaxhighlighter .preprocessor {
+ color: #646464 !important;
+}
+.syntaxhighlighter .variable {
+ color: #222 !important;
+}
+.syntaxhighlighter .value {
+ color: #009900 !important;
+}
+.syntaxhighlighter .functions {
+ color: #ff1493 !important;
+}
+.syntaxhighlighter .constants {
+ color: #0066cc !important;
+}
+.syntaxhighlighter .script {
+ color: #222 !important;
+ background-color: none !important;
+}
+.syntaxhighlighter .color1, .syntaxhighlighter .color1 a {
+ color: gray !important;
+}
+.syntaxhighlighter .color2, .syntaxhighlighter .color2 a {
+ color: #222 !important;
+ font-weight: bold !important;
+}
+.syntaxhighlighter .color3, .syntaxhighlighter .color3 a {
+ color: red !important;
+}
+
+.syntaxhighlighter .xml .keyword {
+ color: #64434d !important;
+ font-weight: normal !important;
+}
+.syntaxhighlighter .xml .color1, .syntaxhighlighter .xml .color1 a {
+ color: #7f007f !important;
+}
+.syntaxhighlighter .xml .string {
+ font-style: italic !important;
+ color: #6588A8 !important;
+}
diff --git a/railties/guides/rails_guides/generator.rb b/railties/guides/rails_guides/generator.rb
index eaa9d79ce8..0a2170a09e 100644
--- a/railties/guides/rails_guides/generator.rb
+++ b/railties/guides/rails_guides/generator.rb
@@ -207,10 +207,28 @@ module RailsGuides
# with code blocks by hand.
def with_workaround_for_notextile(body)
code_blocks = []
+
body.gsub!(%r{<(yaml|shell|ruby|erb|html|sql|plain)>(.*?)</\1>}m) do |m|
- es = ERB::Util.h($2)
- css_class = ['erb', 'shell'].include?($1) ? 'html' : $1
- code_blocks << %{<div class="code_container"><code class="#{css_class}">#{es}</code></div>}
+ brush = case $1
+ when 'ruby', 'sql', 'plain'
+ $1
+ when 'erb'
+ 'ruby; html-script: true'
+ when 'html'
+ 'xml' # html is understood, but there are .xml rules in the CSS
+ else
+ 'plain'
+ end
+
+ code_blocks.push(<<HTML)
+<notextile>
+<div class="code_container">
+<pre class="brush: #{brush}; gutter: false; toolbar: false">
+#{ERB::Util.h($2).strip}
+</pre>
+</div>
+</notextile>
+HTML
"\ndirty_workaround_for_notextile_#{code_blocks.size - 1}\n"
end
diff --git a/railties/guides/rails_guides/helpers.rb b/railties/guides/rails_guides/helpers.rb
index bf99538696..d466c76c7c 100644
--- a/railties/guides/rails_guides/helpers.rb
+++ b/railties/guides/rails_guides/helpers.rb
@@ -4,19 +4,14 @@ module RailsGuides
link = content_tag(:a, :href => url) { name }
result = content_tag(:dt, link)
- if ticket = options[:ticket]
- result << content_tag(:dd, lh(ticket), :class => 'ticket')
+ if options[:work_in_progress]
+ result << content_tag(:dd, 'Work in progress', :class => 'work-in-progress')
end
result << content_tag(:dd, capture(&block))
result
end
- def lh(id, label = "Lighthouse Ticket")
- url = "http://rails.lighthouseapp.com/projects/16213/tickets/#{id}"
- content_tag(:a, label, :href => url)
- end
-
def author(name, nick, image = 'credits_pic_blank.gif', &block)
image = "images/#{image}"
diff --git a/railties/guides/source/3_0_release_notes.textile b/railties/guides/source/3_0_release_notes.textile
index 9c08c9fa0a..adb1c755df 100644
--- a/railties/guides/source/3_0_release_notes.textile
+++ b/railties/guides/source/3_0_release_notes.textile
@@ -271,10 +271,10 @@ end
<ruby>
scope 'es' do
- resources :projects, :path_names => { :edit => 'cambiar' }, :path => 'projeto'
+ resources :projects, :path_names => { :edit => 'cambiar' }, :path => 'proyecto'
end
-# Gives you the edit action with /es/projeto/1/cambiar
+# Gives you the edit action with /es/proyecto/1/cambiar
</ruby>
* Added +root+ method to the router as a short cut for <tt>match '/', :to => path</tt>.
diff --git a/railties/guides/source/action_controller_overview.textile b/railties/guides/source/action_controller_overview.textile
index c02e9f1912..0d6c66f168 100644
--- a/railties/guides/source/action_controller_overview.textile
+++ b/railties/guides/source/action_controller_overview.textile
@@ -239,7 +239,7 @@ class LoginsController < ApplicationController
# "Delete" a login, aka "log the user out"
def destroy
# Remove the user id from the session
- session[:current_user_id] = nil
+ @_current_user = session[:current_user_id] = nil
redirect_to root_url
end
end
@@ -261,6 +261,13 @@ class LoginsController < ApplicationController
end
</ruby>
+Note it is also possible to assign a flash message as part of the redirection.
+
+<ruby>
+redirect_to root_url, :notice => "You have successfully logged out"
+</ruby>
+
+
The +destroy+ action redirects to the application's +root_url+, where the message will be displayed. Note that it's entirely up to the next action to decide what, if anything, it will do with what the previous action put in the flash. It's conventional to display eventual errors or notices from the flash in the application's layout:
<ruby>
@@ -807,8 +814,6 @@ NOTE: Certain exceptions are only rescuable from the +ApplicationController+ cla
h3. Changelog
-"Lighthouse Ticket":http://rails.lighthouseapp.com/projects/16213-rails-guides/tickets/17
-
* February 17, 2009: Yet another proofread by Xavier Noria.
* November 4, 2008: First release version by Tore Darell
diff --git a/railties/guides/source/action_mailer_basics.textile b/railties/guides/source/action_mailer_basics.textile
index 34afebcae4..b75c528a33 100644
--- a/railties/guides/source/action_mailer_basics.textile
+++ b/railties/guides/source/action_mailer_basics.textile
@@ -445,8 +445,8 @@ The following configuration options are best made in one of the environment file
|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, :login, :cram_md5.</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.|
-|delivery_method|Defines a delivery method. Possible values are :smtp (default), :sendmail, and :test.|
-|perform_deliveries|Determines whether deliver_* methods are actually carried out. By default they are, but this can be turned off to help functional testing.|
+|delivery_method|Defines a delivery method. Possible values are :smtp (default), :sendmail, :file and :test.|
+|perform_deliveries|Determines whether deliveries are actually carried out when the +deliver+ method is invoked on the Mail message. By default they are, but this can be turned off to help functional testing.|
|deliveries|Keeps an array of all the emails sent out through the Action Mailer with delivery_method :test. Most useful for unit and functional testing.|
h4. Example Action Mailer Configuration
@@ -492,7 +492,7 @@ class UserMailerTest < ActionMailer::TestCase
user = users(:some_user_in_your_fixtures)
# Send the email, then test that it got queued
- email = UserMailer.deliver_welcome_email(user)
+ email = UserMailer.welcome_email(user).deliver
assert !ActionMailer::Base.deliveries.empty?
# Test the body of the sent email contains what we expect it to
@@ -508,6 +508,4 @@ In the test we send the email and store the returned object in the +email+ varia
h3. Changelog
-"Lighthouse ticket":http://rails.lighthouseapp.com/projects/16213/tickets/25
-
* September 30, 2010: Fixed typos and reformatted Action Mailer configuration table for better understanding. "Jaime Iniesta":http://jaimeiniesta.com
diff --git a/railties/guides/source/action_view_overview.textile b/railties/guides/source/action_view_overview.textile
index 0e1a352ebd..051baa660c 100644
--- a/railties/guides/source/action_view_overview.textile
+++ b/railties/guides/source/action_view_overview.textile
@@ -233,7 +233,7 @@ h4. AssetTagHelper
This module provides methods for generating HTML that links views to assets such as images, javascripts, stylesheets, and feeds.
-By default, Rails links to these assets on the current host in the public folder, but you can direct Rails to link to assets from a dedicated assets server by setting +ActionController::Base.asset_host+ in your +config/environment.rb+. For example, let's say your asset host is +assets.example.com+:
+By default, Rails links to these assets on the current host in the public folder, but you can direct Rails to link to assets from a dedicated assets server by setting +ActionController::Base.asset_host+ in the application configuration, typically in +config/environments/production.rb+. For example, let's say your asset host is +assets.example.com+:
<ruby>
ActionController::Base.asset_host = "assets.example.com"
@@ -1472,7 +1472,5 @@ You can read more about the Rails Internationalization (I18n) API "here":i18n.ht
h3. Changelog
-"Lighthouse Ticket":http://rails.lighthouseapp.com/projects/16213-rails-guides/tickets/71
-
* September 3, 2009: Continuing work by Trevor Turk, leveraging the "Action Pack docs":http://ap.rubyonrails.org/ and "What's new in Edge Rails":http://ryandaigle.com/articles/2007/8/3/what-s-new-in-edge-rails-partials-get-layouts
* April 5, 2009: Starting work by Trevor Turk, leveraging Mike Gunderloy's docs
diff --git a/railties/guides/source/active_record_querying.textile b/railties/guides/source/active_record_querying.textile
index 6837c8b11a..e41b5fb606 100644
--- a/railties/guides/source/active_record_querying.textile
+++ b/railties/guides/source/active_record_querying.textile
@@ -65,6 +65,7 @@ The methods are:
* +lock+
* +readonly+
* +from+
+* +having+
All of the above methods return an instance of <tt>ActiveRecord::Relation</tt>.
@@ -103,7 +104,7 @@ h5. +first+
<ruby>
client = Client.first
-=> #<Client id: 1, first_name: => "Lifo">
+=> #<Client id: 1, first_name: "Lifo">
</ruby>
SQL equivalent of the above is:
@@ -120,7 +121,7 @@ h5. +last+
<ruby>
client = Client.last
-=> #<Client id: 221, first_name: => "Russel">
+=> #<Client id: 221, first_name: "Russel">
</ruby>
SQL equivalent of the above is:
@@ -231,7 +232,7 @@ WARNING: Building your own conditions as pure strings can leave you vulnerable t
h4. Array Conditions
-Now what if that number could vary, say as an argument from somewhere, or perhaps from the user's level status somewhere? The find then becomes something like:
+Now what if that number could vary, say as an argument from somewhere? The find then becomes something like:
<ruby>
Client.where("orders_count = ?", params[:orders])
@@ -279,62 +280,15 @@ h5(#array-range_conditions). Range Conditions
If you're looking for a range inside of a table (for example, users created in a certain timeframe) you can use the conditions option coupled with the +IN+ SQL statement for this. If you had two dates coming in from a controller you could do something like this to look for a range:
<ruby>
-Client.where("created_at IN (?)",
- (params[:start_date].to_date)..(params[:end_date].to_date))
+Client.where(:created_at => (params[:start_date].to_date)..(params[:end_date].to_date))
</ruby>
-This would generate the proper query which is great for small ranges but not so good for larger ranges. For example if you pass in a range of date objects spanning a year that's 365 (or possibly 366, depending on the year) strings it will attempt to match your field against.
+This query will generate something similar to the following SQL:
<sql>
-SELECT * FROM users WHERE (created_at IN
- ('2007-12-31','2008-01-01','2008-01-02','2008-01-03','2008-01-04','2008-01-05',
- '2008-01-06','2008-01-07','2008-01-08','2008-01-09','2008-01-10','2008-01-11',
- '2008-01-12','2008-01-13','2008-01-14','2008-01-15','2008-01-16','2008-01-17',
- '2008-01-18','2008-01-19','2008-01-20','2008-01-21','2008-01-22','2008-01-23',...
- ‘2008-12-15','2008-12-16','2008-12-17','2008-12-18','2008-12-19','2008-12-20',
- '2008-12-21','2008-12-22','2008-12-23','2008-12-24','2008-12-25','2008-12-26',
- '2008-12-27','2008-12-28','2008-12-29','2008-12-30','2008-12-31'))
+ SELECT "clients".* FROM "clients" WHERE ("clients"."created_at" BETWEEN '2010-09-29' AND '2010-11-30')
</sql>
-h5. Time and Date Conditions
-
-Things can get *really* messy if you pass in Time objects as it will attempt to compare your field to *every second* in that range:
-
-<ruby>
-Client.where("created_at IN (?)",
- (params[:start_date].to_date.to_time)..(params[:end_date].to_date.to_time))
-</ruby>
-
-<sql>
-SELECT * FROM users WHERE (created_at IN
- ('2007-12-01 00:00:00', '2007-12-01 00:00:01' ...
- '2007-12-01 23:59:59', '2007-12-02 00:00:00'))
-</sql>
-
-This could possibly cause your database server to raise an unexpected error, for example MySQL will throw back this error:
-
-<shell>
-Got a packet bigger than 'max_allowed_packet' bytes: _query_
-</shell>
-
-Where _query_ is the actual query used to get that error.
-
-In this example it would be better to use greater-than and less-than operators in SQL, like so:
-
-<ruby>
-Client.where(
- "created_at > ? AND created_at < ?", params[:start_date], params[:end_date])
-</ruby>
-
-You can also use the greater-than-or-equal-to and less-than-or-equal-to like this:
-
-<ruby>
-Client.where(
- "created_at >= ? AND created_at <= ?", params[:start_date], params[:end_date])
-</ruby>
-
-Just like in Ruby. If you want a shorter syntax be sure to check out the "Hash Conditions":#hash-conditions section later on in the guide.
-
h4. Hash Conditions
Active Record also allows you to pass in hash conditions which can increase the readability of your conditions syntax. With hash conditions, you pass in a hash with keys of the fields you want conditionalised and the values of how you want to conditionalise them:
@@ -385,7 +339,7 @@ SELECT * FROM clients WHERE (clients.orders_count IN (1,3,5))
h4. Ordering
-To retrieve records from the database in a specific order, you can specify the +:order+ option to the +find+ call.
+To retrieve records from the database in a specific order, you can use the +order+ method.
For example, if you're getting a set of records and want to order them in ascending order by the +created_at+ field in your table:
@@ -928,8 +882,6 @@ For options, please see the parent section, "Calculations":#calculations.
h3. Changelog
-"Lighthouse ticket":http://rails.lighthouseapp.com/projects/16213-rails-guides/tickets/16
-
* April 7, 2010: Fixed document to validate XHTML 1.0 Strict. "Jaime Iniesta":http://jaimeiniesta.com
* February 3, 2010: Update to Rails 3 by "James Miller":credits.html#bensie
* February 7, 2009: Second version by "Pratik":credits.html#lifo
diff --git a/railties/guides/source/active_record_validations_callbacks.textile b/railties/guides/source/active_record_validations_callbacks.textile
index a8ccfc7e40..0824ba450c 100644
--- a/railties/guides/source/active_record_validations_callbacks.textile
+++ b/railties/guides/source/active_record_validations_callbacks.textile
@@ -96,7 +96,7 @@ To verify whether or not an object is valid, Rails uses the +valid?+ method. You
<ruby>
class Person < ActiveRecord::Base
- validates_presence_of :name
+ validates :name, :presence => true
end
Person.create(:name => "John Doe").valid? # => true
@@ -109,7 +109,7 @@ Note that an object instantiated with +new+ will not report errors even if it's
<ruby>
class Person < ActiveRecord::Base
- validates_presence_of :name
+ validates :name, :presence => true
end
>> p = Person.new
@@ -141,13 +141,13 @@ end
h4(#validations_overview-errors). +errors[]+
-To verify whether or not a particular attribute of an object is valid, you can use +errors[:attribute]+ that returns an array with all attribute errors, when there are no errors on the specified attribute, an empty array is returned.
+To verify whether or not a particular attribute of an object is valid, you can use +errors[:attribute]+. It returns an array of all the errors for +:attribute+. If there are no errors on the specified attribute, an empty array is returned.
This method is only useful _after_ validations have been run, because it only inspects the errors collection and does not trigger validations itself. It's different from the +ActiveRecord::Base#invalid?+ method explained above because it doesn't verify the validity of the object as a whole. It only checks to see whether there are errors found on an individual attribute of the object.
<ruby>
class Person < ActiveRecord::Base
- validates_presence_of :name
+ validates :name, :presence => true
end
>> Person.new.errors[:name].any? # => false
@@ -235,7 +235,7 @@ This helper validates that the attributes' values are not included in a given se
<ruby>
class Account < ActiveRecord::Base
- validates_exclusion_of :subdomain, :in => %w(www),
+ validates_exclusion_of :subdomain, :in => %w(www us ca jp),
:message => "Subdomain %{value} is reserved."
end
</ruby>
@@ -355,7 +355,7 @@ This helper validates that the specified attributes are not empty. It uses the +
<ruby>
class Person < ActiveRecord::Base
- validates_presence_of :name, :login, :email
+ validates :name, :login, :email, :presence => true
end
</ruby>
@@ -505,7 +505,7 @@ class Person < ActiveRecord::Base
validates_numericality_of :age, :on => :update
# the default (validates on both create and update)
- validates_presence_of :name, :on => :save
+ validates :name, :presence => true, :on => :save
end
</ruby>
@@ -603,7 +603,7 @@ Returns an OrderedHash with all errors. Each key is the attribute name and the v
<ruby>
class Person < ActiveRecord::Base
- validates_presence_of :name
+ validates :name, :presence => true
validates_length_of :name, :minimum => 3
end
@@ -623,7 +623,7 @@ h4(#working_with_validation_errors-errors-2). +errors[]+
<ruby>
class Person < ActiveRecord::Base
- validates_presence_of :name
+ validates :name, :presence => true
validates_length_of :name, :minimum => 3
end
@@ -699,7 +699,7 @@ The +clear+ method is used when you intentionally want to clear all the messages
<ruby>
class Person < ActiveRecord::Base
- validates_presence_of :name
+ validates :name, :presence => true
validates_length_of :name, :minimum => 3
end
@@ -723,7 +723,7 @@ The +size+ method returns the total number of error messages for the object.
<ruby>
class Person < ActiveRecord::Base
- validates_presence_of :name
+ validates :name, :presence => true
validates_length_of :name, :minimum => 3
validates_presence_of :email
end
@@ -824,10 +824,10 @@ Here is a simple example where we change the Rails behaviour to always display t
ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
if instance.error_message.kind_of?(Array)
%(#{html_tag}<span class="validation-error">&nbsp;
- #{instance.error_message.join(',')}</span>)
+ #{instance.error_message.join(',')}</span>).html_safe
else
%(#{html_tag}<span class="validation-error">&nbsp;
- #{instance.error_message}</span>)
+ #{instance.error_message}</span>).html_safe
end
end
</ruby>
@@ -1128,14 +1128,14 @@ As with callback classes, the observer's methods receive the observed model as a
h4. Registering Observers
-Observers are conventionally placed inside of your +app/models+ directory and registered in your application's +config/environment.rb+ file. For example, the +UserObserver+ above would be saved as +app/models/user_observer.rb+ and registered in +config/environment.rb+ this way:
+Observers are conventionally placed inside of your +app/models+ directory and registered in your application's +config/application.rb+ file. For example, the +UserObserver+ above would be saved as +app/models/user_observer.rb+ and registered in +config/application.rb+ this way:
<ruby>
# Activate observers that should always be running
config.active_record.observers = :user_observer
</ruby>
-As usual, settings in +config/environments+ take precedence over those in +config/environment.rb+. So, if you prefer that an observer doesn't run in all environments, you can simply register it in a specific environment instead.
+As usual, settings in +config/environments+ take precedence over those in +config/application.rb+. So, if you prefer that an observer doesn't run in all environments, you can simply register it in a specific environment instead.
h4. Sharing Observers
@@ -1151,7 +1151,7 @@ class MailerObserver < ActiveRecord::Observer
end
</ruby>
-In this example, the +after_create+ method would be called whenever a +Registration+ or +User+ was created. Note that this new +MailerObserver+ would also need to be registered in +config/environment.rb+ in order to take effect.
+In this example, the +after_create+ method would be called whenever a +Registration+ or +User+ was created. Note that this new +MailerObserver+ would also need to be registered in +config/application.rb+ in order to take effect.
<ruby>
# Activate observers that should always be running
@@ -1160,8 +1160,6 @@ config.active_record.observers = :mailer_observer
h3. Changelog
-"Lighthouse ticket":http://rails.lighthouseapp.com/projects/16213/tickets/26-active-record-validations-and-callbacks
-
* July 20, 2010: Fixed typos and rephrased some paragraphs for clarity. "Jaime Iniesta":http://jaimeiniesta.com
* May 24, 2010: Fixed document to validate XHTML 1.0 Strict. "Jaime Iniesta":http://jaimeiniesta.com
* May 15, 2010: Validation Errors section updated by "Emili Parreño":http://www.eparreno.com
diff --git a/railties/guides/source/active_support_core_extensions.textile b/railties/guides/source/active_support_core_extensions.textile
index dfc4d38112..7333a81cf9 100644
--- a/railties/guides/source/active_support_core_extensions.textile
+++ b/railties/guides/source/active_support_core_extensions.textile
@@ -167,6 +167,12 @@ def log_info(sql, name, ms)
end
</ruby>
++try+ can also be called without arguments but a block, which will only be executed if the object is not nil:
+
+<ruby>
+@person.try { |p| "#{p.first_name} #{p.last_name}" }
+</ruby>
+
NOTE: Defined in +active_support/core_ext/object/try.rb+.
h4. +singleton_class+
@@ -395,39 +401,6 @@ C.new(0, 1).instance_values # => {"x" => 0, "y" => 1}
NOTE: Defined in +active_support/core_ext/object/instance_variables.rb+.
-h5. +copy_instance_variables_from(object, exclude = [])+
-
-Copies the instance variables of +object+ into +self+.
-
-Instance variable names in the +exclude+ array are ignored. If +object+
-responds to +protected_instance_variables+ the ones returned are
-also ignored. For example, Rails controllers implement that method.
-
-In both arrays strings and symbols are understood, and they have to include
-the at sign.
-
-<ruby>
-class C
- def initialize(x, y, z)
- @x, @y, @z = x, y, z
- end
-
- def protected_instance_variables
- %w(@z)
- end
-end
-
-a = C.new(0, 1, 2)
-b = C.new(3, 4, 5)
-
-a.copy_instance_variables_from(b, [:@y])
-# a is now: @x = 3, @y = 1, @z = 2
-</ruby>
-
-In the example +object+ and +self+ are of the same type, but they don't need to.
-
-NOTE: Defined in +active_support/core_ext/object/instance_variables.rb+.
-
h4. Silencing Warnings, Streams, and Exceptions
The methods +silence_warnings+ and +enable_warnings+ change the value of +$VERBOSE+ accordingly for the duration of their block, and reset it afterwards:
@@ -1216,6 +1189,12 @@ To insert something verbatim use the +raw+ helper rather than calling +html_safe
<%= raw @cms.current_template %> <%# inserts @cms.current_template as is %>
</erb>
+or, equivalently, use <tt><%==</tt>:
+
+<erb>
+<%== @cms.current_template %> <%# inserts @cms.current_template as is %>
+</erb>
+
The +raw+ helper calls +html_safe+ for you:
<ruby>
@@ -2859,9 +2838,9 @@ d.end_of_week # => Sun, 09 May 2010
+beginning_of_week+ is aliased to +monday+ and +at_beginning_of_week+. +end_of_week+ is aliased to +sunday+ and +at_end_of_week+.
-h6. +next_week+
+h6. +prev_week+, +next_week+
-+next_week+ receives a symbol with a day name in English (in lowercase, default is +:monday+) and it returns the date corresponding to that day in the next week:
+The method +next_week+ receives a symbol with a day name in English (in lowercase, default is +:monday+) and it returns the date corresponding to that day:
<ruby>
d = Date.new(2010, 5, 9) # => Sun, 09 May 2010
@@ -2869,6 +2848,14 @@ d.next_week # => Mon, 10 May 2010
d.next_week(:saturday) # => Sat, 15 May 2010
</ruby>
+The method +prev_week+ is analogous:
+
+<ruby>
+d.prev_week # => Mon, 26 Apr 2010
+d.prev_week(:saturday) # => Sat, 01 May 2010
+d.prev_week(:friday) # => Fri, 30 Apr 2010
+</ruby>
+
h6. +beginning_of_month+, +end_of_month+
The methods +beginning_of_month+ and +end_of_month+ return the dates for the beginning and end of the month:
@@ -2946,6 +2933,15 @@ Date.new(2010, 4, 30).months_ago(2) # => Sun, 28 Feb 2010
Date.new(2009, 12, 31).months_since(2) # => Sun, 28 Feb 2010
</ruby>
+h6. +weeks_ago+
+
+The method +weeks_ago+ works analogously for weeks:
+
+<ruby>
+Date.new(2010, 5, 24).weeks_ago(1) # => Mon, 17 May 2010
+Date.new(2010, 5, 24).weeks_ago(2) # => Mon, 10 May 2010
+</ruby>
+
h6. +advance+
The most generic way to jump to other days is +advance+. This method receives a hash with keys +:years+, +:months+, +:weeks+, +:days+, and returns a date advanced as much as the present keys indicate:
@@ -3067,6 +3063,8 @@ yesterday
tomorrow
beginning_of_week (monday, at_beginning_of_week)
end_on_week (at_end_of_week)
+weeks_ago
+prev_week
next_week
months_ago
months_since
@@ -3239,6 +3237,8 @@ beginning_of_day (midnight, at_midnight, at_beginning_of_day)
end_of_day
beginning_of_week (monday, at_beginning_of_week)
end_on_week (at_end_of_week)
+weeks_ago
+prev_week
next_week
months_ago
months_since
@@ -3407,7 +3407,5 @@ NOTE: Defined in +active_support/core_ext/load_error.rb+.
h3. Changelog
-"Lighthouse ticket":https://rails.lighthouseapp.com/projects/16213/tickets/67
-
* August 10, 2010: Starts to take shape, added to the index.
* April 18, 2009: Initial version by "Xavier Noria":credits.html#fxn
diff --git a/railties/guides/source/api_documentation_guidelines.textile b/railties/guides/source/api_documentation_guidelines.textile
index c2131ff450..e3ccd6396c 100644
--- a/railties/guides/source/api_documentation_guidelines.textile
+++ b/railties/guides/source/api_documentation_guidelines.textile
@@ -6,7 +6,7 @@ endprologue.
h3. RDoc
-The Rails API documentation is generated with RDoc 2.5. Please consult the "RDoc documentation":http://rdoc.rubyforge.org/RDoc.htmlFor for help with its markup.
+The Rails API documentation is generated with RDoc 2.5. Please consult the documentation for help with the "markup":http://rdoc.rubyforge.org/RDoc.html, and take into account also these "additional directives":http://rdoc.rubyforge.org/RDoc/Parser/Ruby.html.
h3. Wording
@@ -116,14 +116,12 @@ Use fixed-width fonts for:
* file names
<ruby>
-# Copies the instance variables of +object+ into +self+.
-#
-# Instance variable names in the +exclude+ array are ignored. If +object+
-# responds to <tt>protected_instance_variables</tt> the ones returned are
-# also ignored. For example, Rails controllers implement that method.
-# ...
-def copy_instance_variables_from(object, exclude = [])
- ...
+class Array
+ # Calls <tt>to_param</tt> on all its elements and joins the result with
+ # slashes. This is used by <tt>url_for</tt> in Action Pack.
+ def to_param
+ collect { |e| e.to_param }.join '/'
+ end
end
</ruby>
diff --git a/railties/guides/source/association_basics.textile b/railties/guides/source/association_basics.textile
index f6d61373e1..14bbe907f3 100644
--- a/railties/guides/source/association_basics.textile
+++ b/railties/guides/source/association_basics.textile
@@ -1876,8 +1876,6 @@ Extensions can refer to the internals of the association proxy using these three
h3. Changelog
-"Lighthouse ticket":http://rails.lighthouseapp.com/projects/16213-rails-guides/tickets/11
-
* April 7, 2010: Fixed document to validate XHTML 1.0 Strict. "Jaime Iniesta":http://jaimeiniesta.com
* April 19, 2009: Added +:touch+ option to +belongs_to+ associations by "Mike Gunderloy":credits.html#mgunderloy
* February 1, 2009: Added +:autosave+ option "Mike Gunderloy":credits.html#mgunderloy
diff --git a/railties/guides/source/caching_with_rails.textile b/railties/guides/source/caching_with_rails.textile
index 3320b610e7..63c52da32a 100644
--- a/railties/guides/source/caching_with_rails.textile
+++ b/railties/guides/source/caching_with_rails.textile
@@ -368,7 +368,6 @@ h3. Further reading
h3. Changelog
-"Lighthouse ticket":http://rails.lighthouseapp.com/projects/16213-rails-guides/tickets/10-guide-to-caching
* May 02, 2009: Formatting cleanups
* April 26, 2009: Clean up typos in submitted patch
diff --git a/railties/guides/source/command_line.textile b/railties/guides/source/command_line.textile
index 752b5926f7..acd105c622 100644
--- a/railties/guides/source/command_line.textile
+++ b/railties/guides/source/command_line.textile
@@ -590,6 +590,3 @@ h5. Miscellaneous Tasks
+rake routes+ will list all of your defined routes, which is useful for tracking down routing problems in your app, or giving you a good overview of the URLs in an app you're trying to get familiar with.
-h3. Changelog
-
-"Lighthouse ticket":http://rails.lighthouseapp.com/projects/16213/tickets/29
diff --git a/railties/guides/source/configuring.textile b/railties/guides/source/configuring.textile
index bb38c64307..fcf7ba0ae5 100644
--- a/railties/guides/source/configuring.textile
+++ b/railties/guides/source/configuring.textile
@@ -13,7 +13,7 @@ Rails offers (at least) four good spots to place initialization code:
* application.rb
* Environment-specific Configuration Files
-* Initializers (load_application_initializers)
+* Initializers
* After-Initializers
h3. Running Code Before Rails
@@ -23,39 +23,63 @@ To run some code before Rails itself is loaded, simply put it above the call to
h3. Configuring Rails Components
-In general, the work of configuring Rails means configuring the components of Rails, as well as configuring Rails itself. The +application.rb+ and environment-specific configuration files (such as +config/environments/production.rb+) allow you to specify the various settings that you want to pass down to all of the components. For example, the default Rails 2.3 +application.rb+ file includes one setting:
+In general, the work of configuring Rails means configuring the components of Rails, as well as configuring Rails itself. The +application.rb+ and environment-specific configuration files (such as +config/environments/production.rb+) allow you to specify the various settings that you want to pass down to all of the components. For example, the default Rails 3.0 +application.rb+ file includes this setting:
<ruby>
-config.filter_parameters << :password
+ config.filter_parameters += [:password]
</ruby>
This is a setting for Rails itself. If you want to pass settings to individual Rails components, you can do so via the same +config+ object:
<ruby>
-config.active_record.colorize_logging = false
+ config.active_record.timestamped_migrations = false
</ruby>
Rails will use that particular setting to configure Active Record.
h4. Rails General Configuration
-* +config.routes_configuration_file+ overrides the default path for the routes configuration file. This defaults to +config/routes.rb+.
+* +config.after_initialize+ takes a block which will be ran _after_ Rails has finished initializing. Useful for configuring values set up by other initializers:
-* +config.cache_classes+ controls whether or not application classes should be reloaded on each request.
+<ruby>
+ config.after_initialize do
+ ActionView::Base.sanitized_allowed_tags.delete 'div'
+ end
+</ruby>
+
+* +config.allow_concurrency+ should be set to +true+ to allow concurrent (threadsafe) action processing. Set to +false+ by default. You probably don't want to call this one directly, though, because a series of other adjustments need to be made for threadsafe mode to work properly. Can also be enabled with +threadsafe!+.
+
+* +config.asset_host+ sets the host for the assets. Useful when CDNs are used for hosting assets rather than the application server itself. Shorter version of +config.action_controller.asset_host+.
+
+* +config.asset_path+ takes a block which configures where assets can be found. Shorter version of +config.action_controller.asset_path+.
+
+<ruby>
+ config.asset_path = proc { |asset_path| "assets/#{asset_path}" }
+</ruby>
+
+* +config.autoload_once_paths+ accepts an array of paths from which Rails will automatically load from only once. All elements of this array must also be in +autoload_paths+.
+
+* +config.autoload_paths+ accepts an array of additional paths to prepend to the load path. By default, all app, lib, vendor and mock paths are included in this list.
+
+* +config.cache_classes+ controls whether or not application classes should be reloaded on each request. Defaults to _true_ in development, _false_ in test and production. Can also be enabled with +threadsafe!+.
* +config.cache_store+ configures which cache store to use for Rails caching. Options include +:memory_store+, +:file_store+, +:mem_cache_store+ or the name of your own custom class.
-* +config.controller_paths+ accepts an array of paths that will be searched for controllers. Defaults to +app/controllers+.
+* +config.colorize_logging+ specifies whether or not to use ANSI color codes when logging information. Defaults to _true_.
+
+* +config.consider_all_requests_local+ is generally set to +true+ during development and +false+ during production; if it is set to +true+, then any error will cause detailed debugging information to be dumped in the HTTP response. For finer-grained control, set this to +false+ and implement +local_request?+ in controllers to specify which requests should provide debugging information on errors.
-* +config.database_configuration_file+ overrides the default path for the database configuration file. Default to +config/database.yml+.
+* +config.controller_paths+ configures where Rails can find controllers for this application.
-* +config.dependency_loading+ enables or disables dependency loading during the request cycle. Setting dependency_loading to _true_ will allow new classes to be loaded during a request and setting it to _false_ will disable this behavior.
+* +config.dependency_loading+ enables or disables dependency loading during the request cycle. Setting dependency_loading to _true_ will allow new classes to be loaded during a request and setting it to _false_ will disable this behavior. Can also be enabled with +threadsafe!+.
* +config.eager_load_paths+ accepts an array of paths from which Rails will eager load on boot if cache classes is enabled. All elements of this array must also be in +load_paths+.
-* +config.load_once_paths+ accepts an array of paths from which Rails will automatically load from only once. All elements of this array must also be in +load_paths+.
+* +config.encoding+ sets up the application-wide encoding. Defaults to UTF-8.
-* +config.load_paths+ accepts an array of additional paths to prepend to the load path. By default, all app, lib, vendor and mock paths are included in this list.
+* +config.filter_parameters+ used for filtering out the parameters that you don't want shown in the logs, such as passwords or credit card numbers.
+
+* +config.helper_paths+ configures where Rails can find helpers for this application.
* +config.log_level+ defines the verbosity of the Rails logger. In production mode, this defaults to +:info+. In development mode, it defaults to +:debug+.
@@ -63,26 +87,99 @@ h4. Rails General Configuration
* +config.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby 1.8+ Logger class, which is then used to log information from Action Controller. Set to nil to disable logging.
-* +config.plugin_loader+ overrides the class that handles loading each plugin. Defaults to +Rails::Plugin::Loader+.
-
-* +config.plugin_locators+ overrides the class that handle finding the desired plugins that you‘d like to load for your application. By default it is the +Rails::Plugin::FileSystemLocator+.
-
-* +config.plugin_paths+ overrides the path to the root of the plugins directory. Defaults to +vendor/plugins+.
+* +config.middleware+ allows you to configure the application's middleware. This is covered in depth in the "Configuring Middleware" section below.
* +config.plugins+ accepts the list of plugins to load. If this is set to nil, all plugins will be loaded. If this is set to [], no plugins will be loaded. Otherwise, plugins will be loaded in the order specified.
-* +config.preload_frameworks+ enables or disables preloading all frameworks at startup.
+* +config.preload_frameworks+ enables or disables preloading all frameworks at startup. Can also be enabled with +threadsafe!+.
* +config.reload_plugins+ enables or disables plugin reloading.
-* +config.root_path+ configures the root path of the application.
+* +config.root+ configures the root path of the application.
-* +config.time_zone+ sets the default time zone for the application and enables time zone awareness for Active Record.
+* +config.secret_token+ used for specifying a key which allows sessions for the application to be verified against a known secure key to prevent tampering.
+
+* +config.serve_static_assets+ configures Rails to serve static assets. Defaults to _true_, but in the production environment is turned off. The server software used to run the application should be used to serve the assets instead.
+
+* +config.threadsafe!+ enables +allow_concurrency+, +cache_classes+, +dependency_loading+ and +preload_frameworks+ to make the application threadsafe.
-* +config.view_path+ sets the path of the root of an application's views. Defaults to +app/views+.
+WARNING: Threadsafe operation is incompatible with the normal workings of development mode Rails. In particular, automatic dependency loading and class reloading are automatically disabled when you call +config.threadsafe!+.
+
+* +config.time_zone+ sets the default time zone for the application and enables time zone awareness for Active Record.
* +config.whiny_nils+ enables or disabled warnings when an methods of nil are invoked. Defaults to _false_.
+h4. Configuring Generators
+
+Rails 3 allows you to alter what generators are used with the +config.generators+ method. This method takes a block:
+
+<ruby>
+ config.generators do |g|
+ g.orm :active_record
+ g.test_framework :test_unit
+ end
+</ruby>
+
+The full set of methods that can be used in this block are as follows:
+
+* +force_plural+ allows pluralized model names. Defaults to _false_.
+* +helper+ defines whether or not to generate helpers. Defaults to _true_
+* +orm+ defines which orm to use. Defaults to _nil_, so will use Active Record by default.
+* +integration_tool+ defines which integration tool to use. Defaults to _nil_
+* +performance_tool+ defines which performance tool to use. Defaults to _nil_
+* +resource_controller+ defines which generator to use for generating a controller when using +rails generate resource+. Defaults to +:controller+.
+* +scaffold_controller+ different from +resource_controller+, defines which generator to use for generating a _scaffolded_ controller when using +rails generate scaffold+. Defaults to +:scaffold_controller+
+* +stylesheets+ turns on the hook for stylesheets in generators. Used in Rails for when the +scaffold+ generator is ran, but this hook can be used in other generates as well.
+* +test_framework+ defines which test framework to use. Defaults to _nil_, so will use Test::Unit by default.
+* +template_engine+ defines which template engine to use, such as ERB or Haml. Defaults to +:erb+.
+
+h4. Configuring Middleware
+
+Every Rails application comes with a standard set of middleware which it uses in this order in the development environment:
+
+* +ActionDispatch::Static+ is used to serve static assets. Disabled if +config.serve_static_assets+ is _true_.
+* +Rack::Lock+ Will wrap the app in mutex so it can only be called by a single thread at a time. Only enabled if +config.action_controller.allow_concurrency+ is set to _false_, which it is by default.
+* +ActiveSupport::Cache::Strategy::LocalCache+ Serves as a basic memory backed cache. This cache is not thread safe and is intended only for serving as a temporary memory cache for a single thread.
+* +Rack::Runtime+ Sets an +X-Runtime+ header, containing the time (in seconds) taken to execute the request.
+* +Rails::Rack::Logger+ Will notify the logs that the request has began. After request is complete, flushes all the logs.
+* +ActionDispatch::ShowExceptions+ rescues any exception returned by the application and renders nice exception pages if the request is local or if +config.consider_all_requests_local+ is set to _true_. If +config.action_dispatch.show_exceptions+ is set to _false_, exceptions will be raised regardless.
+* +ActionDispatch::RemoteIp+ checks for IP spoofing attacks. Configurable with the +config.action_dispatch.ip_spoofing_check+ and +config.action_dispatch.trusted_proxies+ settings.
+* +Rack::Sendfile+ The Sendfile middleware 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_
+* +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 an +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.
+* +ActionDispatch::ParamsParser+ parses out parameters from the request into +params+
+* +Rack::MethodOverride+ allows the method to be overridden if +params[:_method]+ is set. This is the middleware which supports the PUT and DELETE HTTP method types.
+* +ActionDispatch::Head+ converts HEAD requests to GET requests and serves them as so.
+* +ActionDispatch::BestStandardsSupport+ enables "best standards support" so that IE8 renders some elements correctly.
+
+Besides these usual middleware, you can add your own by using the +config.middleware.use+ method:
+
+<ruby>
+ config.middleware.use Magical::Unicorns
+</ruby>
+
+This will put the +Magical::Unicorns+ middleware on the end of the stack. If you wish to put this middleware before another use +insert_before+:
+
+<ruby>
+ config.middleware.insert_before ActionDispatch::Head, Magical::Unicorns
+</ruby>
+
+There's also +insert_after+ which will insert a middleware _after_ another:
+
+<ruby>
+ config.middleware.insert_after ActionDispatch::Head, Magical::Unicorns
+</ruby>
+
+Middlewares can also be completely swapped out and replaced with others:
+
+<ruby>
+ config.middleware.swap ActionDispatch::BestStandardsSupport, Magical::Unicorns
+</ruby>
+
h4. Configuring i18n
* +config.i18n.default_locale+ sets the default locale of an application used for i18n. Defaults to +:en+.
@@ -105,8 +202,6 @@ h4. Configuring Active Record
* +config.active_record.pluralize_table_names+ specifies whether Rails will look for singular or plural table names in the database. If set to +true+ (the default), then the Customer class will use the +customers+ table. If set to +false+, then the Customers class will use the +customer+ table.
-* +config.active_record.colorize_logging+ (true by default) specifies whether or not to use ANSI color codes when logging information from ActiveRecord.
-
* +config.active_record.default_timezone+ determines whether to use +Time.local+ (if set to +:local+) or +Time.utc+ (if set to +:utc+) when pulling dates and times from the database. The default is +:local+.
* +config.active_record.schema_format+ controls the format for dumping the database schema to a file. The options are +:ruby+ (the default) for a database-independent version that depends on migrations, or +:sql+ for a set of (potentially database-dependent) SQL statements.
@@ -127,34 +222,26 @@ h4. Configuring Action Controller
<tt>config.action_controller</tt> includes a number of configuration settings:
-* +config.action_controller.asset_host+ provides a string that is prepended to all of the URL-generating helpers in +AssetHelper+. This is designed to allow moving all javascript, CSS, and image files to a separate asset host.
+* +config.action_controller.asset_host+ sets the host for the assets. Useful when CDNs are used for hosting assets rather than the application server itself.
-* +config.action_controller.asset_path+ allows you to override the default asset path generation by providing your own instructions.
+* +config.action_controller.asset_path+ takes a block which configures where assets can be found. Shorter version of +config.action_controller.asset_path+.
-* +config.action_controller.consider_all_requests_local+ is generally set to +true+ during development and +false+ during production; if it is set to +true+, then any error will cause detailed debugging information to be dumped in the HTTP response. For finer-grained control, set this to +false+ and implement +local_request?+ to specify which requests should provide debugging information on errors.
+* +config.action_controller.page_cache_directory+ should be the document root for the web server and is set using <tt>Base.page_cache_directory = "/document/root"</tt>. For Rails, this directory has already been set to Rails.public_path (which is usually set to <tt>Rails.root + "/public"</tt>). Changing this setting can be useful to avoid naming conflicts with files in <tt>public/</tt>, but doing so will likely require configuring your web server to look in the new location for cached files.
-* +config.action_controller.allow_concurrency+ should be set to +true+ to allow concurrent (threadsafe) action processing. Set to +false+ by default. You probably don't want to call this one directly, though, because a series of other adjustments need to be made for threadsafe mode to work properly. Instead, you should simply call +config.threadsafe!+ inside your +production.rb+ file, which makes all the necessary adjustments.
-
-WARNING: Threadsafe operation is incompatible with the normal workings of development mode Rails. In particular, automatic dependency loading and class reloading are automatically disabled when you call +config.threadsafe!+.
+* +config.action_controller.page_cache_extension+ configures the extension used for cached pages saved to +page_cache_directory+. Defaults to +.html+
-* +config.action_controller.param_parsers+ provides an array of handlers that can extract information from incoming HTTP requests and add it to the +params+ hash. By default, parsers for multipart forms, URL-encoded forms, XML, and JSON are active.
+* +config.action_controller.perform_caching+ configures whether the application should perform caching or not. Set to _false_ in development mode, _true_ in production.
* +config.action_controller.default_charset+ specifies the default character set for all renders. The default is "utf-8".
* +config.action_controller.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby 1.8+ Logger class, which is then used to log information from Action Controller. Set to nil to disable logging.
-* +config.action_controller.resource_path_names+ is a hash of default names for several RESTful actions. By default, the new action is named +new+ and the edit action is named +edit+.
-
* +config.action_controller.request_forgery_protection_token+ sets the token parameter name for RequestForgery. Calling +protect_from_forgery+ sets it to +:authenticity_token+ by default.
-* +config.action_controller.optimise_named_routes+ turns on some optimizations in generating the routing table. It is set to +true+ by default.
-
* +config.action_controller.allow_forgery_protection+ enables or disables CSRF protection. By default this is +false+ in test mode and +true+ in all other modes.
* +config.action_controller.relative_url_root+ can be used to tell Rails that you are deploying to a subdirectory. The default is +ENV['RAILS_RELATIVE_URL_ROOT']+.
-* +config.action_dispatch.session_store+ sets the name of the store for session data. The default is +:cookie_store+; other valid options include +:active_record_store+, +:mem_cache_store+ or the name of your own custom class.
-
The caching code adds two additional settings:
* +ActionController::Base.page_cache_directory+ sets the directory where Rails will create cached pages for your web server. The default is +Rails.public_path+ (which is usually set to +Rails.root + "/public"+).
@@ -169,14 +256,16 @@ The Active Record session store can also be configured:
* +ActiveRecord::SessionStore::Session.data_column_name+ sets the name of the column which stores marshaled session data. Defaults to +data+.
+h4. Configuring Action Dispatch
+
+* +config.action_dispatch.session_store+ sets the name of the store for session data. The default is +:cookie_store+; other valid options include +:active_record_store+, +:mem_cache_store+ or the name of your own custom class.
+
h4. Configuring Action View
There are only a few configuration options for Action View, starting with four on +ActionView::Base+:
* +config.action_view.debug_rjs+ specifies whether RJS responses should be wrapped in a try/catch block that alert()s the caught exception (and then re-raises it). The default is +false+.
-* +config.action_view.warn_cache_misses+ tells Rails to display a warning whenever an action results in a cache miss on your view paths. The default is +false+.
-
* +config.action_view.field_error_proc+ provides an HTML generator for displaying errors that come from Active Record. The default is <tt>Proc.new{ |html_tag, instance| %Q(%&lt;div class=&quot;field_with_errors&quot;&gt;#{html_tag}&lt;/div&gt;).html_safe }</tt>
* +config.action_view.default_form_builder+ tells Rails which form builder to use by default. The default is +ActionView::Helpers::FormBuilder+.
@@ -189,8 +278,6 @@ h4. Configuring Action Mailer
There are a number of settings available on +config.action_mailer+:
-* +config.action_mailer.template_root+ gives the root folder for Action Mailer templates.
-
* +config.action_mailer.logger+ accepts a logger conforming to the interface of Log4r or the default Ruby 1.8+ Logger class, which is then used to log information from Action Mailer. Set to nil to disable logging.
* +config.action_mailer.smtp_settings+ allows detailed configuration for the +:smtp+ delivery method. It accepts a hash of options, which can include any of these options:
@@ -211,15 +298,13 @@ There are a number of settings available on +config.action_mailer+:
* +config.action_mailer.perform_deliveries+ specifies whether mail will actually be delivered. By default this is +true+; it can be convenient to set it to +false+ for testing.
-* +config.action_mailer.default_charset+ tells Action Mailer which character set to use for the body and for encoding the subject. It defaults to +utf-8+.
-
-* +config.action_mailer.default_content_type+ specifies the default content type used for the main part of the message. It defaults to "text/plain"
-
-* +config.action_mailer.default_mime_version+ is the default MIME version for the message. It defaults to +1.0+.
-
-* +config.action_mailer.default_implicit_parts_order+ - When a message is built implicitly (i.e. multiple parts are assembled from templates
-which specify the content type in their filenames) this variable controls how the parts are ordered. Defaults to +["text/html", "text/enriched", "text/plain"]+. Items that appear first in the array have higher priority in the mail client
-and appear last in the mime encoded message.
+* +config.action_mailer.default+ configures Action Mailer defaults. These default to:
+<ruby>
+ :mime_version => "1.0",
+ :charset => "UTF-8",
+ :content_type => "text/plain",
+ :parts_order => [ "text/plain", "text/enriched", "text/html" ]
+</ruby>
h4. Configuring Active Resource
@@ -241,25 +326,22 @@ There are a few configuration options available in Active Support:
* +ActiveSupport::Logger.silencer+ is set to +false+ to disable the ability to silence logging in a block. The default is +true+.
-h3. Using Initializers
+h3. Initialization events
-After loading the framework and any gems and plugins in your application, Rails turns to loading initializers. An initializer is any file of Ruby code stored under +config/initializers+ in your application. You can use initializers to hold configuration settings that should be made after all of the frameworks and plugins are loaded.
-
-NOTE: You can use subfolders to organize your initializers if you like, because Rails will look into the whole file hierarchy from the +initializers+ folder on down.
+Rails has 4 initialization events which can be hooked into (listed in order that they are ran):
-TIP: If you have any ordering dependency in your initializers, you can control the load order by naming. For example, +01_critical.rb+ will be loaded before +02_normal.rb+.
+* +before_configuration+: This is run as soon as the application constant inherits from +Rails::Application+. The +config+ calls are evaluated before this happens.
+* +before_eager_load+: This is run directly before eager loading occurs, which is the default behaviour for the _production_ environment and not for the +development+ enviroment.
+* +before_initialize+ This is run directly before the initialization process of the application occurs.
+* +after_initialize+ Run directly after the initialization of the application, but before the application initializers are run.
-h3. Using an After-Initializer
+WARNING: Some parts of your application, notably observers and routing, are not yet set up at the point where the +after_initialize+ block is called.
-After-initializers are run (as you might guess) after any initializers are loaded. You can supply an +after_initialize+ block (or an array of such blocks) by setting up +config.after_initialize+ in any of the Rails configuration files:
+After loading the framework and any gems and plugins in your application, Rails turns to loading initializers. An initializer is any file of Ruby code stored under +config/initializers+ in your application. You can use initializers to hold configuration settings that should be made after all of the frameworks and plugins are loaded.
-<ruby>
-config.after_initialize do
- SomeClass.init
-end
-</ruby>
+NOTE: You can use subfolders to organize your initializers if you like, because Rails will look into the whole file hierarchy from the +initializers+ folder on down.
-WARNING: Some parts of your application, notably observers and routing, are not yet set up at the point where the +after_initialize+ block is called.
+TIP: If you have any ordering dependency in your initializers, you can control the load order by naming. For example, +01_critical.rb+ will be loaded before +02_normal.rb+.
h3. Rails Environment Settings
@@ -273,12 +355,9 @@ Some parts of Rails can also be configured externally by supplying environment v
* +ENV["RAILS_CACHE_ID"]+ and +ENV["RAILS_APP_VERSION"]+ are used to generate expanded cache keys in Rails' caching code. This allows you to have multiple separate caches from the same application.
-* +ENV['RAILS_GEM_VERSION']+ defines the version of the Rails gems to use, if +RAILS_GEM_VERSION+ is not defined in your +environment.rb+ file.
-
h3. Changelog
-"Lighthouse ticket":http://rails.lighthouseapp.com/projects/16213-rails-guides/tickets/28
-
+* November 26, 2010: Removed all config settings not available in Rails 3 (Ryan Bigg)
* August 13, 2009: Updated with config syntax and added general configuration options by "John Pignata"
* January 3, 2009: First reasonably complete draft by "Mike Gunderloy":credits.html#mgunderloy
* November 5, 2008: Rough outline by "Mike Gunderloy":credits.html#mgunderloy
diff --git a/railties/guides/source/contribute.textile b/railties/guides/source/contribute.textile
index 88c5c79e9d..3d4607de1d 100644
--- a/railties/guides/source/contribute.textile
+++ b/railties/guides/source/contribute.textile
@@ -1,6 +1,6 @@
h2. Contribute to the Rails Guides
-Rails Guides aim to improve the Rails documentation and to make the barrier to entry as low as possible. A reasonably experienced developer should be able to use the Guides to come up to speed on Rails quickly. You can track the overall effort at the "Rails Guides Lighthouse":http://rails.lighthouseapp.com/projects/16213-rails-guides/tickets. Our sponsors have contributed prizes for those who write an entire guide, but there are many other ways to contribute.
+Rails Guides aim to improve the Rails documentation and to make the barrier to entry as low as possible. A reasonably experienced developer should be able to use the guides to come up to speed on Rails quickly. Our sponsors have contributed prizes for those who write an entire guide, but there are many other ways to contribute.
endprologue.
diff --git a/railties/guides/source/contributing_to_rails.textile b/railties/guides/source/contributing_to_rails.textile
index 7184759610..1a1f4e9858 100644
--- a/railties/guides/source/contributing_to_rails.textile
+++ b/railties/guides/source/contributing_to_rails.textile
@@ -105,12 +105,17 @@ mysql> GRANT ALL PRIVILEGES ON activerecord_unittest2.*
to 'rails'@'localhost';
</shell>
-Then ensure you run bundle install without the +--without db+ option:
+Now you'll have to install Active Record dependencies. This step is a little tricky because just running +bundle install+ without the +--without db+ parameter won't get those dependencies installed. It turns out that bundler remembers the +--without db+ parameter between calls so you'll have to manually override this. (See the "+bundle_install+ man page":http://gembundler.com/man/bundle-install.1.html for details)
+
+The easiest way to do this is to remove bundler's config file and then run +install+ again:
<shell>
+rm .bundle/config
bundle install
</shell>
+INFO: If you don't feel comfortable deleting bundler's config file, you can achieve the same effect by manually removing the "+BUNDLE_WITHOUT: db+" line on +.bundle/config+.
+
Finally, enter this from the +activerecord+ directory to create the test databases:
<shell>
@@ -127,7 +132,7 @@ You can now run tests as you did for +sqlite3+:
rake test_mysql
</shell>
-You can also +myqsl+ with +postgresql+, +jdbcmysql+, +jdbcsqlite3+ or +jdbcpostgresql+. Check out the file +activerecord/RUNNING_UNIT_TESTS+ for information on running more targeted database tests, or the file +ci/ci_build.rb+ to see the test suite that the Rails continuous integration server runs.
+You can also replace +mysql+ with +postgresql+, +jdbcmysql+, +jdbcsqlite3+ or +jdbcpostgresql+. Check out the file +activerecord/RUNNING_UNIT_TESTS+ for information on running more targeted database tests, or the file +ci/ci_build.rb+ to see the test suite that the Rails continuous integration server runs.
NOTE: If you're working with Active Record code, you _must_ ensure that the tests pass for at least MySQL, PostgreSQL, and SQLite 3. Subtle differences between the various Active Record database adapters have been behind the rejection of many patches that looked OK when tested only against MySQL.
@@ -189,7 +194,7 @@ h3. Contributing to the Rails Documentation
Another area where you can help out if you're not yet ready to take the plunge to writing Rails core code is with Rails documentation. You can help with the Rails Guides or the Rails API documentation.
-TIP: "docrails":http://github.com/lifo/docrails/tree/master is the documentation branch for Rails with an *open commit policy*. You can simply PM "lifo":http://github.com/lifo on Github and ask for the commit rights. Documentation changes made as part of the "docrails":http://github.com/lifo/docrails/tree/master project are merged back to the Rails master code from time to time. Check out the "original announcement":http://weblog.rubyonrails.org/2008/5/2/help-improve-rails-documentation-on-git-branch for more details.
+TIP: "docrails":http://github.com/lifo/docrails/tree/master is the documentation branch for Rails with an *open commit policy*, it has public write access. Documentation changes made as part of the "docrails":http://github.com/lifo/docrails/tree/master project are merged back to the Rails master code from time to time. Check out the "original announcement":http://weblog.rubyonrails.org/2008/5/2/help-improve-rails-documentation-on-git-branch for more details.
h4. The Rails Guides
@@ -300,8 +305,6 @@ And then...think about your next contribution!
h3. Changelog
-"Lighthouse ticket":http://rails.lighthouseapp.com/projects/16213-rails-guides/tickets/64
-
* April 6, 2010: Fixed document to validate XHTML 1.0 Strict. "Jaime Iniesta":http://jaimeiniesta.com
* August 1, 2009: Updates/amplifications by "Mike Gunderloy":credits.html#mgunderloy
* March 2, 2009: Initial draft by "Mike Gunderloy":credits.html#mgunderloy
diff --git a/railties/guides/source/debugging_rails_applications.textile b/railties/guides/source/debugging_rails_applications.textile
index 35069f33ad..6613fad406 100644
--- a/railties/guides/source/debugging_rails_applications.textile
+++ b/railties/guides/source/debugging_rails_applications.textile
@@ -127,8 +127,8 @@ Rails makes use of Ruby's standard +logger+ to write log information. You can al
You can specify an alternative logger in your +environment.rb+ or any environment file:
<ruby>
-ActiveRecord::Base.logger = Logger.new(STDOUT)
-ActiveRecord::Base.logger = Log4r::Logger.new("Application Log")
+Rails.logger = Logger.new(STDOUT)
+Rails.logger = Log4r::Logger.new("Application Log")
</ruby>
Or in the +Initializer+ section, add _any_ of the following
@@ -142,13 +142,13 @@ TIP: By default, each log is created under +Rails.root/log/+ and the log file na
h4. Log Levels
-When something is logged it's printed into the corresponding log if the log level of the message is equal or higher than the configured log level. If you want to know the current log level you can call the +ActiveRecord::Base.logger.level+ method.
+When something is logged it's printed into the corresponding log if the log level of the message is equal or higher than the configured log level. If you want to know the current log level you can call the +Rails.logger.level+ method.
The available log levels are: +:debug+, +:info+, +:warn+, +:error+, and +:fatal+, corresponding to the log level numbers from 0 up to 4 respectively. To change the default log level, use
<ruby>
config.log_level = Logger::WARN # In any environment initializer, or
-ActiveRecord::Base.logger.level = 0 # at any time
+Rails.logger.level = 0 # at any time
</ruby>
This is useful when you want to log under development or staging, but you don't want to flood your production log with unnecessary information.
@@ -225,6 +225,8 @@ The debugger used by Rails, +ruby-debug+, comes as a gem. To install it, just ru
$ sudo gem install ruby-debug
</shell>
+TIP: If you are using Ruby 1.9, you can install a compatible version of +ruby-debug+ by running +sudo gem install ruby-debug19+
+
In case you want to download a particular version or get the source code, refer to the "project's page on rubyforge":http://rubyforge.org/projects/ruby-debug/.
Rails has had built-in support for ruby-debug since Rails 2.0. Inside any Rails application you can invoke the debugger by calling the +debugger+ method.
@@ -250,7 +252,7 @@ Make sure you have started your web server with the option +--debugger+:
<shell>
~/PathTo/rails_project$ rails server --debugger
-=> Booting Mongrel (use 'rails server webrick' to force WEBrick)
+=> Booting WEBrick
=> Rails 3.0.0 application starting on http://0.0.0.0:3000
=> Debugger enabled
...
@@ -258,8 +260,6 @@ Make sure you have started your web server with the option +--debugger+:
TIP: In development mode, you can dynamically +require \'ruby-debug\'+ instead of restarting the server, if it was started without +--debugger+.
-In order to use Rails debugging you'll need to be running either *WEBrick* or *Mongrel*. For the moment, no alternative servers are supported.
-
h4. The Shell
As soon as your application calls the +debugger+ method, the debugger will be started in a debugger shell inside the terminal window where you launched your application server, and you will be placed at ruby-debug's prompt +(rdb:n)+. The _n_ is the thread number. The prompt will also show you the next line of code that is waiting to run.
@@ -704,8 +704,6 @@ h3. References
h3. Changelog
-"Lighthouse ticket":http://rails.lighthouseapp.com/projects/16213-rails-guides/tickets/5
-
* April 4, 2010: Fixed document to validate XHTML 1.0 Strict. "Jaime Iniesta":http://jaimeiniesta.com
* November 3, 2008: Accepted for publication. Added RJS, memory leaks and plugins chapters by "Emilio Tagua":credits.html#miloops
* October 19, 2008: Copy editing pass by "Mike Gunderloy":credits.html#mgunderloy
diff --git a/railties/guides/source/form_helpers.textile b/railties/guides/source/form_helpers.textile
index ce0f66b2c1..e178a60307 100644
--- a/railties/guides/source/form_helpers.textile
+++ b/railties/guides/source/form_helpers.textile
@@ -59,15 +59,15 @@ To create this form you will use +form_tag+, +label_tag+, +text_field_tag+, and
A basic search form
-<html>
+<erb>
<%= form_tag(search_path, :method => "get") do %>
<%= label_tag(:q, "Search for:") %>
<%= text_field_tag(:q) %>
<%= submit_tag("Search") %>
<% end %>
-</html>
+</erb>
-TIP: +search_path+ can be a named route specified in "routes.rb": <br /><tt>map.search "search", :controller => "search"</tt>
+TIP: +search_path+ can be a named route specified in "routes.rb" as: <br /><code>match "search" => "search"</code> This declares that path "/search" will be handled by action "search" belonging to controller "search".
The above view code will result in the following markup:
@@ -107,7 +107,7 @@ WARNING: Do not delimit the second hash without doing so with the first hash, ot
h4. Helpers for Generating Form Elements
-Rails provides a series of helpers for generating form elements such as checkboxes, text fields, radio buttons, and so on. These basic helpers, with names ending in <notextile>_tag</notextile> such as +text_field_tag+, +check_box_tag+, etc., generate just a single +&lt;input&gt;+ element. The first parameter to these is always the name of the input. In the controller this name will be the key in the +params+ hash used to get the value entered by the user. For example, if the form contains
+Rails provides a series of helpers for generating form elements such as checkboxes, text fields and radio buttons. These basic helpers, with names ending in <notextile>_tag</notextile> such as +text_field_tag+ and +check_box_tag+ generate just a single +&lt;input&gt;+ element. The first parameter to these is always the name of the input. In the controller this name will be the key in the +params+ hash used to get the value entered by the user. For example, if the form contains
<erb>
<%= text_field_tag(:query) %>
@@ -127,17 +127,19 @@ Checkboxes are form controls that give the user a set of options they can enable
<erb>
<%= check_box_tag(:pet_dog) %>
- <%= label_tag(:pet_dog, "I own a dog") %>
+<%= label_tag(:pet_dog, "I own a dog") %>
<%= check_box_tag(:pet_cat) %>
- <%= label_tag(:pet_cat, "I own a cat") %>
+<%= label_tag(:pet_cat, "I own a cat") %>
+</erb>
output:
+<html>
<input id="pet_dog" name="pet_dog" type="checkbox" value="1" />
- <label for="pet_dog">I own a dog</label>
+<label for="pet_dog">I own a dog</label>
<input id="pet_cat" name="pet_cat" type="checkbox" value="1" />
- <label for="pet_cat">I own a cat</label>
-</erb>
+<label for="pet_cat">I own a cat</label>
+</html>
The second parameter to +check_box_tag+ is the value of the input. This is the value that will be submitted by the browser if the checkbox is ticked (i.e. the value that will be present in the +params+ hash). With the above form you would check the value of +params[:pet_dog]+ and +params[:pet_cat]+ to see which pets the user owns.
@@ -147,17 +149,19 @@ Radio buttons, while similar to checkboxes, are controls that specify a set of o
<erb>
<%= radio_button_tag(:age, "child") %>
- <%= label_tag(:age_child, "I am younger than 21") %>
+<%= label_tag(:age_child, "I am younger than 21") %>
<%= radio_button_tag(:age, "adult") %>
- <%= label_tag(:age_adult, "I'm over 21") %>
+<%= label_tag(:age_adult, "I'm over 21") %>
+</erb>
output:
+<html>
<input id="age_child" name="age" type="radio" value="child" />
- <label for="age_child">I am younger than 21</label>
+<label for="age_child">I am younger than 21</label>
<input id="age_adult" name="age" type="radio" value="adult" />
- <label for="age_adult">I'm over 21</label>
-</erb>
+<label for="age_adult">I'm over 21</label>
+</html>
As with +check_box_tag+ the second parameter to +radio_button_tag+ is the value of the input. Because these two radio buttons share the same name (age) the user will only be able to select one and +params[:age]+ will contain either "child" or "adult".
@@ -171,13 +175,15 @@ Other form controls worth mentioning are the text area, password input and hidde
<%= text_area_tag(:message, "Hi, nice site", :size => "24x6") %>
<%= password_field_tag(:password) %>
<%= hidden_field_tag(:parent_id, "5") %>
+</erb>
output:
+<html>
<textarea id="message" name="message" cols="24" rows="6">Hi, nice site</textarea>
<input id="password" name="password" type="password" />
<input id="parent_id" name="parent_id" type="hidden" value="5" />
-</erb>
+</html>
Hidden inputs are not shown to the user, but they hold data like any textual input. Values inside them can be changed with JavaScript.
@@ -226,13 +232,13 @@ The corresponding view +app/views/articles/new.html.erb+ using +form_for+ looks
<%= form_for @article, :url => { :action => "create" }, :html => {:class => "nifty_form"} do |f| %>
<%= f.text_field :title %>
<%= f.text_area :body, :size => "60x12" %>
- <%= submit_tag "Create" %>
+ <%= f.submit "Create" %>
<% end %>
</erb>
There are a few things to note here:
-# +:article+ is the name of the model and +@article+ is the actual object being edited.
+# +@article+ is the actual object being edited.
# There is a single hash of options. Routing options are passed in the +:url+ hash, HTML options are passed in the +:html+ hash.
# The +form_for+ method yields a *form builder* object (the +f+ variable).
# Methods to create form controls are called *on* the form builder object +f+
@@ -278,7 +284,7 @@ h4. Relying on Record Identification
The Article model is directly available to users of the application, so -- following the best practices for developing with Rails -- you should declare it *a resource*:
<ruby>
-map.resources :articles
+resources :articles
</ruby>
TIP: Declaring a resource has a number of side-affects. See "Rails Routing From the Outside In":routing.html#resource-routing-the-rails-default for more information on setting up and using resources.
@@ -288,13 +294,13 @@ When dealing with RESTful resources, calls to +form_for+ can get significantly e
<ruby>
## Creating a new article
# long-style:
-form_for(:article, @article, :url => articles_path)
+form_for(@article, :url => articles_path)
# same thing, short-style (record identification gets used):
form_for(@article)
## Editing an existing article
# long-style:
-form_for(:article, @article, :url => article_path(@article), :html => { :method => "put" })
+form_for(@article, :url => article_path(@article), :html => { :method => "put" })
# short-style:
form_for(@article)
</ruby>
@@ -770,8 +776,6 @@ Many apps grow beyond simple forms editing a single object. For example when cre
h3. Changelog
-"Lighthouse ticket":http://rails.lighthouseapp.com/projects/16213-rails-guides/tickets/1
-
* April 6, 2010: Fixed document to validate XHTML 1.0 Strict. "Jaime Iniesta":http://jaimeiniesta.com
h3. Authors
diff --git a/railties/guides/source/generators.textile b/railties/guides/source/generators.textile
index b1f8ea29da..99c34ed30f 100644
--- a/railties/guides/source/generators.textile
+++ b/railties/guides/source/generators.textile
@@ -92,7 +92,7 @@ class InitializerGenerator < Rails::Generators::NamedBase
end
</ruby>
-First, notice that we are inheriting from +Rails::Generators::NamedBase+ instead of +Rails::Generators::Base+. This means that our generator expects at least one argument, which will be the name of the initializer.
+First, notice that we are inheriting from +Rails::Generators::NamedBase+ instead of +Rails::Generators::Base+. This means that our generator expects at least one argument, which will be the name of the initializer, and will be available in our code in the variable +name+.
We can see that by invoking the description of this new generator (don't forget to delete the old generator file):
@@ -144,7 +144,7 @@ generators/initializer_generator.rb
If none is found you get an error message.
-INFO: The examples above put files under the application's +lib+ because said directoty belongs to +$LOAD_PATH+.
+INFO: The examples above put files under the application's +lib+ because said directory belongs to +$LOAD_PATH+.
h3. Customizing Your Workflow
@@ -201,7 +201,7 @@ config.generators do |g|
end
</ruby>
-If we generate another resource with the scaffold generator, we can notice that neither stylesheets nor fixtures are created anymore. If you want to customize it further, for example to use DataMapper and RSpec instead of Active Record and TestUnit, it's just a matter of adding their gems to your application and configuring your generators.
+If we generate another resource with the scaffold generator, we can see that neither stylesheets nor fixtures are created anymore. If you want to customize it further, for example to use DataMapper and RSpec instead of Active Record and TestUnit, it's just a matter of adding their gems to your application and configuring your generators.
To demonstrate this, we are going to create a new helper generator that simply adds some instance variable readers. First, we create a generator:
@@ -363,8 +363,6 @@ Fallbacks allow your generators to have a single responsibility, increasing code
h3. Changelog
-"Lighthouse Ticket":http://rails.lighthouseapp.com/projects/16213-rails-guides/tickets/102
-
* August 23, 2010: Edit pass by "Xavier Noria":credits.html#fxn
* April 30, 2010: Reviewed by José Valim
diff --git a/railties/guides/source/getting_started.textile b/railties/guides/source/getting_started.textile
index 42b3313752..902b7353c0 100644
--- a/railties/guides/source/getting_started.textile
+++ b/railties/guides/source/getting_started.textile
@@ -282,7 +282,7 @@ You actually have a functional Rails application already. To see it, you need to
$ rails server
</shell>
-This will fire up an instance of the Mongrel web server by default (Rails can also use several other web servers). To see your application in action, open a browser window and navigate to "http://localhost:3000":http://localhost:3000. You should see Rails' default information page:
+This will fire up an instance of the WEBrick web server by default (Rails can also use several other web servers). To see your application in action, open a browser window and navigate to "http://localhost:3000":http://localhost:3000. You should see Rails' default information page:
!images/rails_welcome.png(Welcome Aboard screenshot)!
@@ -727,7 +727,6 @@ After finding the requested post, Rails uses the +edit.html.erb+ view to display
<%= link_to 'Show', @post %> |
<%= link_to 'Back', posts_path %>
-<% end %>
</erb>
Again, as with the +new+ action, the +edit+ action is using the +form+ partial, this time however, the form will do a PUT action to the PostsController and the submit button will display "Update Post"
@@ -920,8 +919,6 @@ So first, we'll wire up the Post show template (+/app/views/posts/show.html.erb+
<h2>Add a comment:</h2>
<%= form_for([@post, @post.comments.build]) do |f| %>
- <%= f.error_messages %>
-
<div class="field">
<%= f.label :commenter %><br />
<%= f.text_field :commenter %>
@@ -990,8 +987,6 @@ Once we have made the new comment, we send the user back to the original post us
<h2>Add a comment:</h2>
<%= form_for([@post, @post.comments.build]) do |f| %>
- <%= f.error_messages %>
-
<div class="field">
<%= f.label :commenter %><br />
<%= f.text_field :commenter %>
@@ -1058,8 +1053,6 @@ Then in the +app/views/posts/show.html.erb+ you can change it to look like the f
<h2>Add a comment:</h2>
<%= form_for([@post, @post.comments.build]) do |f| %>
- <%= f.error_messages %>
-
<div class="field">
<%= f.label :commenter %><br />
<%= f.text_field :commenter %>
@@ -1087,8 +1080,6 @@ Lets also move that new comment section out to it's own partial, again, you crea
<erb>
<%= form_for([@post, @post.comments.build]) do |f| %>
- <%= f.error_messages %>
-
<div class="field">
<%= f.label :commenter %><br />
<%= f.text_field :commenter %>
@@ -1478,8 +1469,6 @@ Two very common sources of data that are not UTF-8:
h3. Changelog
-"Lighthouse ticket":http://rails.lighthouseapp.com/projects/16213-rails-guides/tickets/2
-
* August 30, 2010: Minor editing after Rails 3 release by "Joost Baaij":http://www.spacebabies.nl
* July 12, 2010: Fixes, editing and updating of code samples by "Jaime Iniesta":http://jaimeiniesta.com
* May 16, 2010: Added a section on configuration gotchas to address common encoding problems that people might have by "Yehuda Katz":http://www.yehudakatz.com
diff --git a/railties/guides/source/i18n.textile b/railties/guides/source/i18n.textile
index 8a7e9fcae6..8a39bdf3c1 100644
--- a/railties/guides/source/i18n.textile
+++ b/railties/guides/source/i18n.textile
@@ -127,7 +127,7 @@ If you want to translate your Rails application to a *single language other than
However, you would probably like to *provide support for more locales* in your application. In such case, you need to set and pass the locale between requests.
-WARNING: You may be tempted to store the chosen locale in a _session_ or a _cookie_. *Do not do so*. The locale should be transparent and a part of the URL. This way you don't break people's basic assumptions about the web itself: if you send a URL of some page to a friend, she should see the same page, same content. A fancy word for this would be that you're being "_RESTful_":http://en.wikipedia.org/wiki/Representational_State_Transfer. Read more about the RESTful approach in "Stefan Tilkov's articles":http://www.infoq.com/articles/rest-introduction. There may be some exceptions to this rule, which are discussed below.
+WARNING: You may be tempted to store the chosen locale in a _session_ or a <em>cookie</em>. *Do not do so*. The locale should be transparent and a part of the URL. This way you don't break people's basic assumptions about the web itself: if you send a URL of some page to a friend, she should see the same page, same content. A fancy word for this would be that you're being "<em>RESTful</em>":http://en.wikipedia.org/wiki/Representational_State_Transfer. Read more about the RESTful approach in "Stefan Tilkov's articles":http://www.infoq.com/articles/rest-introduction. There may be some exceptions to this rule, which are discussed below.
The _setting part_ is easy. You can set the locale in a +before_filter+ in the +ApplicationController+ like this:
@@ -253,7 +253,7 @@ match '/:locale' => 'dashboard#index'
Do take special care about the *order of your routes*, so this route declaration does not "eat" other ones. (You may want to add it directly before the +root :to+ declaration.)
-IMPORTANT: This solution has currently one rather big *downside*. Due to the _default_url_options_ implementation, you have to pass the +:id+ option explicitly, like this: +link_to 'Show', book_url(:id => book)+ and not depend on Rails' magic in code like +link_to 'Show', book+. If this should be a problem, have a look at two plugins which simplify work with routes in this way: Sven Fuchs's "routing_filter":http://github.com/svenfuchs/routing-filter/tree/master and Raul Murciano's "translate_routes":http://github.com/raul/translate_routes/tree/master. See also the page "How to encode the current locale in the URL":http://rails-i18n.org/wiki/wikipages/how-to-encode-the-current-locale-in-the-url in the Rails i18n Wiki.
+NOTE: Have a look at two plugins which simplify work with routes in this way: Sven Fuchs's "routing_filter":http://github.com/svenfuchs/routing-filter/tree/master and Raul Murciano's "translate_routes":http://github.com/raul/translate_routes/tree/master.
h4. Setting the Locale from the Client Supplied Information
@@ -278,7 +278,7 @@ def extract_locale_from_accept_language_header
end
</ruby>
-Of course, in a production environment you would need much more robust code, and could use a plugin such as Iain Hecker's "http_accept_language":http://github.com/iain/http_accept_language/tree/master or even Rack middleware such as Ryan Tomayko's "locale":http://github.com/rtomayko/rack-contrib/blob/master/lib/rack/locale.rb.
+Of course, in a production environment you would need much more robust code, and could use a plugin such as Iain Hecker's "http_accept_language":http://github.com/iain/http_accept_language/tree/master or even Rack middleware such as Ryan Tomayko's "locale":http://github.com/rack/rack-contrib/blob/master/lib/rack/contrib/locale.rb.
h5. Using GeoIP (or Similar) Database
@@ -464,24 +464,24 @@ I18n.t 'message'
The +translate+ method also takes a +:scope+ option which can contain one or more additional keys that will be used to specify a “namespace” or scope for a translation key:
<ruby>
-I18n.t :invalid, :scope => [:activerecord, :errors, :messages]
+I18n.t :record_invalid, :scope => [:activerecord, :errors, :messages]
</ruby>
-This looks up the +:invalid+ message in the Active Record error messages.
+This looks up the +:record_invalid+ message in the Active Record error messages.
Additionally, both the key and scopes can be specified as dot-separated keys as in:
<ruby>
-I18n.translate :"activerecord.errors.messages.invalid"
+I18n.translate "activerecord.errors.messages.record_invalid"
</ruby>
Thus the following calls are equivalent:
<ruby>
-I18n.t 'activerecord.errors.messages.invalid'
-I18n.t 'errors.messages.invalid', :scope => :active_record
-I18n.t :invalid, :scope => 'activerecord.errors.messages'
-I18n.t :invalid, :scope => [:activerecord, :errors, :messages]
+I18n.t 'activerecord.errors.messages.record_invalid'
+I18n.t 'errors.messages.record_invalid', :scope => :active_record
+I18n.t :record_invalid, :scope => 'activerecord.errors.messages'
+I18n.t :record_invalid, :scope => [:activerecord, :errors, :messages]
</ruby>
h5. Defaults
@@ -672,11 +672,11 @@ Active Record validation error messages can also be translated easily. Active Re
This gives you quite powerful means to flexibly adjust your messages to your application's needs.
-Consider a User model with a +validates_presence_of+ validation for the name attribute like this:
+Consider a User model with a validation for the name attribute like this:
<ruby>
class User < ActiveRecord::Base
- validates_presence_of :name
+ validates :name, :presence => true
end
</ruby>
@@ -697,7 +697,7 @@ activerecord.errors.models.user.attributes.name.blank
activerecord.errors.models.user.blank
activerecord.errors.messages.blank
errors.attributes.name.blank
-errors.messagges.blank
+errors.messages.blank
</ruby>
When your models are additionally using inheritance then the messages are looked up in the inheritance chain.
@@ -706,7 +706,7 @@ For example, you might have an Admin model inheriting from User:
<ruby>
class Admin < User
- validates_presence_of :name
+ validates :name, :presence => true
end
</ruby>
@@ -719,7 +719,7 @@ activerecord.errors.models.user.attributes.title.blank
activerecord.errors.models.user.blank
activerecord.errors.messages.blank
errors.attributes.title.blank
-errors.messagges.blank
+errors.messages.blank
</ruby>
This way you can provide special translations for various error messages at different points in your models inheritance chain and in the attributes, models, or default scopes.
@@ -733,27 +733,27 @@ So, for example, instead of the default error message +"can not be blank"+ you c
* +count+, where available, can be used for pluralization if present:
|_. validation |_.with option |_.message |_.interpolation|
-| validates_confirmation_of | - | :confirmation | -|
-| validates_acceptance_of | - | :accepted | -|
-| validates_presence_of | - | :blank | -|
-| validates_length_of | :within, :in | :too_short | count|
-| validates_length_of | :within, :in | :too_long | count|
-| validates_length_of | :is | :wrong_length | count|
-| validates_length_of | :minimum | :too_short | count|
-| validates_length_of | :maximum | :too_long | count|
-| validates_uniqueness_of | - | :taken | -|
-| validates_format_of | - | :invalid | -|
-| validates_inclusion_of | - | :inclusion | -|
-| validates_exclusion_of | - | :exclusion | -|
-| validates_associated | - | :invalid | -|
-| validates_numericality_of | - | :not_a_number | -|
-| validates_numericality_of | :greater_than | :greater_than | count|
-| validates_numericality_of | :greater_than_or_equal_to | :greater_than_or_equal_to | count|
-| validates_numericality_of | :equal_to | :equal_to | count|
-| validates_numericality_of | :less_than | :less_than | count|
-| validates_numericality_of | :less_than_or_equal_to | :less_than_or_equal_to | count|
-| validates_numericality_of | :odd | :odd | -|
-| validates_numericality_of | :even | :even | -|
+| confirmation | - | :confirmation | -|
+| acceptance | - | :accepted | -|
+| presence | - | :blank | -|
+| length | :within, :in | :too_short | count|
+| length | :within, :in | :too_long | count|
+| length | :is | :wrong_length | count|
+| length | :minimum | :too_short | count|
+| length | :maximum | :too_long | count|
+| uniqueness | - | :taken | -|
+| format | - | :invalid | -|
+| inclusion | - | :inclusion | -|
+| exclusion | - | :exclusion | -|
+| associated | - | :invalid | -|
+| numericality | - | :not_a_number | -|
+| numericality | :greater_than | :greater_than | count|
+| numericality | :greater_than_or_equal_to | :greater_than_or_equal_to | count|
+| numericality | :equal_to | :equal_to | count|
+| numericality | :less_than | :less_than | count|
+| numericality | :less_than_or_equal_to | :less_than_or_equal_to | count|
+| numericality | :odd | :odd | -|
+| numericality | :even | :even | -|
h5. Translations for the Active Record +error_messages_for+ Helper
@@ -830,7 +830,7 @@ In other contexts you might want to change this behaviour, though. E.g. the defa
<ruby>
module I18n
- def just_raise_that_exception(*args)
+ def self.just_raise_that_exception(*args)
raise args.first
end
end
@@ -889,8 +889,3 @@ fn1. Or, to quote "Wikipedia":http://en.wikipedia.org/wiki/Internationalization_
fn2. Other backends might allow or require to use other formats, e.g. a GetText backend might allow to read GetText files.
fn3. One of these reasons is that we don't want to imply any unnecessary load for applications that do not need any I18n capabilities, so we need to keep the I18n library as simple as possible for English. Another reason is that it is virtually impossible to implement a one-fits-all solution for all problems related to I18n for all existing languages. So a solution that allows us to exchange the entire implementation easily is appropriate anyway. This also makes it much easier to experiment with custom features and extensions.
-
-
-h3. Changelog
-
-"Lighthouse ticket":http://rails.lighthouseapp.com/projects/16213/tickets/23
diff --git a/railties/guides/source/index.html.erb b/railties/guides/source/index.html.erb
index 6b897e3a6a..84fbc53a69 100644
--- a/railties/guides/source/index.html.erb
+++ b/railties/guides/source/index.html.erb
@@ -31,7 +31,7 @@ Ruby on Rails Guides
<div id="subCol">
<dl>
<dd class="warning">Rails Guides are a result of the ongoing <a href="http://hackfest.rubyonrails.org">Guides hackfest</a>, and a work in progress.</dd>
- <dd class="ticket">Guides marked with this icon are currently being worked on. While they might still be useful to you, they may contain incomplete information and even errors. You can help by reviewing them and posting your comments and corrections at the respective Lighthouse ticket.</dd>
+ <dd class="work-in-progress">Guides marked with this icon are currently being worked on. While they might still be useful to you, they may contain incomplete information and even errors. You can help by reviewing them and posting your comments and corrections to the author.</dd>
</dl>
</div>
<% end %>
@@ -71,7 +71,7 @@ Ruby on Rails Guides
<p>This guide covers the basic layout features of Action Controller and Action View, including rendering and redirecting, using content_for blocks, and working with partials.</p>
<% end %>
-<%= guide("Action View Form Helpers", 'form_helpers.html', :ticket => 1) do %>
+<%= guide("Action View Form Helpers", 'form_helpers.html', :work_in_progress => true) do %>
<p>Guide to using built-in Form helpers.</p>
<% end %>
</dl>
@@ -100,11 +100,11 @@ Ruby on Rails Guides
<p>This guide covers how to add internationalization to your applications. Your application will be able to translate content to different languages, change pluralization rules, use correct date formats for each country and so on.</p>
<% end %>
-<%= guide("Action Mailer Basics", 'action_mailer_basics.html', :ticket => 25) do %>
+<%= guide("Action Mailer Basics", 'action_mailer_basics.html', :work_in_progress => true) do %>
<p>This guide describes how to use Action Mailer to send and receive emails.</p>
<% end %>
-<%= guide("Testing Rails Applications", 'testing.html', :ticket => 8) do %>
+<%= guide("Testing Rails Applications", 'testing.html', :work_in_progress => true) do %>
<p>This is a rather comprehensive guide to doing both unit and functional tests in Rails. It covers everything from &quot;What is a test?&quot; to the testing APIs. Enjoy.</p>
<% end %>
@@ -124,11 +124,11 @@ Ruby on Rails Guides
<p>This guide covers the basic configuration settings for a Rails application.</p>
<% end %>
-<%= guide("Rails Command Line Tools and Rake tasks", 'command_line.html', :ticket => 29) do %>
+<%= guide("Rails Command Line Tools and Rake tasks", 'command_line.html', :work_in_progress => true) do %>
<p>This guide covers the command line tools and rake tasks provided by Rails.</p>
<% end %>
-<%= guide("Caching with Rails", 'caching_with_rails.html', :ticket => 10) do %>
+<%= guide("Caching with Rails", 'caching_with_rails.html', :work_in_progress => true) do %>
<p>Various caching techniques provided by Rails.</p>
<% end %>
</dl>
@@ -136,7 +136,7 @@ Ruby on Rails Guides
<h3>Extending Rails</h3>
<dl>
- <%= guide("The Basics of Creating Rails Plugins", 'plugins.html', :ticket => 32) do %>
+ <%= guide("The Basics of Creating Rails Plugins", 'plugins.html', :work_in_progress => true) do %>
<p>This guide covers how to build a plugin to extend the functionality of Rails.</p>
<% end %>
diff --git a/railties/guides/source/initialization.textile b/railties/guides/source/initialization.textile
index 3e02bc0158..4cc5f3843f 100644
--- a/railties/guides/source/initialization.textile
+++ b/railties/guides/source/initialization.textile
@@ -141,7 +141,7 @@ Here the only two gems we need are +rails+ and +sqlite3-ruby+, so it seems. This
* activesupport-3.0.0.gem
* arel-0.4.0.gem
* builder-2.1.2.gem
-* bundler-1.0.0.gem
+* bundler-1.0.3.gem
* erubis-2.6.6.gem
* i18n-0.4.1.gem
* mail-2.2.5.gem
@@ -1479,10 +1479,10 @@ Next, the Railtie itself is defined:
require "action_view/railties/log_subscriber"
log_subscriber ActionView::Railties::LogSubscriber.new
- initializer "action_view.cache_asset_timestamps" do |app|
+ initializer "action_view.cache_asset_id" do |app|
unless app.config.cache_classes
- ActionView.base_hook do
- ActionView::Helpers::AssetTagHelper.cache_asset_timestamps = false
+ ActiveSupport.on_load(:action_view) do
+ ActionView::Helpers::AssetTagHelper::AssetPaths.cache_asset_ids = false
end
end
end
@@ -1492,7 +1492,7 @@ Next, the Railtie itself is defined:
The +ActionView::LogSubscriber+ sets up a method called +render_template+ which is called when a template is rendered. TODO: Templates only or partials and layouts also? I would imagine these fall under the templates category, but there needs to research to ensure this is correct.
-The sole initializer defined here, _action_view.cache_asset_timestamps_ is responsible for caching the timestamps on the ends of your assets. If you've ever seen a link generated by +image_tag+ or +stylesheet_link_tag+ you would know that I mean that this timestamp is the number after the _?_ in this example: _/javascripts/prototype.js?1265442620_. This initializer will do nothing if +cache_classes+ is set to false in any of your application's configuration. TODO: Elaborate.
+The sole initializer defined here, _action_view.cache_asset_ids_ is responsible for caching the timestamps on the ends of your assets. If you've ever seen a link generated by +image_tag+ or +stylesheet_link_tag+ you would know that I mean that this timestamp is the number after the _?_ in this example: _/javascripts/prototype.js?1265442620_. This initializer will do nothing if +cache_classes+ is set to false in any of your application's configuration. TODO: Elaborate.
h4. Action Mailer Railtie
@@ -3003,7 +3003,7 @@ The +I18n::Railtie+ also defines an +after_initialize+ which we will return to l
**Action View Initializers **
-* action_view.cache_asset_timestamps
+* action_view.cache_asset_ids
**Action Mailer Initializers **
diff --git a/railties/guides/source/layout.html.erb b/railties/guides/source/layout.html.erb
index f0aa227c7e..bb62506f04 100644
--- a/railties/guides/source/layout.html.erb
+++ b/railties/guides/source/layout.html.erb
@@ -8,13 +8,10 @@
<title><%= yield(:page_title) || 'Ruby on Rails guides' %></title>
<link rel="stylesheet" type="text/css" href="stylesheets/style.css" />
-<link rel="stylesheet" type="text/css" href="stylesheets/syntax.css" />
<link rel="stylesheet" type="text/css" href="stylesheets/print.css" media="print" />
-<script type="text/javascript" src="javascripts/guides.js"></script>
-<script type="text/javascript" src="javascripts/code_highlighter.js"></script>
-<script type="text/javascript" src="javascripts/highlighters.js"></script>
-
+<link rel="stylesheet" type="text/css" href="stylesheets/syntaxhighlighter/shCore.css" />
+<link rel="stylesheet" type="text/css" href="stylesheets/syntaxhighlighter/shThemeRailsGuides.css" />
</head>
<body class="guide">
<% if @edge %>
@@ -109,6 +106,31 @@
<div class="wrapper">
<div id="mainCol">
<%= yield.html_safe %>
+
+ <h3>Feedback</h3>
+ <p>
+ You're encouraged to help in keeping the quality of this guide.
+ </p>
+ <p>
+ If you see any typos or factual errors you are confident to
+ patch please clone <%= link_to 'docrails', 'https://github.com/lifo/docrails' %>
+ and push the change yourself. That branch of Rails has public write access.
+ Commits are still reviewed, but that happens after you've submitted your
+ contribution. <%= link_to 'docrails', 'https://github.com/lifo/docrails' %> is
+ cross-merged with master periodically.
+ </p>
+ <p>
+ You may also find incomplete content, or stuff that is not up to date.
+ Please do add any missing documentation for master. Check the
+ <%= link_to 'Ruby on Rails Guides Guidelines', 'ruby_on_rails_guides_guidelines.html' %>
+ guide for style and conventions.
+ </p>
+ <p>
+ Issues may also be reported <%= link_to 'in Github', 'https://github.com/lifo/docrails/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' %>.
+ </p>
</div>
</div>
</div>
@@ -120,5 +142,15 @@
<p>"Rails", "Ruby on Rails", and the Rails logo are trademarks of David Heinemeier Hansson. All rights reserved.</p>
</div>
</div>
+
+ <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">
+ SyntaxHighlighter.all()
+ </script>
</body>
</html>
diff --git a/railties/guides/source/layouts_and_rendering.textile b/railties/guides/source/layouts_and_rendering.textile
index 50c5986a64..80a1fdd38d 100644
--- a/railties/guides/source/layouts_and_rendering.textile
+++ b/railties/guides/source/layouts_and_rendering.textile
@@ -90,7 +90,7 @@ If we want to display the properties of all the books in our view, we can do so
<%= link_to 'New book', new_book_path %>
</ruby>
-NOTE: The actual rendering is done by subclasses of +ActionView::TemplateHandlers+. This guide does not dig into that process, but it's important to know that the file extension on your view controls the choice of template handler. In Rails 2, the standard extensions are +.erb+ for ERB (HTML with embedded Ruby), +.rjs+ for RJS (javascript with embedded ruby) and +.builder+ for Builder (XML generator).
+NOTE: The actual rendering is done by subclasses of +ActionView::TemplateHandlers+. This guide does not dig into that process, but it's important to know that the file extension on your view controls the choice of template handler. In Rails 2, the standard extensions are +.erb+ for ERB (HTML with embedded Ruby), +.rjs+ for RJS (JavaScript with embedded ruby) and +.builder+ for Builder (XML generator).
h4. Using +render+
@@ -252,7 +252,7 @@ render :inline =>
h5. Using +render+ with +:update+
-You can also render javascript-based page updates inline using the +:update+ option to +render+:
+You can also render JavaScript-based page updates inline using the +:update+ option to +render+:
<ruby>
render :update do |page|
@@ -260,7 +260,7 @@ render :update do |page|
end
</ruby>
-WARNING: Placing javascript updates in your controller may seem to streamline small updates, but it defeats the MVC orientation of Rails and will make it harder for other developers to follow the logic of your project. We recommend using a separate rjs template instead, no matter how small the update.
+WARNING: Placing JavaScript updates in your controller may seem to streamline small updates, but it defeats the MVC orientation of Rails and will make it harder for other developers to follow the logic of your project. We recommend using a separate RJS template instead, no matter how small the update.
h5. Rendering Text
@@ -276,7 +276,7 @@ NOTE: By default, if you use the +:text+ option, the text is rendered without us
h5. Rendering JSON
-JSON is a javascript data format used by many AJAX libraries. Rails has built-in support for converting objects to JSON and rendering that JSON back to the browser:
+JSON is a JavaScript data format used by many AJAX libraries. Rails has built-in support for converting objects to JSON and rendering that JSON back to the browser:
<ruby>
render :json => @product
@@ -655,7 +655,7 @@ I'll discuss each of these in turn.
h4. Asset Tags
-Asset tags provide methods for generating HTML that links views to assets like images, videos, audio, javascript, stylesheets, and feeds. There are six types of include tag:
+Asset tags provide methods for generating HTML that links views to assets like images, videos, audio, JavaScript, stylesheets, and feeds. There are six types of include tag:
* +auto_discovery_link_tag+
* +javascript_include_tag+
@@ -715,7 +715,7 @@ The +defaults+ option loads the Prototype and Scriptaculous libraries:
<%= javascript_include_tag :defaults %>
</erb>
-The +all+ option loads every javascript file in +public/javascripts+, starting with the Prototype and Scriptaculous libraries:
+The +all+ option loads every JavaScript file in +public/javascripts+, starting with the Prototype and Scriptaculous libraries:
<erb>
<%= javascript_include_tag :all %>
@@ -727,7 +727,7 @@ You can supply the +:recursive+ option to load files in subfolders of +public/ja
<%= javascript_include_tag :all, :recursive => true %>
</erb>
-If you're loading multiple javascript files, you can create a better user experience by combining multiple files into a single download. To make this happen in production, specify +:cache => true+ in your +javascript_include_tag+:
+If you're loading multiple JavaScript files, you can create a better user experience by combining multiple files into a single download. To make this happen in production, specify +:cache => true+ in your +javascript_include_tag+:
<erb>
<%= javascript_include_tag "main", "columns", :cache => true %>
@@ -962,7 +962,7 @@ The result of rendering this page into the supplied layout would be this HTML:
</html>
</erb>
-The +content_for+ method is very helpful when your layout contains distinct regions such as sidebars and footers that should get their own blocks of content inserted. It's also useful for inserting tags that load page-specific javascript or css files into the header of an otherwise generic layout.
+The +content_for+ method is very helpful when your layout contains distinct regions such as sidebars and footers that should get their own blocks of content inserted. It's also useful for inserting tags that load page-specific JavaScript or css files into the header of an otherwise generic layout.
h4. Using Partials
@@ -970,7 +970,7 @@ Partial templates - usually just called "partials" - are another device for brea
h5. Naming Partials
-To render a partial as part of a view, you use the +render+ method within the view, and include the +:partial+ option:
+To render a partial as part of a view, you use the +render+ method within the view:
<ruby>
<%= render "menu" %>
@@ -1185,17 +1185,15 @@ On pages generated by +NewsController+, you want to hide the top menu and add a
<div id="right_menu">Right menu items here</div>
<%= yield(:news_content) or yield %>
<% end %>
-<%= render :file => 'layouts/application' %>
+<%= render :template => 'layouts/application' %>
</erb>
That's it. The News views will use the new layout, hiding the top menu and adding a new right menu inside the "content" div.
-There are several ways of getting similar results with different sub-templating schemes using this technique. Note that there is no limit in nesting levels. One can use the +ActionView::render+ method via +render :file => 'layouts/news'+ to base a new layout on the News layout. If you are sure you will not subtemplate the +News+ layout, you can replace the +yield(:news_content) or yield+ with simply +yield+.
+There are several ways of getting similar results with different sub-templating schemes using this technique. Note that there is no limit in nesting levels. One can use the +ActionView::render+ method via +render :template => 'layouts/news'+ to base a new layout on the News layout. If you are sure you will not subtemplate the +News+ layout, you can replace the +yield(:news_content) or yield+ with simply +yield+.
h3. Changelog
-"Lighthouse ticket":http://rails.lighthouseapp.com/projects/16213-rails-guides/tickets/15
-
* April 4, 2010: Fixed document to validate XHTML 1.0 Strict. "Jaime Iniesta":http://jaimeiniesta.com
* January 25, 2010: Rails 3.0 Update by "Mikel Lindsaar":credits.html#raasdnil
* December 27, 2008: Merge patch from Rodrigo Rosenfeld Rosas covering subtemplates
diff --git a/railties/guides/source/migrations.textile b/railties/guides/source/migrations.textile
index 89aa007279..0d13fbc10a 100644
--- a/railties/guides/source/migrations.textile
+++ b/railties/guides/source/migrations.textile
@@ -546,7 +546,7 @@ Schema files are also useful if you want a quick look at what attributes an Acti
h4. Types of Schema Dumps
-There are two ways to dump the schema. This is set in +config/environment.rb+ by the +config.active_record.schema_format+ setting, which may be either +:sql+ or +:ruby+.
+There are two ways to dump the schema. This is set in +config/application.rb+ by the +config.active_record.schema_format+ setting, which may be either +:sql+ or +:ruby+.
If +:ruby+ is selected then the schema is stored in +db/schema.rb+. If you look at this file you'll find that it looks an awful lot like one very big migration:
@@ -584,13 +584,11 @@ h3. Active Record and Referential Integrity
The Active Record way claims that intelligence belongs in your models, not in the database. As such, features such as triggers or foreign key constraints, which push some of that intelligence back into the database, are not heavily used.
-Validations such as +validates_uniqueness_of+ are one way in which models can enforce data integrity. The +:dependent+ option on associations allows models to automatically destroy child objects when the parent is destroyed. Like anything which operates at the application level these cannot guarantee referential integrity and so some people augment them with foreign key constraints.
+Validations such as +validates :foreign_key, :uniqueness => true+ are one way in which models can enforce data integrity. The +:dependent+ option on associations allows models to automatically destroy child objects when the parent is destroyed. Like anything which operates at the application level these cannot guarantee referential integrity and so some people augment them with foreign key constraints.
Although Active Record does not provide any tools for working directly with such features, the +execute+ method can be used to execute arbitrary SQL. There are also a number of plugins such as "foreign_key_migrations":http://github.com/harukizaemon/redhillonrails/tree/master/foreign_key_migrations/ which add foreign key support to Active Record (including support for dumping foreign keys in +db/schema.rb+).
h3. Changelog
-"Lighthouse ticket":http://rails.lighthouseapp.com/projects/16213-rails-guides/tickets/6
-
* July 15, 2010: minor typos corrected by "Jaime Iniesta":http://jaimeiniesta.com
* September 14, 2008: initial version by "Frederick Cheung":credits.html#fcheung
diff --git a/railties/guides/source/performance_testing.textile b/railties/guides/source/performance_testing.textile
index 9dda6d420a..41bdd27e9b 100644
--- a/railties/guides/source/performance_testing.textile
+++ b/railties/guides/source/performance_testing.textile
@@ -524,7 +524,5 @@ Rails has been lucky to have two startups dedicated to Rails specific performanc
h3. Changelog
-"Lighthouse ticket":http://rails.lighthouseapp.com/projects/16213-rails-guides/tickets/4
-
* January 9, 2009: Complete rewrite by "Pratik":credits.html#lifo
* September 6, 2008: Initial version by Matthew Bergman
diff --git a/railties/guides/source/plugins.textile b/railties/guides/source/plugins.textile
index c04c7b9406..cb43282ace 100644
--- a/railties/guides/source/plugins.textile
+++ b/railties/guides/source/plugins.textile
@@ -602,8 +602,8 @@ This is just a simple test to make sure the class is being loaded correctly. Af
%w{ models }.each do |dir|
path = File.join(File.dirname(__FILE__), 'app', dir)
$LOAD_PATH << path
- ActiveSupport::Dependencies.load_paths << path
- ActiveSupport::Dependencies.load_once_paths.delete(path)
+ ActiveSupport::Dependencies.autoload_paths << path
+ ActiveSupport::Dependencies.autoload_once_paths.delete(path)
end
</ruby>
@@ -669,8 +669,8 @@ This is just a simple test to make sure the controller is being loaded correctly
%w{ models controllers }.each do |dir|
path = File.join(File.dirname(__FILE__), 'app', dir)
$LOAD_PATH << path
- ActiveSupport::Dependencies.load_paths << path
- ActiveSupport::Dependencies.load_once_paths.delete(path)
+ ActiveSupport::Dependencies.autoload_paths << path
+ ActiveSupport::Dependencies.autoload_once_paths.delete(path)
end
</ruby>
@@ -715,8 +715,8 @@ This is just a simple test to make sure the helper is being loaded correctly. A
%w{ models controllers helpers }.each do |dir|
path = File.join(File.dirname(__FILE__), 'app', dir)
$LOAD_PATH << path
- ActiveSupport::Dependencies.load_paths << path
- ActiveSupport::Dependencies.load_once_paths.delete(path)
+ ActiveSupport::Dependencies.autoload_paths << path
+ ActiveSupport::Dependencies.autoload_once_paths.delete(path)
end
</ruby>
@@ -802,7 +802,7 @@ You can also see if your routes work by running +rake routes+ from your app dire
h3. Generators
-Many plugins ship with generators. When you created the plugin above, you specified the +--with-generator+ option, so you already have the generator stubs in 'vendor/plugins/yaffle/generators/yaffle'.
+Many plugins ship with generators. When you created the plugin above, you specified the +--generator+ option, so you already have the generator stubs in 'vendor/plugins/yaffle/generators/yaffle'.
Building generators is a complex topic unto itself and this section will cover one small aspect of generators: generating a simple text file.
@@ -1436,8 +1436,8 @@ require "yaffle/routing"
%w{ models controllers helpers }.each do |dir|
path = File.join(File.dirname(__FILE__), 'app', dir)
$LOAD_PATH << path
- ActiveSupport::Dependencies.load_paths << path
- ActiveSupport::Dependencies.load_once_paths.delete(path)
+ ActiveSupport::Dependencies.autoload_paths << path
+ ActiveSupport::Dependencies.autoload_once_paths.delete(path)
end
# optionally:
@@ -1513,7 +1513,5 @@ The final plugin should have a directory structure that looks something like thi
h3. Changelog
-"Lighthouse ticket":http://rails.lighthouseapp.com/projects/16213/tickets/32-update-plugins-guide
-
* April 4, 2010: Fixed document to validate XHTML 1.0 Strict. "Jaime Iniesta":http://jaimeiniesta.com
* November 17, 2008: Major revision by Jeff Dean
diff --git a/railties/guides/source/rails_application_templates.textile b/railties/guides/source/rails_application_templates.textile
index bc7b151dfe..d4b887ad02 100644
--- a/railties/guides/source/rails_application_templates.textile
+++ b/railties/guides/source/rails_application_templates.textile
@@ -233,6 +233,4 @@ git :commit => "-a -m 'Initial commit'"
h3. Changelog
-"Lighthouse ticket":http://rails.lighthouseapp.com/projects/16213-rails-guides/tickets/78
-
* April 29, 2009: Initial version by "Pratik":credits.html#lifo
diff --git a/railties/guides/source/rails_on_rack.textile b/railties/guides/source/rails_on_rack.textile
index eaebb05f17..f17e9b4798 100644
--- a/railties/guides/source/rails_on_rack.textile
+++ b/railties/guides/source/rails_on_rack.textile
@@ -237,7 +237,5 @@ h4. Understanding Middlewares
h3. Changelog
-"Lighthouse ticket":http://rails.lighthouseapp.com/projects/16213-rails-guides/tickets/58
-
* February 7, 2009: Second version by "Pratik":credits.html#lifo
* January 11, 2009: First version by "Pratik":credits.html#lifo
diff --git a/railties/guides/source/routing.textile b/railties/guides/source/routing.textile
index a8a8ee58ec..2f5c88b8c3 100644
--- a/railties/guides/source/routing.textile
+++ b/railties/guides/source/routing.textile
@@ -153,7 +153,7 @@ h4. Controller Namespaces and Routing
You may wish to organize groups of controllers under a namespace. Most commonly, you might group a number of administrative controllers under an +Admin::+ namespace. You would place these controllers under the +app/controllers/admin+ directory, and you can group them together in your router:
<ruby>
-namespace "admin" do
+namespace :admin do
resources :posts, :comments
end
</ruby>
@@ -194,7 +194,7 @@ end
or, for a single case
<ruby>
-resources :posts, :path => "/admin"
+resources :posts, :path => "/admin/posts"
</ruby>
In each of these cases, the named routes remain the same as if you did not use +scope+. In the last case, the following paths map to +PostsController+:
@@ -436,6 +436,26 @@ match 'exit' => 'sessions#destroy', :as => :logout
This will create +logout_path+ and +logout_url+ as named helpers in your application. Calling +logout_path+ will return +/exit+
+h4. HTTP Verb Constraints
+
+You can use the +:via+ option to constrain the request to one or more HTTP methods:
+
+<ruby>
+match 'photos/show' => 'photos#show', :via => :get
+</ruby>
+
+There is a shorthand version of this as well:
+
+<ruby>
+get 'photos/show'
+</ruby>
+
+You can also permit more than one verb to a single route:
+
+<ruby>
+match 'photos/show' => 'photos#show', :via => [:get, :post]
+</ruby>
+
h4. Segment Constraints
You can use the +:constraints+ option to enforce a format for a dynamic segment:
@@ -478,7 +498,7 @@ match "photos", :constraints => {:subdomain => "admin"}
You can also specify constrains in a block form:
<ruby>
-namespace "admin" do
+namespace :admin do
constraints :subdomain => "admin" do
resources :photos
end
@@ -833,8 +853,6 @@ assert_routing({ :path => "photos", :method => :post }, { :controller => "photos
h3. Changelog
-"Lighthouse ticket":http://rails.lighthouseapp.com/projects/16213-rails-guides/tickets/3
-
* April 10, 2010: Updated guide to remove outdated and superfluous information, and to provide information about new features, by "Yehuda Katz":http://www.yehudakatz.com
* April 2, 2010: Updated guide to match new Routing DSL in Rails 3, by "Rizwan Reza":http://www.rizwanreza.com/
* Febuary 1, 2010: Modifies the routing documentation to match new routing DSL in Rails 3, by Prem Sichanugrist
diff --git a/railties/guides/source/security.textile b/railties/guides/source/security.textile
index 4656cf4e40..528c8861d4 100644
--- a/railties/guides/source/security.textile
+++ b/railties/guides/source/security.textile
@@ -166,7 +166,7 @@ end
The section about session fixation introduced the problem of maintained sessions. An attacker maintaining a session every five minutes can keep the session alive forever, although you are expiring sessions. A simple solution for this would be to add a created_at column to the sessions table. Now you can delete sessions that were created a long time ago. Use this line in the sweep method above:
<ruby>
-delete_all "updated_at < '#{time.to_s(:db)}' OR
+delete_all "updated_at < '#{time.ago.to_s(:db)}' OR
created_at < '#{2.days.ago.to_s(:db)}'"
</ruby>
@@ -550,7 +550,7 @@ Ruby uses a slightly different approach than many other languages to match the e
<ruby>
class File < ActiveRecord::Base
- validates_format_of :name, :with => /^[\w\.\-\+]+$/
+ validates :name, :format => /^[\w\.\-\+]+$/
end
</ruby>
@@ -979,6 +979,4 @@ The security landscape shifts and it is important to keep up to date, because mi
h3. Changelog
-"Lighthouse ticket":http://rails.lighthouseapp.com/projects/16213-rails-guides/tickets/7
-
* November 1, 2008: First approved version by Heiko Webers
diff --git a/railties/guides/source/testing.textile b/railties/guides/source/testing.textile
index 043a2462b4..c292a5d83b 100644
--- a/railties/guides/source/testing.textile
+++ b/railties/guides/source/testing.textile
@@ -315,7 +315,7 @@ Now to get this test to pass we can add a model level validation for the _title_
<ruby>
class Post < ActiveRecord::Base
- validates_presence_of :title
+ validates :title, :presence => true
end
</ruby>
@@ -940,8 +940,6 @@ The built-in +test/unit+ based testing is not the only way to test Rails applica
h3. Changelog
-"Lighthouse ticket":http://rails.lighthouseapp.com/projects/16213-rails-guides/tickets/8
-
* April 4, 2010: Fixed document to validate XHTML 1.0 Strict. "Jaime Iniesta":http://jaimeiniesta.com
* November 13, 2008: Revised based on feedback from Pratik Naik by "Akshay Surve":credits.html#asurve (not yet approved for publication)
* October 14, 2008: Edit and formatting pass by "Mike Gunderloy":credits.html#mgunderloy (not yet approved for publication)
diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb
index d13356ab4d..182068071d 100644
--- a/railties/lib/rails/application.rb
+++ b/railties/lib/rails/application.rb
@@ -35,7 +35,6 @@ module Rails
#
class Application < Engine
autoload :Bootstrap, 'rails/application/bootstrap'
- autoload :Configurable, 'rails/application/configurable'
autoload :Configuration, 'rails/application/configuration'
autoload :Finisher, 'rails/application/finisher'
autoload :Railties, 'rails/application/railties'
@@ -147,7 +146,7 @@ module Rails
middleware.use ::Rack::Cache, rack_cache if rack_cache
middleware.use ::ActionDispatch::Static, config.static_asset_paths if config.serve_static_assets
- middleware.use ::Rack::Lock if !config.allow_concurrency
+ middleware.use ::Rack::Lock unless config.allow_concurrency
middleware.use ::Rack::Runtime
middleware.use ::Rails::Rack::Logger
middleware.use ::ActionDispatch::ShowExceptions, config.consider_all_requests_local if config.action_dispatch.show_exceptions
diff --git a/railties/lib/rails/backtrace_cleaner.rb b/railties/lib/rails/backtrace_cleaner.rb
index bedefaa51c..36fd9aea19 100644
--- a/railties/lib/rails/backtrace_cleaner.rb
+++ b/railties/lib/rails/backtrace_cleaner.rb
@@ -22,7 +22,7 @@ module Rails
gems_paths = (Gem.path + [Gem.default_dir]).uniq.map!{ |p| Regexp.escape(p) }
return if gems_paths.empty?
- gems_regexp = %r{(#{gems_paths.join('|')})/gems/([^/]+)-([\w\.]+)/(.*)}
+ gems_regexp = %r{(#{gems_paths.join('|')})/gems/([^/]+)-([\w.]+)/(.*)}
add_filter { |line| line.sub(gems_regexp, '\2 (\3) \4') }
end
end
diff --git a/railties/lib/rails/cli.rb b/railties/lib/rails/cli.rb
index 1260772605..2b32f7edf1 100644
--- a/railties/lib/rails/cli.rb
+++ b/railties/lib/rails/cli.rb
@@ -5,10 +5,12 @@ require 'rails/script_rails_loader'
# the rest of this script is not run.
Rails::ScriptRailsLoader.exec_script_rails!
-railties_path = File.expand_path('../../lib', __FILE__)
-$:.unshift(railties_path) if File.directory?(railties_path) && !$:.include?(railties_path)
-
require 'rails/ruby_version_check'
Signal.trap("INT") { puts; exit }
-require 'rails/commands/application'
+if ARGV.first == 'plugin'
+ ARGV.shift
+ require 'rails/commands/plugin_new'
+else
+ require 'rails/commands/application'
+end
diff --git a/railties/lib/rails/commands.rb b/railties/lib/rails/commands.rb
index e3aa6d7c3e..338565247f 100644
--- a/railties/lib/rails/commands.rb
+++ b/railties/lib/rails/commands.rb
@@ -12,14 +12,19 @@ command = aliases[command] || command
case command
when 'generate', 'destroy', 'plugin'
- require APP_PATH
- Rails.application.require_environment!
+ if command == 'plugin' && ARGV.first == 'new'
+ require "rails/commands/plugin_new"
+ else
+ require APP_PATH
+ Rails.application.require_environment!
- if defined?(ENGINE_PATH)
- engine = Rails.application.railties.engines.find { |r| r.root.to_s == ENGINE_PATH }
- Rails.application = engine
+ if defined?(ENGINE_PATH)
+ engine = Rails.application.railties.engines.find { |r| r.root.to_s == ENGINE_PATH }
+ Rails.application = engine
+ end
+
+ require "rails/commands/#{command}"
end
- require "rails/commands/#{command}"
when 'benchmarker', 'profiler'
require APP_PATH
diff --git a/railties/lib/rails/commands/plugin_new.rb b/railties/lib/rails/commands/plugin_new.rb
new file mode 100644
index 0000000000..8baa8ebfd4
--- /dev/null
+++ b/railties/lib/rails/commands/plugin_new.rb
@@ -0,0 +1,10 @@
+if ARGV.first != "new"
+ ARGV[0] = "--help"
+else
+ ARGV.shift
+end
+
+require 'rails/generators'
+require 'rails/generators/rails/plugin_new/plugin_new_generator'
+
+Rails::Generators::PluginNewGenerator.start
diff --git a/railties/lib/rails/configuration.rb b/railties/lib/rails/configuration.rb
index 8369795e71..66fab0a760 100644
--- a/railties/lib/rails/configuration.rb
+++ b/railties/lib/rails/configuration.rb
@@ -1,5 +1,6 @@
require 'active_support/deprecation'
require 'active_support/ordered_options'
+require 'active_support/core_ext/hash/deep_dup'
require 'rails/paths'
require 'rails/rack'
@@ -51,6 +52,13 @@ module Rails
@colorize_logging = true
end
+ def initialize_copy(source)
+ @aliases = @aliases.deep_dup
+ @options = @options.deep_dup
+ @fallbacks = @fallbacks.deep_dup
+ @templates = @templates.dup
+ end
+
def method_missing(method, *args)
method = method.to_s.sub(/=$/, '').to_sym
diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb
index e9ce9610b8..85fa4424c4 100644
--- a/railties/lib/rails/engine.rb
+++ b/railties/lib/rails/engine.rb
@@ -189,17 +189,14 @@ module Rails
# served by default. You should choose one of the two following strategies:
#
# * enable serving static files by setting config.serve_static_assets to true
- # * symlink engines' public directories in application's public directory by running
- # `rake ENGINE_NAME:install:assets`, where ENGINE_NAME is usually my_engine for the
- # examples above
+ # * copy engine's public files to application's public folder with rake ENGINE_NAME:install:assets, for example
+ # rake my_engine:install:assets
#
# == Engine name
#
- # There are some places where engine's name is used.
- #
+ # There are some places where engine's name is used:
# * routes: when you mount engine with mount(MyEngine::Engine => '/my_engine'), it's used as default :as option
- #
- # * rake tasks: engines have a few rake tasks. They are usually under my_engine namespace.
+ # * some of the rake tasks are based on engine name, e.g. my_engine:install:migrations, my_engine:install:assets
#
# Engine name is set by default based on class name. For MyEngine::Engine it will be my_engine_engine.
# You can change it manually it manually using engine_name method:
@@ -317,46 +314,36 @@ module Rails
#
# rake ENGINE_NAME:install:migrations
#
+ # Note that some of the migrations may be skipped if migration with the same name already exists
+ # in application. In such situation you must decide whether to leave that migration or rename the
+ # migration in application and rerun copying migrations.
+ #
# If your engine has migrations, you may also want to prepare data for the database in
# seeds.rb file. You can load that data using load_seed method, e.g.
#
# MyEngine::Engine.load_seed
#
class Engine < Railtie
- autoload :Configurable, "rails/engine/configurable"
autoload :Configuration, "rails/engine/configuration"
+ autoload :Railties, "rails/engine/railties"
class << self
attr_accessor :called_from, :isolated
+ alias :isolated? :isolated
alias :engine_name :railtie_name
def inherited(base)
unless base.abstract_railtie?
base.called_from = begin
# Remove the line number from backtraces making sure we don't leave anything behind
- call_stack = caller.map { |p| p.split(':')[0..-2].join(':') }
- File.dirname(call_stack.detect { |p| p !~ %r[railties[\w\-\.]*/lib/rails|rack[\w\-\.]*/lib/rack] })
+ call_stack = caller.map { |p| p.sub(/:\d+.*/, '') }
+ File.dirname(call_stack.detect { |p| p !~ %r[railties[\w.-]*/lib/rails|rack[\w.-]*/lib/rack] })
end
end
super
end
- def find_root_with_flag(flag, default=nil)
- root_path = self.called_from
-
- while root_path && File.directory?(root_path) && !File.exist?("#{root_path}/#{flag}")
- parent = File.dirname(root_path)
- root_path = parent != root_path && parent
- end
-
- root = File.exist?("#{root_path}/#{flag}") ? root_path : default
- raise "Could not find root path for #{self}" unless root
-
- RbConfig::CONFIG['host_os'] =~ /mswin|mingw/ ?
- Pathname.new(root).expand_path : Pathname.new(root).realpath
- end
-
def endpoint(endpoint = nil)
@endpoint = endpoint if endpoint
@endpoint
@@ -376,16 +363,14 @@ module Rails
_railtie
end
- define_method(:table_name_prefix) do
- "#{name}_"
+ unless mod.respond_to?(:table_name_prefix)
+ define_method(:table_name_prefix) do
+ "#{name}_"
+ end
end
end
end
end
-
- def isolated?
- !!isolated
- end
end
delegate :middleware, :root, :paths, :to => :config
@@ -509,7 +494,7 @@ module Rails
end
initializer :append_asset_paths do
- config.asset_path ||= "/#{engine_name}%s"
+ config.asset_path ||= "/#{railtie_name}%s"
public_path = paths["public"].first
if config.compiled_asset_path && File.exist?(public_path)
@@ -538,6 +523,12 @@ module Rails
next if self.is_a?(Rails::Application)
namespace railtie_name do
+ desc "Shortcut for running both rake #{railtie_name}:install:migrations and #{railtie_name}:install:assets"
+ task :install do
+ Rake::Task["#{railtie_name}:install:migrations"].invoke
+ Rake::Task["#{railtie_name}:install:assets"].invoke
+ end
+
namespace :install do
# TODO Add assets copying to this list
# TODO Skip this if there is no paths["db/migrate"] for the engine
@@ -546,6 +537,12 @@ module Rails
ENV["FROM"] = railtie_name
Rake::Task["railties:install:migrations"].invoke
end
+
+ desc "Copy assets from #{railtie_name} to application"
+ task :assets do
+ ENV["FROM"] = railtie_name
+ Rake::Task["railties:install:assets"].invoke
+ end
end
end
end
diff --git a/railties/lib/rails/engine/configuration.rb b/railties/lib/rails/engine/configuration.rb
index 7a07dcad7d..4f458b0aee 100644
--- a/railties/lib/rails/engine/configuration.rb
+++ b/railties/lib/rails/engine/configuration.rb
@@ -10,6 +10,7 @@ module Rails
def initialize(root=nil)
super()
@root = root
+ @generators = app_generators.dup
end
# Returns the middleware stack for the engine.
diff --git a/railties/lib/rails/generators.rb b/railties/lib/rails/generators.rb
index 240810b8bd..66c4088a68 100644
--- a/railties/lib/rails/generators.rb
+++ b/railties/lib/rails/generators.rb
@@ -228,6 +228,7 @@ module Rails
rails = groups.delete("rails")
rails.map! { |n| n.sub(/^rails:/, '') }
rails.delete("app")
+ rails.delete("plugin_new")
print_list("rails", rails)
hidden_namespaces.each {|n| groups.delete(n.to_s) }
@@ -301,6 +302,7 @@ module Rails
$LOAD_PATH.each do |base|
Dir[File.join(base, "{rails/generators,generators}", "**", "*_generator.rb")].each do |path|
begin
+ path = path.sub("#{base}/", "")
require path
rescue Exception => e
# No problem
diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb
new file mode 100644
index 0000000000..f5c626553c
--- /dev/null
+++ b/railties/lib/rails/generators/app_base.rb
@@ -0,0 +1,176 @@
+require 'digest/md5'
+require 'active_support/secure_random'
+require 'rails/version' unless defined?(Rails::VERSION)
+require 'rbconfig'
+require 'open-uri'
+require 'uri'
+
+module Rails
+ module Generators
+ class AppBase < Base
+ DATABASES = %w( mysql oracle postgresql sqlite3 frontbase ibm_db )
+ JAVASCRIPTS = %w( prototype jquery )
+
+ attr_accessor :rails_template
+ add_shebang_option!
+
+ argument :app_path, :type => :string
+
+ def self.add_shared_options_for(name)
+ class_option :builder, :type => :string, :aliases => "-b",
+ :desc => "Path to a #{name} builder (can be a filesystem path or URL)"
+
+ class_option :template, :type => :string, :aliases => "-m",
+ :desc => "Path to an #{name} template (can be a filesystem path or URL)"
+
+ class_option :skip_gemfile, :type => :boolean, :default => false,
+ :desc => "Don't create a Gemfile"
+
+ class_option :skip_git, :type => :boolean, :aliases => "-G", :default => false,
+ :desc => "Skip Git ignores and keeps"
+
+ class_option :skip_active_record, :type => :boolean, :aliases => "-O", :default => false,
+ :desc => "Skip Active Record files"
+
+ class_option :database, :type => :string, :aliases => "-d", :default => "sqlite3",
+ :desc => "Preconfigure for selected database (options: #{DATABASES.join('/')})"
+
+ class_option :javascript, :type => :string, :aliases => "-j", :default => "prototype",
+ :desc => "Preconfigure for selected javascript library (options: #{JAVASCRIPTS.join('/')})"
+
+ class_option :skip_javascript, :type => :boolean, :aliases => "-J", :default => false,
+ :desc => "Skip javascript files"
+
+ class_option :dev, :type => :boolean, :default => false,
+ :desc => "Setup the #{name} with Gemfile pointing to your Rails checkout"
+
+ class_option :edge, :type => :boolean, :default => false,
+ :desc => "Setup the #{name} with Gemfile pointing to Rails repository"
+
+ class_option :skip_test_unit, :type => :boolean, :aliases => "-T", :default => false,
+ :desc => "Skip Test::Unit files"
+
+ class_option :help, :type => :boolean, :aliases => "-h", :group => :rails,
+ :desc => "Show this help message and quit"
+ end
+
+ def initialize(*args)
+ @original_wd = Dir.pwd
+
+ super
+ end
+
+ protected
+
+ def builder
+ @builder ||= begin
+ if path = options[:builder]
+ if URI(path).is_a?(URI::HTTP)
+ contents = open(path, "Accept" => "application/x-thor-template") {|io| io.read }
+ else
+ contents = open(File.expand_path(path, @original_wd)) {|io| io.read }
+ end
+
+ prok = eval("proc { #{contents} }", TOPLEVEL_BINDING, path, 1)
+ instance_eval(&prok)
+ end
+
+ builder_class = get_builder_class
+ builder_class.send(:include, ActionMethods)
+ builder_class.new(self)
+ end
+ end
+
+ def build(meth, *args)
+ builder.send(meth, *args) if builder.respond_to?(meth)
+ end
+
+ def create_root
+ self.destination_root = File.expand_path(app_path, destination_root)
+ valid_const?
+
+ empty_directory '.'
+ set_default_accessors!
+ FileUtils.cd(destination_root) unless options[:pretend]
+ end
+
+ def apply_rails_template
+ apply rails_template if rails_template
+ rescue Thor::Error, LoadError, Errno::ENOENT => e
+ raise Error, "The template [#{rails_template}] could not be loaded. Error: #{e}"
+ end
+
+ def set_default_accessors!
+ self.rails_template = case options[:template]
+ when /^http:\/\//
+ options[:template]
+ when String
+ File.expand_path(options[:template], Dir.pwd)
+ else
+ options[:template]
+ end
+ end
+
+ def database_gemfile_entry
+ entry = ""
+ unless options[:skip_active_record]
+ entry = "gem '#{gem_for_database}'"
+ entry << ", :require => '#{require_for_database}'" if require_for_database
+ end
+ entry
+ end
+
+ def rails_gemfile_entry
+ if options.dev?
+ <<-GEMFILE
+gem 'rails', :path => '#{Rails::Generators::RAILS_DEV_PATH}'
+gem 'arel', :git => 'git://github.com/rails/arel.git'
+gem "rack", :git => "git://github.com/rack/rack.git"
+ GEMFILE
+ elsif options.edge?
+ <<-GEMFILE
+gem 'rails', :git => 'git://github.com/rails/rails.git'
+gem 'arel', :git => 'git://github.com/rails/arel.git'
+gem "rack", :git => "git://github.com/rack/rack.git"
+ GEMFILE
+ else
+ <<-GEMFILE
+gem 'rails', '#{Rails::VERSION::STRING}'
+
+# Bundle edge Rails instead:
+# gem 'rails', :git => 'git://github.com/rails/rails.git'
+# gem 'arel', :git => 'git://github.com/rails/arel.git'
+# gem "rack", :git => "git://github.com/rack/rack.git"
+ GEMFILE
+ end
+ end
+
+ def gem_for_database
+ # %w( mysql oracle postgresql sqlite3 frontbase ibm_db )
+ case options[:database]
+ when "oracle" then "ruby-oci8"
+ when "postgresql" then "pg"
+ when "sqlite3" then "sqlite3-ruby"
+ when "frontbase" then "ruby-frontbase"
+ when "mysql" then "mysql2"
+ else options[:database]
+ end
+ end
+
+ def require_for_database
+ case options[:database]
+ when "sqlite3" then "sqlite3"
+ end
+ end
+
+ def bundle_if_dev_or_edge
+ bundle_command = File.basename(Thor::Util.ruby_command).sub(/ruby/, 'bundle')
+ run "#{bundle_command} install" if dev_or_edge?
+ end
+
+ def dev_or_edge?
+ options.dev? || options.edge?
+ end
+ end
+ end
+end
diff --git a/railties/lib/rails/generators/named_base.rb b/railties/lib/rails/generators/named_base.rb
index 9131a19043..e0dde4360f 100644
--- a/railties/lib/rails/generators/named_base.rb
+++ b/railties/lib/rails/generators/named_base.rb
@@ -16,6 +16,14 @@ module Rails
parse_attributes! if respond_to?(:attributes)
end
+ no_tasks do
+ def template(source, *args, &block)
+ inside_template do
+ super
+ end
+ end
+ end
+
protected
attr_reader :file_name
alias :singular_name :file_name
@@ -23,16 +31,14 @@ module Rails
# Wrap block with namespace of current application
# if namespace exists and is not skipped
def module_namespacing(&block)
- inside_namespace do
- content = capture(&block)
- content = wrap_with_namespace(content) if namespaced?
- concat(content)
- end
+ content = capture(&block)
+ content = wrap_with_namespace(content) if namespaced?
+ concat(content)
end
def indent(content, multiplier = 2)
spaces = " " * multiplier
- content.each_line.map {|line| "#{spaces}#{line}" }.join("\n")
+ content = content.each_line.map {|line| "#{spaces}#{line}" }.join
end
def wrap_with_namespace(content)
@@ -40,12 +46,15 @@ module Rails
"module #{namespace.name}\n#{content}\nend\n"
end
- def inside_namespace
- @inside_namespace = true if namespaced?
- result = yield
- result
+ def inside_template
+ @inside_template = true
+ yield
ensure
- @inside_namespace = false
+ @inside_template = false
+ end
+
+ def inside_template?
+ @inside_template
end
def namespace
@@ -55,11 +64,7 @@ module Rails
end
def namespaced?
- !options[:skip_namespace] && !!namespace
- end
-
- def inside_namespace?
- @inside_namespace
+ !options[:skip_namespace] && namespace
end
def file_path
@@ -67,7 +72,7 @@ module Rails
end
def class_path
- inside_namespace? || !namespaced? ? regular_class_path : namespaced_class_path
+ inside_template? || !namespaced? ? regular_class_path : namespaced_class_path
end
def regular_class_path
diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb
index 7907191c74..ef1eb8d237 100644
--- a/railties/lib/rails/generators/rails/app/app_generator.rb
+++ b/railties/lib/rails/generators/rails/app/app_generator.rb
@@ -1,9 +1,4 @@
-require 'digest/md5'
-require 'active_support/secure_random'
-require 'rails/version' unless defined?(Rails::VERSION)
-require 'rbconfig'
-require 'open-uri'
-require 'uri'
+require 'rails/generators/app_base'
module Rails
module ActionMethods
@@ -108,12 +103,20 @@ module Rails
end
def javascripts
- unless options[:skip_prototype]
- directory "public/javascripts"
- else
- empty_directory_with_gitkeep "public/javascripts"
- create_file "public/javascripts/application.js"
+ empty_directory "public/javascripts"
+
+ unless options[:skip_javascript]
+ copy_file "public/javascripts/#{@options[:javascript]}.js"
+ copy_file "public/javascripts/#{@options[:javascript]}_ujs.js", "public/javascripts/rails.js"
+
+ if options[:prototype]
+ copy_file "public/javascripts/controls.js"
+ copy_file "public/javascripts/dragdrop.js"
+ copy_file "public/javascripts/effects.js"
+ end
end
+
+ copy_file "public/javascripts/application.js"
end
def script
@@ -150,71 +153,28 @@ module Rails
RESERVED_NAMES = %w[application destroy benchmarker profiler
plugin runner test]
- class AppGenerator < Base
- DATABASES = %w( mysql oracle postgresql sqlite3 frontbase ibm_db )
-
- attr_accessor :rails_template
- add_shebang_option!
-
- argument :app_path, :type => :string
-
- class_option :database, :type => :string, :aliases => "-d", :default => "sqlite3",
- :desc => "Preconfigure for selected database (options: #{DATABASES.join('/')})"
-
- class_option :builder, :type => :string, :aliases => "-b",
- :desc => "Path to an application builder (can be a filesystem path or URL)"
-
- class_option :template, :type => :string, :aliases => "-m",
- :desc => "Path to an application template (can be a filesystem path or URL)"
-
- class_option :dev, :type => :boolean, :default => false,
- :desc => "Setup the application with Gemfile pointing to your Rails checkout"
-
- class_option :edge, :type => :boolean, :default => false,
- :desc => "Setup the application with Gemfile pointing to Rails repository"
-
- class_option :skip_gemfile, :type => :boolean, :default => false,
- :desc => "Don't create a Gemfile"
-
- class_option :skip_active_record, :type => :boolean, :aliases => "-O", :default => false,
- :desc => "Skip Active Record files"
-
- class_option :skip_test_unit, :type => :boolean, :aliases => "-T", :default => false,
- :desc => "Skip Test::Unit files"
-
- class_option :skip_prototype, :type => :boolean, :aliases => "-J", :default => false,
- :desc => "Skip Prototype files"
-
- class_option :skip_git, :type => :boolean, :aliases => "-G", :default => false,
- :desc => "Skip Git ignores and keeps"
+ class AppGenerator < AppBase
+ add_shared_options_for "application"
# Add bin/rails options
class_option :version, :type => :boolean, :aliases => "-v", :group => :rails,
:desc => "Show Rails version number and quit"
- class_option :help, :type => :boolean, :aliases => "-h", :group => :rails,
- :desc => "Show this help message and quit"
-
def initialize(*args)
raise Error, "Options should be given after the application name. For details run: rails --help" if args[0].blank?
- @original_wd = Dir.pwd
-
super
if !options[:skip_active_record] && !DATABASES.include?(options[:database])
raise Error, "Invalid value for --database option. Supported for preconfiguration are: #{DATABASES.join(", ")}."
end
+
+ if !options[:skip_javascript] && !JAVASCRIPTS.include?(options[:javascript])
+ raise Error, "Invalid value for --javascript option. Supported for preconfiguration are: #{JAVASCRIPTS.join(", ")}."
+ end
end
- def create_root
- self.destination_root = File.expand_path(app_path, destination_root)
- valid_app_const?
-
- empty_directory '.'
- set_default_accessors!
- FileUtils.cd(destination_root) unless options[:pretend]
- end
+ public_task :create_root
def create_root_files
build(:readme)
@@ -269,7 +229,7 @@ module Rails
build(:stylesheets)
end
- def create_prototype_files
+ def create_javascript_files
build(:javascripts)
end
@@ -293,16 +253,7 @@ module Rails
build(:leftovers)
end
- def apply_rails_template
- apply rails_template if rails_template
- rescue Thor::Error, LoadError, Errno::ENOENT => e
- raise Error, "The template [#{rails_template}] could not be loaded. Error: #{e}"
- end
-
- def bundle_if_dev_or_edge
- bundle_command = File.basename(Thor::Util.ruby_command).sub(/ruby/, 'bundle')
- run "#{bundle_command} install" if dev_or_edge?
- end
+ public_task :apply_rails_template, :bundle_if_dev_or_edge
protected
@@ -310,40 +261,6 @@ module Rails
"rails new #{self.arguments.map(&:usage).join(' ')} [options]"
end
- def builder
- @builder ||= begin
- if path = options[:builder]
- if URI(path).is_a?(URI::HTTP)
- contents = open(path, "Accept" => "application/x-thor-template") {|io| io.read }
- else
- contents = open(File.expand_path(path, @original_wd)) {|io| io.read }
- end
-
- prok = eval("proc { #{contents} }", TOPLEVEL_BINDING, path, 1)
- instance_eval(&prok)
- end
-
- builder_class = defined?(::AppBuilder) ? ::AppBuilder : Rails::AppBuilder
- builder_class.send(:include, ActionMethods)
- builder_class.new(self)
- end
- end
-
- def build(meth, *args)
- builder.send(meth, *args) if builder.respond_to?(meth)
- end
-
- def set_default_accessors!
- self.rails_template = case options[:template]
- when /^http:\/\//
- options[:template]
- when String
- File.expand_path(options[:template], Dir.pwd)
- else
- options[:template]
- end
- end
-
# Define file as an alias to create_file for backwards compatibility.
def file(*args, &block)
create_file(*args, &block)
@@ -372,7 +289,7 @@ module Rails
@app_const ||= "#{app_const_base}::Application"
end
- def valid_app_const?
+ def valid_const?
if app_const =~ /^\d/
raise Error, "Invalid application name #{app_name}. Please give a name which does not start with numbers."
elsif RESERVED_NAMES.include?(app_name)
@@ -386,28 +303,6 @@ module Rails
ActiveSupport::SecureRandom.hex(64)
end
- def dev_or_edge?
- options.dev? || options.edge?
- end
-
- def gem_for_database
- # %w( mysql oracle postgresql sqlite3 frontbase ibm_db )
- case options[:database]
- when "oracle" then "ruby-oci8"
- when "postgresql" then "pg"
- when "sqlite3" then "sqlite3-ruby"
- when "frontbase" then "ruby-frontbase"
- when "mysql" then "mysql2"
- else options[:database]
- end
- end
-
- def require_for_database
- case options[:database]
- when "sqlite3" then "sqlite3"
- end
- end
-
def mysql_socket
@mysql_socket ||= [
"/tmp/mysql.sock", # default
@@ -426,6 +321,10 @@ module Rails
empty_directory(destination, config)
create_file("#{destination}/.gitkeep") unless options[:skip_git]
end
+
+ def get_builder_class
+ defined?(::AppBuilder) ? ::AppBuilder : Rails::AppBuilder
+ end
end
end
end
diff --git a/railties/lib/rails/generators/rails/app/templates/Gemfile b/railties/lib/rails/generators/rails/app/templates/Gemfile
index 40213b1261..86b9e8f40c 100644
--- a/railties/lib/rails/generators/rails/app/templates/Gemfile
+++ b/railties/lib/rails/generators/rails/app/templates/Gemfile
@@ -1,25 +1,8 @@
source 'http://rubygems.org'
-<%- if options.dev? -%>
-gem 'rails', :path => '<%= Rails::Generators::RAILS_DEV_PATH %>'
-gem 'arel', :git => 'git://github.com/rails/arel.git'
-gem "rack", :git => "git://github.com/rack/rack.git"
-<%- elsif options.edge? -%>
-gem 'rails', :git => 'git://github.com/rails/rails.git'
-gem 'arel', :git => 'git://github.com/rails/arel.git'
-gem "rack", :git => "git://github.com/rack/rack.git"
-<%- else -%>
-gem 'rails', '<%= Rails::VERSION::STRING %>'
+<%= rails_gemfile_entry -%>
-# Bundle edge Rails instead:
-# gem 'rails', :git => 'git://github.com/rails/rails.git'
-# gem 'arel', :git => 'git://github.com/rails/arel.git'
-# gem "rack", :git => "git://github.com/rack/rack.git"
-<%- end -%>
-
-<% unless options[:skip_active_record] -%>
-gem '<%= gem_for_database %>'<% if require_for_database %>, :require => '<%= require_for_database %>'<% end %>
-<% end -%>
+<%= database_gemfile_entry -%>
# Use unicorn as the web server
# gem 'unicorn'
diff --git a/railties/lib/rails/generators/rails/app/templates/Rakefile b/railties/lib/rails/generators/rails/app/templates/Rakefile
index d83cafc3be..4dc1023f1f 100644..100755
--- a/railties/lib/rails/generators/rails/app/templates/Rakefile
+++ b/railties/lib/rails/generators/rails/app/templates/Rakefile
@@ -1,7 +1,7 @@
+#!/usr/bin/env rake
# Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
require File.expand_path('../config/application', __FILE__)
-require 'rake'
<%= app_const %>.load_tasks
diff --git a/railties/lib/rails/generators/rails/app/templates/config/application.rb b/railties/lib/rails/generators/rails/app/templates/config/application.rb
index 7d63e99e05..6e515756fe 100644
--- a/railties/lib/rails/generators/rails/app/templates/config/application.rb
+++ b/railties/lib/rails/generators/rails/app/templates/config/application.rb
@@ -40,12 +40,18 @@ module <%= app_const_base %>
# config.i18n.default_locale = :de
# JavaScript files you want as :defaults (application.js is always included).
-<% if options[:skip_prototype] -%>
+<% if options[:skip_javascript] -%>
config.action_view.javascript_expansions[:defaults] = %w()
+<% elsif options[:javascript] == 'jquery' -%>
+ config.action_view.javascript_expansions[:defaults] = %w(jquery rails)
<% else -%>
# config.action_view.javascript_expansions[:defaults] = %w(jquery rails)
<% end -%>
+<% if options[:skip_test_unit] -%>
+ config.generators.test_framework = false
+<% end -%>
+
# Configure the default encoding used in templates for Ruby 1.9.
config.encoding = "utf-8"
diff --git a/railties/lib/rails/generators/rails/app/templates/public/javascripts/jquery.js b/railties/lib/rails/generators/rails/app/templates/public/javascripts/jquery.js
new file mode 100644
index 0000000000..a4f114586c
--- /dev/null
+++ b/railties/lib/rails/generators/rails/app/templates/public/javascripts/jquery.js
@@ -0,0 +1,7179 @@
+/*!
+ * jQuery JavaScript Library v1.4.4
+ * http://jquery.com/
+ *
+ * Copyright 2010, John Resig
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ * Copyright 2010, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ *
+ * Date: Thu Nov 11 19:04:53 2010 -0500
+ */
+(function( window, undefined ) {
+
+// Use the correct document accordingly with window argument (sandbox)
+var document = window.document;
+var jQuery = (function() {
+
+// Define a local copy of jQuery
+var jQuery = function( selector, context ) {
+ // The jQuery object is actually just the init constructor 'enhanced'
+ return new jQuery.fn.init( selector, context );
+ },
+
+ // Map over jQuery in case of overwrite
+ _jQuery = window.jQuery,
+
+ // Map over the $ in case of overwrite
+ _$ = window.$,
+
+ // A central reference to the root jQuery(document)
+ rootjQuery,
+
+ // A simple way to check for HTML strings or ID strings
+ // (both of which we optimize for)
+ quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/,
+
+ // Is it a simple selector
+ isSimple = /^.[^:#\[\.,]*$/,
+
+ // Check if a string has a non-whitespace character in it
+ rnotwhite = /\S/,
+ rwhite = /\s/,
+
+ // Used for trimming whitespace
+ trimLeft = /^\s+/,
+ trimRight = /\s+$/,
+
+ // Check for non-word characters
+ rnonword = /\W/,
+
+ // Check for digits
+ rdigit = /\d/,
+
+ // Match a standalone tag
+ rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,
+
+ // JSON RegExp
+ rvalidchars = /^[\],:{}\s]*$/,
+ rvalidescape = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,
+ rvalidtokens = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
+ rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g,
+
+ // Useragent RegExp
+ rwebkit = /(webkit)[ \/]([\w.]+)/,
+ ropera = /(opera)(?:.*version)?[ \/]([\w.]+)/,
+ rmsie = /(msie) ([\w.]+)/,
+ rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
+
+ // Keep a UserAgent string for use with jQuery.browser
+ userAgent = navigator.userAgent,
+
+ // For matching the engine and version of the browser
+ browserMatch,
+
+ // Has the ready events already been bound?
+ readyBound = false,
+
+ // The functions to execute on DOM ready
+ readyList = [],
+
+ // The ready event handler
+ DOMContentLoaded,
+
+ // Save a reference to some core methods
+ toString = Object.prototype.toString,
+ hasOwn = Object.prototype.hasOwnProperty,
+ push = Array.prototype.push,
+ slice = Array.prototype.slice,
+ trim = String.prototype.trim,
+ indexOf = Array.prototype.indexOf,
+
+ // [[Class]] -> type pairs
+ class2type = {};
+
+jQuery.fn = jQuery.prototype = {
+ init: function( selector, context ) {
+ var match, elem, ret, doc;
+
+ // Handle $(""), $(null), or $(undefined)
+ if ( !selector ) {
+ return this;
+ }
+
+ // Handle $(DOMElement)
+ if ( selector.nodeType ) {
+ this.context = this[0] = selector;
+ this.length = 1;
+ return this;
+ }
+
+ // The body element only exists once, optimize finding it
+ if ( selector === "body" && !context && document.body ) {
+ this.context = document;
+ this[0] = document.body;
+ this.selector = "body";
+ this.length = 1;
+ return this;
+ }
+
+ // Handle HTML strings
+ if ( typeof selector === "string" ) {
+ // Are we dealing with HTML string or an ID?
+ match = quickExpr.exec( selector );
+
+ // Verify a match, and that no context was specified for #id
+ if ( match && (match[1] || !context) ) {
+
+ // HANDLE: $(html) -> $(array)
+ if ( match[1] ) {
+ doc = (context ? context.ownerDocument || context : document);
+
+ // If a single string is passed in and it's a single tag
+ // just do a createElement and skip the rest
+ ret = rsingleTag.exec( selector );
+
+ if ( ret ) {
+ if ( jQuery.isPlainObject( context ) ) {
+ selector = [ document.createElement( ret[1] ) ];
+ jQuery.fn.attr.call( selector, context, true );
+
+ } else {
+ selector = [ doc.createElement( ret[1] ) ];
+ }
+
+ } else {
+ ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
+ selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;
+ }
+
+ return jQuery.merge( this, selector );
+
+ // HANDLE: $("#id")
+ } else {
+ elem = document.getElementById( match[2] );
+
+ // Check parentNode to catch when Blackberry 4.6 returns
+ // nodes that are no longer in the document #6963
+ if ( elem && elem.parentNode ) {
+ // Handle the case where IE and Opera return items
+ // by name instead of ID
+ if ( elem.id !== match[2] ) {
+ return rootjQuery.find( selector );
+ }
+
+ // Otherwise, we inject the element directly into the jQuery object
+ this.length = 1;
+ this[0] = elem;
+ }
+
+ this.context = document;
+ this.selector = selector;
+ return this;
+ }
+
+ // HANDLE: $("TAG")
+ } else if ( !context && !rnonword.test( selector ) ) {
+ this.selector = selector;
+ this.context = document;
+ selector = document.getElementsByTagName( selector );
+ return jQuery.merge( this, selector );
+
+ // HANDLE: $(expr, $(...))
+ } else if ( !context || context.jquery ) {
+ return (context || rootjQuery).find( selector );
+
+ // HANDLE: $(expr, context)
+ // (which is just equivalent to: $(context).find(expr)
+ } else {
+ return jQuery( context ).find( selector );
+ }
+
+ // HANDLE: $(function)
+ // Shortcut for document ready
+ } else if ( jQuery.isFunction( selector ) ) {
+ return rootjQuery.ready( selector );
+ }
+
+ if (selector.selector !== undefined) {
+ this.selector = selector.selector;
+ this.context = selector.context;
+ }
+
+ return jQuery.makeArray( selector, this );
+ },
+
+ // Start with an empty selector
+ selector: "",
+
+ // The current version of jQuery being used
+ jquery: "1.4.4",
+
+ // The default length of a jQuery object is 0
+ length: 0,
+
+ // The number of elements contained in the matched element set
+ size: function() {
+ return this.length;
+ },
+
+ toArray: function() {
+ return slice.call( this, 0 );
+ },
+
+ // Get the Nth element in the matched element set OR
+ // Get the whole matched element set as a clean array
+ get: function( num ) {
+ return num == null ?
+
+ // Return a 'clean' array
+ this.toArray() :
+
+ // Return just the object
+ ( num < 0 ? this.slice(num)[ 0 ] : this[ num ] );
+ },
+
+ // Take an array of elements and push it onto the stack
+ // (returning the new matched element set)
+ pushStack: function( elems, name, selector ) {
+ // Build a new jQuery matched element set
+ var ret = jQuery();
+
+ if ( jQuery.isArray( elems ) ) {
+ push.apply( ret, elems );
+
+ } else {
+ jQuery.merge( ret, elems );
+ }
+
+ // Add the old object onto the stack (as a reference)
+ ret.prevObject = this;
+
+ ret.context = this.context;
+
+ if ( name === "find" ) {
+ ret.selector = this.selector + (this.selector ? " " : "") + selector;
+ } else if ( name ) {
+ ret.selector = this.selector + "." + name + "(" + selector + ")";
+ }
+
+ // Return the newly-formed element set
+ return ret;
+ },
+
+ // Execute a callback for every element in the matched set.
+ // (You can seed the arguments with an array of args, but this is
+ // only used internally.)
+ each: function( callback, args ) {
+ return jQuery.each( this, callback, args );
+ },
+
+ ready: function( fn ) {
+ // Attach the listeners
+ jQuery.bindReady();
+
+ // If the DOM is already ready
+ if ( jQuery.isReady ) {
+ // Execute the function immediately
+ fn.call( document, jQuery );
+
+ // Otherwise, remember the function for later
+ } else if ( readyList ) {
+ // Add the function to the wait list
+ readyList.push( fn );
+ }
+
+ return this;
+ },
+
+ eq: function( i ) {
+ return i === -1 ?
+ this.slice( i ) :
+ this.slice( i, +i + 1 );
+ },
+
+ first: function() {
+ return this.eq( 0 );
+ },
+
+ last: function() {
+ return this.eq( -1 );
+ },
+
+ slice: function() {
+ return this.pushStack( slice.apply( this, arguments ),
+ "slice", slice.call(arguments).join(",") );
+ },
+
+ map: function( callback ) {
+ return this.pushStack( jQuery.map(this, function( elem, i ) {
+ return callback.call( elem, i, elem );
+ }));
+ },
+
+ end: function() {
+ return this.prevObject || jQuery(null);
+ },
+
+ // For internal use only.
+ // Behaves like an Array's method, not like a jQuery method.
+ push: push,
+ sort: [].sort,
+ splice: [].splice
+};
+
+// Give the init function the jQuery prototype for later instantiation
+jQuery.fn.init.prototype = jQuery.fn;
+
+jQuery.extend = jQuery.fn.extend = function() {
+ var options, name, src, copy, copyIsArray, clone,
+ target = arguments[0] || {},
+ i = 1,
+ length = arguments.length,
+ deep = false;
+
+ // Handle a deep copy situation
+ if ( typeof target === "boolean" ) {
+ deep = target;
+ target = arguments[1] || {};
+ // skip the boolean and the target
+ i = 2;
+ }
+
+ // Handle case when target is a string or something (possible in deep copy)
+ if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
+ target = {};
+ }
+
+ // extend jQuery itself if only one argument is passed
+ if ( length === i ) {
+ target = this;
+ --i;
+ }
+
+ for ( ; i < length; i++ ) {
+ // Only deal with non-null/undefined values
+ if ( (options = arguments[ i ]) != null ) {
+ // Extend the base object
+ for ( name in options ) {
+ src = target[ name ];
+ copy = options[ name ];
+
+ // Prevent never-ending loop
+ if ( target === copy ) {
+ continue;
+ }
+
+ // Recurse if we're merging plain objects or arrays
+ if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
+ if ( copyIsArray ) {
+ copyIsArray = false;
+ clone = src && jQuery.isArray(src) ? src : [];
+
+ } else {
+ clone = src && jQuery.isPlainObject(src) ? src : {};
+ }
+
+ // Never move original objects, clone them
+ target[ name ] = jQuery.extend( deep, clone, copy );
+
+ // Don't bring in undefined values
+ } else if ( copy !== undefined ) {
+ target[ name ] = copy;
+ }
+ }
+ }
+ }
+
+ // Return the modified object
+ return target;
+};
+
+jQuery.extend({
+ noConflict: function( deep ) {
+ window.$ = _$;
+
+ if ( deep ) {
+ window.jQuery = _jQuery;
+ }
+
+ return jQuery;
+ },
+
+ // Is the DOM ready to be used? Set to true once it occurs.
+ isReady: false,
+
+ // A counter to track how many items to wait for before
+ // the ready event fires. See #6781
+ readyWait: 1,
+
+ // Handle when the DOM is ready
+ ready: function( wait ) {
+ // A third-party is pushing the ready event forwards
+ if ( wait === true ) {
+ jQuery.readyWait--;
+ }
+
+ // Make sure that the DOM is not already loaded
+ if ( !jQuery.readyWait || (wait !== true && !jQuery.isReady) ) {
+ // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+ if ( !document.body ) {
+ return setTimeout( jQuery.ready, 1 );
+ }
+
+ // Remember that the DOM is ready
+ jQuery.isReady = true;
+
+ // If a normal DOM Ready event fired, decrement, and wait if need be
+ if ( wait !== true && --jQuery.readyWait > 0 ) {
+ return;
+ }
+
+ // If there are functions bound, to execute
+ if ( readyList ) {
+ // Execute all of them
+ var fn,
+ i = 0,
+ ready = readyList;
+
+ // Reset the list of functions
+ readyList = null;
+
+ while ( (fn = ready[ i++ ]) ) {
+ fn.call( document, jQuery );
+ }
+
+ // Trigger any bound ready events
+ if ( jQuery.fn.trigger ) {
+ jQuery( document ).trigger( "ready" ).unbind( "ready" );
+ }
+ }
+ }
+ },
+
+ bindReady: function() {
+ if ( readyBound ) {
+ return;
+ }
+
+ readyBound = true;
+
+ // Catch cases where $(document).ready() is called after the
+ // browser event has already occurred.
+ if ( document.readyState === "complete" ) {
+ // Handle it asynchronously to allow scripts the opportunity to delay ready
+ return setTimeout( jQuery.ready, 1 );
+ }
+
+ // Mozilla, Opera and webkit nightlies currently support this event
+ if ( document.addEventListener ) {
+ // Use the handy event callback
+ document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );
+
+ // A fallback to window.onload, that will always work
+ window.addEventListener( "load", jQuery.ready, false );
+
+ // If IE event model is used
+ } else if ( document.attachEvent ) {
+ // ensure firing before onload,
+ // maybe late but safe also for iframes
+ document.attachEvent("onreadystatechange", DOMContentLoaded);
+
+ // A fallback to window.onload, that will always work
+ window.attachEvent( "onload", jQuery.ready );
+
+ // If IE and not a frame
+ // continually check to see if the document is ready
+ var toplevel = false;
+
+ try {
+ toplevel = window.frameElement == null;
+ } catch(e) {}
+
+ if ( document.documentElement.doScroll && toplevel ) {
+ doScrollCheck();
+ }
+ }
+ },
+
+ // See test/unit/core.js for details concerning isFunction.
+ // Since version 1.3, DOM methods and functions like alert
+ // aren't supported. They return false on IE (#2968).
+ isFunction: function( obj ) {
+ return jQuery.type(obj) === "function";
+ },
+
+ isArray: Array.isArray || function( obj ) {
+ return jQuery.type(obj) === "array";
+ },
+
+ // A crude way of determining if an object is a window
+ isWindow: function( obj ) {
+ return obj && typeof obj === "object" && "setInterval" in obj;
+ },
+
+ isNaN: function( obj ) {
+ return obj == null || !rdigit.test( obj ) || isNaN( obj );
+ },
+
+ type: function( obj ) {
+ return obj == null ?
+ String( obj ) :
+ class2type[ toString.call(obj) ] || "object";
+ },
+
+ isPlainObject: function( obj ) {
+ // Must be an Object.
+ // Because of IE, we also have to check the presence of the constructor property.
+ // Make sure that DOM nodes and window objects don't pass through, as well
+ if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
+ return false;
+ }
+
+ // Not own constructor property must be Object
+ if ( obj.constructor &&
+ !hasOwn.call(obj, "constructor") &&
+ !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
+ return false;
+ }
+
+ // Own properties are enumerated firstly, so to speed up,
+ // if last one is own, then all properties are own.
+
+ var key;
+ for ( key in obj ) {}
+
+ return key === undefined || hasOwn.call( obj, key );
+ },
+
+ isEmptyObject: function( obj ) {
+ for ( var name in obj ) {
+ return false;
+ }
+ return true;
+ },
+
+ error: function( msg ) {
+ throw msg;
+ },
+
+ parseJSON: function( data ) {
+ if ( typeof data !== "string" || !data ) {
+ return null;
+ }
+
+ // Make sure leading/trailing whitespace is removed (IE can't handle it)
+ data = jQuery.trim( data );
+
+ // Make sure the incoming data is actual JSON
+ // Logic borrowed from http://json.org/json2.js
+ if ( rvalidchars.test(data.replace(rvalidescape, "@")
+ .replace(rvalidtokens, "]")
+ .replace(rvalidbraces, "")) ) {
+
+ // Try to use the native JSON parser first
+ return window.JSON && window.JSON.parse ?
+ window.JSON.parse( data ) :
+ (new Function("return " + data))();
+
+ } else {
+ jQuery.error( "Invalid JSON: " + data );
+ }
+ },
+
+ noop: function() {},
+
+ // Evalulates a script in a global context
+ globalEval: function( data ) {
+ if ( data && rnotwhite.test(data) ) {
+ // Inspired by code by Andrea Giammarchi
+ // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
+ var head = document.getElementsByTagName("head")[0] || document.documentElement,
+ script = document.createElement("script");
+
+ script.type = "text/javascript";
+
+ if ( jQuery.support.scriptEval ) {
+ script.appendChild( document.createTextNode( data ) );
+ } else {
+ script.text = data;
+ }
+
+ // Use insertBefore instead of appendChild to circumvent an IE6 bug.
+ // This arises when a base node is used (#2709).
+ head.insertBefore( script, head.firstChild );
+ head.removeChild( script );
+ }
+ },
+
+ nodeName: function( elem, name ) {
+ return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
+ },
+
+ // args is for internal usage only
+ each: function( object, callback, args ) {
+ var name, i = 0,
+ length = object.length,
+ isObj = length === undefined || jQuery.isFunction(object);
+
+ if ( args ) {
+ if ( isObj ) {
+ for ( name in object ) {
+ if ( callback.apply( object[ name ], args ) === false ) {
+ break;
+ }
+ }
+ } else {
+ for ( ; i < length; ) {
+ if ( callback.apply( object[ i++ ], args ) === false ) {
+ break;
+ }
+ }
+ }
+
+ // A special, fast, case for the most common use of each
+ } else {
+ if ( isObj ) {
+ for ( name in object ) {
+ if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
+ break;
+ }
+ }
+ } else {
+ for ( var value = object[0];
+ i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {}
+ }
+ }
+
+ return object;
+ },
+
+ // Use native String.trim function wherever possible
+ trim: trim ?
+ function( text ) {
+ return text == null ?
+ "" :
+ trim.call( text );
+ } :
+
+ // Otherwise use our own trimming functionality
+ function( text ) {
+ return text == null ?
+ "" :
+ text.toString().replace( trimLeft, "" ).replace( trimRight, "" );
+ },
+
+ // results is for internal usage only
+ makeArray: function( array, results ) {
+ var ret = results || [];
+
+ if ( array != null ) {
+ // The window, strings (and functions) also have 'length'
+ // The extra typeof function check is to prevent crashes
+ // in Safari 2 (See: #3039)
+ // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930
+ var type = jQuery.type(array);
+
+ if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) {
+ push.call( ret, array );
+ } else {
+ jQuery.merge( ret, array );
+ }
+ }
+
+ return ret;
+ },
+
+ inArray: function( elem, array ) {
+ if ( array.indexOf ) {
+ return array.indexOf( elem );
+ }
+
+ for ( var i = 0, length = array.length; i < length; i++ ) {
+ if ( array[ i ] === elem ) {
+ return i;
+ }
+ }
+
+ return -1;
+ },
+
+ merge: function( first, second ) {
+ var i = first.length,
+ j = 0;
+
+ if ( typeof second.length === "number" ) {
+ for ( var l = second.length; j < l; j++ ) {
+ first[ i++ ] = second[ j ];
+ }
+
+ } else {
+ while ( second[j] !== undefined ) {
+ first[ i++ ] = second[ j++ ];
+ }
+ }
+
+ first.length = i;
+
+ return first;
+ },
+
+ grep: function( elems, callback, inv ) {
+ var ret = [], retVal;
+ inv = !!inv;
+
+ // Go through the array, only saving the items
+ // that pass the validator function
+ for ( var i = 0, length = elems.length; i < length; i++ ) {
+ retVal = !!callback( elems[ i ], i );
+ if ( inv !== retVal ) {
+ ret.push( elems[ i ] );
+ }
+ }
+
+ return ret;
+ },
+
+ // arg is for internal usage only
+ map: function( elems, callback, arg ) {
+ var ret = [], value;
+
+ // Go through the array, translating each of the items to their
+ // new value (or values).
+ for ( var i = 0, length = elems.length; i < length; i++ ) {
+ value = callback( elems[ i ], i, arg );
+
+ if ( value != null ) {
+ ret[ ret.length ] = value;
+ }
+ }
+
+ return ret.concat.apply( [], ret );
+ },
+
+ // A global GUID counter for objects
+ guid: 1,
+
+ proxy: function( fn, proxy, thisObject ) {
+ if ( arguments.length === 2 ) {
+ if ( typeof proxy === "string" ) {
+ thisObject = fn;
+ fn = thisObject[ proxy ];
+ proxy = undefined;
+
+ } else if ( proxy && !jQuery.isFunction( proxy ) ) {
+ thisObject = proxy;
+ proxy = undefined;
+ }
+ }
+
+ if ( !proxy && fn ) {
+ proxy = function() {
+ return fn.apply( thisObject || this, arguments );
+ };
+ }
+
+ // Set the guid of unique handler to the same of original handler, so it can be removed
+ if ( fn ) {
+ proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
+ }
+
+ // So proxy can be declared as an argument
+ return proxy;
+ },
+
+ // Mutifunctional method to get and set values to a collection
+ // The value/s can be optionally by executed if its a function
+ access: function( elems, key, value, exec, fn, pass ) {
+ var length = elems.length;
+
+ // Setting many attributes
+ if ( typeof key === "object" ) {
+ for ( var k in key ) {
+ jQuery.access( elems, k, key[k], exec, fn, value );
+ }
+ return elems;
+ }
+
+ // Setting one attribute
+ if ( value !== undefined ) {
+ // Optionally, function values get executed if exec is true
+ exec = !pass && exec && jQuery.isFunction(value);
+
+ for ( var i = 0; i < length; i++ ) {
+ fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
+ }
+
+ return elems;
+ }
+
+ // Getting an attribute
+ return length ? fn( elems[0], key ) : undefined;
+ },
+
+ now: function() {
+ return (new Date()).getTime();
+ },
+
+ // Use of jQuery.browser is frowned upon.
+ // More details: http://docs.jquery.com/Utilities/jQuery.browser
+ uaMatch: function( ua ) {
+ ua = ua.toLowerCase();
+
+ var match = rwebkit.exec( ua ) ||
+ ropera.exec( ua ) ||
+ rmsie.exec( ua ) ||
+ ua.indexOf("compatible") < 0 && rmozilla.exec( ua ) ||
+ [];
+
+ return { browser: match[1] || "", version: match[2] || "0" };
+ },
+
+ browser: {}
+});
+
+// Populate the class2type map
+jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
+ class2type[ "[object " + name + "]" ] = name.toLowerCase();
+});
+
+browserMatch = jQuery.uaMatch( userAgent );
+if ( browserMatch.browser ) {
+ jQuery.browser[ browserMatch.browser ] = true;
+ jQuery.browser.version = browserMatch.version;
+}
+
+// Deprecated, use jQuery.browser.webkit instead
+if ( jQuery.browser.webkit ) {
+ jQuery.browser.safari = true;
+}
+
+if ( indexOf ) {
+ jQuery.inArray = function( elem, array ) {
+ return indexOf.call( array, elem );
+ };
+}
+
+// Verify that \s matches non-breaking spaces
+// (IE fails on this test)
+if ( !rwhite.test( "\xA0" ) ) {
+ trimLeft = /^[\s\xA0]+/;
+ trimRight = /[\s\xA0]+$/;
+}
+
+// All jQuery objects should point back to these
+rootjQuery = jQuery(document);
+
+// Cleanup functions for the document ready method
+if ( document.addEventListener ) {
+ DOMContentLoaded = function() {
+ document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );
+ jQuery.ready();
+ };
+
+} else if ( document.attachEvent ) {
+ DOMContentLoaded = function() {
+ // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
+ if ( document.readyState === "complete" ) {
+ document.detachEvent( "onreadystatechange", DOMContentLoaded );
+ jQuery.ready();
+ }
+ };
+}
+
+// The DOM ready check for Internet Explorer
+function doScrollCheck() {
+ if ( jQuery.isReady ) {
+ return;
+ }
+
+ try {
+ // If IE is used, use the trick by Diego Perini
+ // http://javascript.nwbox.com/IEContentLoaded/
+ document.documentElement.doScroll("left");
+ } catch(e) {
+ setTimeout( doScrollCheck, 1 );
+ return;
+ }
+
+ // and execute any waiting functions
+ jQuery.ready();
+}
+
+// Expose jQuery to the global object
+return (window.jQuery = window.$ = jQuery);
+
+})();
+
+
+(function() {
+
+ jQuery.support = {};
+
+ var root = document.documentElement,
+ script = document.createElement("script"),
+ div = document.createElement("div"),
+ id = "script" + jQuery.now();
+
+ div.style.display = "none";
+ div.innerHTML = " <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
+
+ var all = div.getElementsByTagName("*"),
+ a = div.getElementsByTagName("a")[0],
+ select = document.createElement("select"),
+ opt = select.appendChild( document.createElement("option") );
+
+ // Can't get basic test support
+ if ( !all || !all.length || !a ) {
+ return;
+ }
+
+ jQuery.support = {
+ // IE strips leading whitespace when .innerHTML is used
+ leadingWhitespace: div.firstChild.nodeType === 3,
+
+ // Make sure that tbody elements aren't automatically inserted
+ // IE will insert them into empty tables
+ tbody: !div.getElementsByTagName("tbody").length,
+
+ // Make sure that link elements get serialized correctly by innerHTML
+ // This requires a wrapper element in IE
+ htmlSerialize: !!div.getElementsByTagName("link").length,
+
+ // Get the style information from getAttribute
+ // (IE uses .cssText insted)
+ style: /red/.test( a.getAttribute("style") ),
+
+ // Make sure that URLs aren't manipulated
+ // (IE normalizes it by default)
+ hrefNormalized: a.getAttribute("href") === "/a",
+
+ // Make sure that element opacity exists
+ // (IE uses filter instead)
+ // Use a regex to work around a WebKit issue. See #5145
+ opacity: /^0.55$/.test( a.style.opacity ),
+
+ // Verify style float existence
+ // (IE uses styleFloat instead of cssFloat)
+ cssFloat: !!a.style.cssFloat,
+
+ // Make sure that if no value is specified for a checkbox
+ // that it defaults to "on".
+ // (WebKit defaults to "" instead)
+ checkOn: div.getElementsByTagName("input")[0].value === "on",
+
+ // Make sure that a selected-by-default option has a working selected property.
+ // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
+ optSelected: opt.selected,
+
+ // Will be defined later
+ deleteExpando: true,
+ optDisabled: false,
+ checkClone: false,
+ scriptEval: false,
+ noCloneEvent: true,
+ boxModel: null,
+ inlineBlockNeedsLayout: false,
+ shrinkWrapBlocks: false,
+ reliableHiddenOffsets: true
+ };
+
+ // Make sure that the options inside disabled selects aren't marked as disabled
+ // (WebKit marks them as diabled)
+ select.disabled = true;
+ jQuery.support.optDisabled = !opt.disabled;
+
+ script.type = "text/javascript";
+ try {
+ script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
+ } catch(e) {}
+
+ root.insertBefore( script, root.firstChild );
+
+ // Make sure that the execution of code works by injecting a script
+ // tag with appendChild/createTextNode
+ // (IE doesn't support this, fails, and uses .text instead)
+ if ( window[ id ] ) {
+ jQuery.support.scriptEval = true;
+ delete window[ id ];
+ }
+
+ // Test to see if it's possible to delete an expando from an element
+ // Fails in Internet Explorer
+ try {
+ delete script.test;
+
+ } catch(e) {
+ jQuery.support.deleteExpando = false;
+ }
+
+ root.removeChild( script );
+
+ if ( div.attachEvent && div.fireEvent ) {
+ div.attachEvent("onclick", function click() {
+ // Cloning a node shouldn't copy over any
+ // bound event handlers (IE does this)
+ jQuery.support.noCloneEvent = false;
+ div.detachEvent("onclick", click);
+ });
+ div.cloneNode(true).fireEvent("onclick");
+ }
+
+ div = document.createElement("div");
+ div.innerHTML = "<input type='radio' name='radiotest' checked='checked'/>";
+
+ var fragment = document.createDocumentFragment();
+ fragment.appendChild( div.firstChild );
+
+ // WebKit doesn't clone checked state correctly in fragments
+ jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked;
+
+ // Figure out if the W3C box model works as expected
+ // document.body must exist before we can do this
+ jQuery(function() {
+ var div = document.createElement("div");
+ div.style.width = div.style.paddingLeft = "1px";
+
+ document.body.appendChild( div );
+ jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
+
+ if ( "zoom" in div.style ) {
+ // Check if natively block-level elements act like inline-block
+ // elements when setting their display to 'inline' and giving
+ // them layout
+ // (IE < 8 does this)
+ div.style.display = "inline";
+ div.style.zoom = 1;
+ jQuery.support.inlineBlockNeedsLayout = div.offsetWidth === 2;
+
+ // Check if elements with layout shrink-wrap their children
+ // (IE 6 does this)
+ div.style.display = "";
+ div.innerHTML = "<div style='width:4px;'></div>";
+ jQuery.support.shrinkWrapBlocks = div.offsetWidth !== 2;
+ }
+
+ div.innerHTML = "<table><tr><td style='padding:0;display:none'></td><td>t</td></tr></table>";
+ var tds = div.getElementsByTagName("td");
+
+ // Check if table cells still have offsetWidth/Height when they are set
+ // to display:none and there are still other visible table cells in a
+ // table row; if so, offsetWidth/Height are not reliable for use when
+ // determining if an element has been hidden directly using
+ // display:none (it is still safe to use offsets if a parent element is
+ // hidden; don safety goggles and see bug #4512 for more information).
+ // (only IE 8 fails this test)
+ jQuery.support.reliableHiddenOffsets = tds[0].offsetHeight === 0;
+
+ tds[0].style.display = "";
+ tds[1].style.display = "none";
+
+ // Check if empty table cells still have offsetWidth/Height
+ // (IE < 8 fail this test)
+ jQuery.support.reliableHiddenOffsets = jQuery.support.reliableHiddenOffsets && tds[0].offsetHeight === 0;
+ div.innerHTML = "";
+
+ document.body.removeChild( div ).style.display = "none";
+ div = tds = null;
+ });
+
+ // Technique from Juriy Zaytsev
+ // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
+ var eventSupported = function( eventName ) {
+ var el = document.createElement("div");
+ eventName = "on" + eventName;
+
+ var isSupported = (eventName in el);
+ if ( !isSupported ) {
+ el.setAttribute(eventName, "return;");
+ isSupported = typeof el[eventName] === "function";
+ }
+ el = null;
+
+ return isSupported;
+ };
+
+ jQuery.support.submitBubbles = eventSupported("submit");
+ jQuery.support.changeBubbles = eventSupported("change");
+
+ // release memory in IE
+ root = script = div = all = a = null;
+})();
+
+
+
+var windowData = {},
+ rbrace = /^(?:\{.*\}|\[.*\])$/;
+
+jQuery.extend({
+ cache: {},
+
+ // Please use with caution
+ uuid: 0,
+
+ // Unique for each copy of jQuery on the page
+ expando: "jQuery" + jQuery.now(),
+
+ // The following elements throw uncatchable exceptions if you
+ // attempt to add expando properties to them.
+ noData: {
+ "embed": true,
+ // Ban all objects except for Flash (which handle expandos)
+ "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",
+ "applet": true
+ },
+
+ data: function( elem, name, data ) {
+ if ( !jQuery.acceptData( elem ) ) {
+ return;
+ }
+
+ elem = elem == window ?
+ windowData :
+ elem;
+
+ var isNode = elem.nodeType,
+ id = isNode ? elem[ jQuery.expando ] : null,
+ cache = jQuery.cache, thisCache;
+
+ if ( isNode && !id && typeof name === "string" && data === undefined ) {
+ return;
+ }
+
+ // Get the data from the object directly
+ if ( !isNode ) {
+ cache = elem;
+
+ // Compute a unique ID for the element
+ } else if ( !id ) {
+ elem[ jQuery.expando ] = id = ++jQuery.uuid;
+ }
+
+ // Avoid generating a new cache unless none exists and we
+ // want to manipulate it.
+ if ( typeof name === "object" ) {
+ if ( isNode ) {
+ cache[ id ] = jQuery.extend(cache[ id ], name);
+
+ } else {
+ jQuery.extend( cache, name );
+ }
+
+ } else if ( isNode && !cache[ id ] ) {
+ cache[ id ] = {};
+ }
+
+ thisCache = isNode ? cache[ id ] : cache;
+
+ // Prevent overriding the named cache with undefined values
+ if ( data !== undefined ) {
+ thisCache[ name ] = data;
+ }
+
+ return typeof name === "string" ? thisCache[ name ] : thisCache;
+ },
+
+ removeData: function( elem, name ) {
+ if ( !jQuery.acceptData( elem ) ) {
+ return;
+ }
+
+ elem = elem == window ?
+ windowData :
+ elem;
+
+ var isNode = elem.nodeType,
+ id = isNode ? elem[ jQuery.expando ] : elem,
+ cache = jQuery.cache,
+ thisCache = isNode ? cache[ id ] : id;
+
+ // If we want to remove a specific section of the element's data
+ if ( name ) {
+ if ( thisCache ) {
+ // Remove the section of cache data
+ delete thisCache[ name ];
+
+ // If we've removed all the data, remove the element's cache
+ if ( isNode && jQuery.isEmptyObject(thisCache) ) {
+ jQuery.removeData( elem );
+ }
+ }
+
+ // Otherwise, we want to remove all of the element's data
+ } else {
+ if ( isNode && jQuery.support.deleteExpando ) {
+ delete elem[ jQuery.expando ];
+
+ } else if ( elem.removeAttribute ) {
+ elem.removeAttribute( jQuery.expando );
+
+ // Completely remove the data cache
+ } else if ( isNode ) {
+ delete cache[ id ];
+
+ // Remove all fields from the object
+ } else {
+ for ( var n in elem ) {
+ delete elem[ n ];
+ }
+ }
+ }
+ },
+
+ // A method for determining if a DOM node can handle the data expando
+ acceptData: function( elem ) {
+ if ( elem.nodeName ) {
+ var match = jQuery.noData[ elem.nodeName.toLowerCase() ];
+
+ if ( match ) {
+ return !(match === true || elem.getAttribute("classid") !== match);
+ }
+ }
+
+ return true;
+ }
+});
+
+jQuery.fn.extend({
+ data: function( key, value ) {
+ var data = null;
+
+ if ( typeof key === "undefined" ) {
+ if ( this.length ) {
+ var attr = this[0].attributes, name;
+ data = jQuery.data( this[0] );
+
+ for ( var i = 0, l = attr.length; i < l; i++ ) {
+ name = attr[i].name;
+
+ if ( name.indexOf( "data-" ) === 0 ) {
+ name = name.substr( 5 );
+ dataAttr( this[0], name, data[ name ] );
+ }
+ }
+ }
+
+ return data;
+
+ } else if ( typeof key === "object" ) {
+ return this.each(function() {
+ jQuery.data( this, key );
+ });
+ }
+
+ var parts = key.split(".");
+ parts[1] = parts[1] ? "." + parts[1] : "";
+
+ if ( value === undefined ) {
+ data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
+
+ // Try to fetch any internally stored data first
+ if ( data === undefined && this.length ) {
+ data = jQuery.data( this[0], key );
+ data = dataAttr( this[0], key, data );
+ }
+
+ return data === undefined && parts[1] ?
+ this.data( parts[0] ) :
+ data;
+
+ } else {
+ return this.each(function() {
+ var $this = jQuery( this ),
+ args = [ parts[0], value ];
+
+ $this.triggerHandler( "setData" + parts[1] + "!", args );
+ jQuery.data( this, key, value );
+ $this.triggerHandler( "changeData" + parts[1] + "!", args );
+ });
+ }
+ },
+
+ removeData: function( key ) {
+ return this.each(function() {
+ jQuery.removeData( this, key );
+ });
+ }
+});
+
+function dataAttr( elem, key, data ) {
+ // If nothing was found internally, try to fetch any
+ // data from the HTML5 data-* attribute
+ if ( data === undefined && elem.nodeType === 1 ) {
+ data = elem.getAttribute( "data-" + key );
+
+ if ( typeof data === "string" ) {
+ try {
+ data = data === "true" ? true :
+ data === "false" ? false :
+ data === "null" ? null :
+ !jQuery.isNaN( data ) ? parseFloat( data ) :
+ rbrace.test( data ) ? jQuery.parseJSON( data ) :
+ data;
+ } catch( e ) {}
+
+ // Make sure we set the data so it isn't changed later
+ jQuery.data( elem, key, data );
+
+ } else {
+ data = undefined;
+ }
+ }
+
+ return data;
+}
+
+
+
+
+jQuery.extend({
+ queue: function( elem, type, data ) {
+ if ( !elem ) {
+ return;
+ }
+
+ type = (type || "fx") + "queue";
+ var q = jQuery.data( elem, type );
+
+ // Speed up dequeue by getting out quickly if this is just a lookup
+ if ( !data ) {
+ return q || [];
+ }
+
+ if ( !q || jQuery.isArray(data) ) {
+ q = jQuery.data( elem, type, jQuery.makeArray(data) );
+
+ } else {
+ q.push( data );
+ }
+
+ return q;
+ },
+
+ dequeue: function( elem, type ) {
+ type = type || "fx";
+
+ var queue = jQuery.queue( elem, type ),
+ fn = queue.shift();
+
+ // If the fx queue is dequeued, always remove the progress sentinel
+ if ( fn === "inprogress" ) {
+ fn = queue.shift();
+ }
+
+ if ( fn ) {
+ // Add a progress sentinel to prevent the fx queue from being
+ // automatically dequeued
+ if ( type === "fx" ) {
+ queue.unshift("inprogress");
+ }
+
+ fn.call(elem, function() {
+ jQuery.dequeue(elem, type);
+ });
+ }
+ }
+});
+
+jQuery.fn.extend({
+ queue: function( type, data ) {
+ if ( typeof type !== "string" ) {
+ data = type;
+ type = "fx";
+ }
+
+ if ( data === undefined ) {
+ return jQuery.queue( this[0], type );
+ }
+ return this.each(function( i ) {
+ var queue = jQuery.queue( this, type, data );
+
+ if ( type === "fx" && queue[0] !== "inprogress" ) {
+ jQuery.dequeue( this, type );
+ }
+ });
+ },
+ dequeue: function( type ) {
+ return this.each(function() {
+ jQuery.dequeue( this, type );
+ });
+ },
+
+ // Based off of the plugin by Clint Helfers, with permission.
+ // http://blindsignals.com/index.php/2009/07/jquery-delay/
+ delay: function( time, type ) {
+ time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
+ type = type || "fx";
+
+ return this.queue( type, function() {
+ var elem = this;
+ setTimeout(function() {
+ jQuery.dequeue( elem, type );
+ }, time );
+ });
+ },
+
+ clearQueue: function( type ) {
+ return this.queue( type || "fx", [] );
+ }
+});
+
+
+
+
+var rclass = /[\n\t]/g,
+ rspaces = /\s+/,
+ rreturn = /\r/g,
+ rspecialurl = /^(?:href|src|style)$/,
+ rtype = /^(?:button|input)$/i,
+ rfocusable = /^(?:button|input|object|select|textarea)$/i,
+ rclickable = /^a(?:rea)?$/i,
+ rradiocheck = /^(?:radio|checkbox)$/i;
+
+jQuery.props = {
+ "for": "htmlFor",
+ "class": "className",
+ readonly: "readOnly",
+ maxlength: "maxLength",
+ cellspacing: "cellSpacing",
+ rowspan: "rowSpan",
+ colspan: "colSpan",
+ tabindex: "tabIndex",
+ usemap: "useMap",
+ frameborder: "frameBorder"
+};
+
+jQuery.fn.extend({
+ attr: function( name, value ) {
+ return jQuery.access( this, name, value, true, jQuery.attr );
+ },
+
+ removeAttr: function( name, fn ) {
+ return this.each(function(){
+ jQuery.attr( this, name, "" );
+ if ( this.nodeType === 1 ) {
+ this.removeAttribute( name );
+ }
+ });
+ },
+
+ addClass: function( value ) {
+ if ( jQuery.isFunction(value) ) {
+ return this.each(function(i) {
+ var self = jQuery(this);
+ self.addClass( value.call(this, i, self.attr("class")) );
+ });
+ }
+
+ if ( value && typeof value === "string" ) {
+ var classNames = (value || "").split( rspaces );
+
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ var elem = this[i];
+
+ if ( elem.nodeType === 1 ) {
+ if ( !elem.className ) {
+ elem.className = value;
+
+ } else {
+ var className = " " + elem.className + " ",
+ setClass = elem.className;
+
+ for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
+ if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {
+ setClass += " " + classNames[c];
+ }
+ }
+ elem.className = jQuery.trim( setClass );
+ }
+ }
+ }
+ }
+
+ return this;
+ },
+
+ removeClass: function( value ) {
+ if ( jQuery.isFunction(value) ) {
+ return this.each(function(i) {
+ var self = jQuery(this);
+ self.removeClass( value.call(this, i, self.attr("class")) );
+ });
+ }
+
+ if ( (value && typeof value === "string") || value === undefined ) {
+ var classNames = (value || "").split( rspaces );
+
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ var elem = this[i];
+
+ if ( elem.nodeType === 1 && elem.className ) {
+ if ( value ) {
+ var className = (" " + elem.className + " ").replace(rclass, " ");
+ for ( var c = 0, cl = classNames.length; c < cl; c++ ) {
+ className = className.replace(" " + classNames[c] + " ", " ");
+ }
+ elem.className = jQuery.trim( className );
+
+ } else {
+ elem.className = "";
+ }
+ }
+ }
+ }
+
+ return this;
+ },
+
+ toggleClass: function( value, stateVal ) {
+ var type = typeof value,
+ isBool = typeof stateVal === "boolean";
+
+ if ( jQuery.isFunction( value ) ) {
+ return this.each(function(i) {
+ var self = jQuery(this);
+ self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal );
+ });
+ }
+
+ return this.each(function() {
+ if ( type === "string" ) {
+ // toggle individual class names
+ var className,
+ i = 0,
+ self = jQuery( this ),
+ state = stateVal,
+ classNames = value.split( rspaces );
+
+ while ( (className = classNames[ i++ ]) ) {
+ // check each className given, space seperated list
+ state = isBool ? state : !self.hasClass( className );
+ self[ state ? "addClass" : "removeClass" ]( className );
+ }
+
+ } else if ( type === "undefined" || type === "boolean" ) {
+ if ( this.className ) {
+ // store className if set
+ jQuery.data( this, "__className__", this.className );
+ }
+
+ // toggle whole className
+ this.className = this.className || value === false ? "" : jQuery.data( this, "__className__" ) || "";
+ }
+ });
+ },
+
+ hasClass: function( selector ) {
+ var className = " " + selector + " ";
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
+ return true;
+ }
+ }
+
+ return false;
+ },
+
+ val: function( value ) {
+ if ( !arguments.length ) {
+ var elem = this[0];
+
+ if ( elem ) {
+ if ( jQuery.nodeName( elem, "option" ) ) {
+ // attributes.value is undefined in Blackberry 4.7 but
+ // uses .value. See #6932
+ var val = elem.attributes.value;
+ return !val || val.specified ? elem.value : elem.text;
+ }
+
+ // We need to handle select boxes special
+ if ( jQuery.nodeName( elem, "select" ) ) {
+ var index = elem.selectedIndex,
+ values = [],
+ options = elem.options,
+ one = elem.type === "select-one";
+
+ // Nothing was selected
+ if ( index < 0 ) {
+ return null;
+ }
+
+ // Loop through all the selected options
+ for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
+ var option = options[ i ];
+
+ // Don't return options that are disabled or in a disabled optgroup
+ if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
+ (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
+
+ // Get the specific value for the option
+ value = jQuery(option).val();
+
+ // We don't need an array for one selects
+ if ( one ) {
+ return value;
+ }
+
+ // Multi-Selects return an array
+ values.push( value );
+ }
+ }
+
+ return values;
+ }
+
+ // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
+ if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) {
+ return elem.getAttribute("value") === null ? "on" : elem.value;
+ }
+
+
+ // Everything else, we just grab the value
+ return (elem.value || "").replace(rreturn, "");
+
+ }
+
+ return undefined;
+ }
+
+ var isFunction = jQuery.isFunction(value);
+
+ return this.each(function(i) {
+ var self = jQuery(this), val = value;
+
+ if ( this.nodeType !== 1 ) {
+ return;
+ }
+
+ if ( isFunction ) {
+ val = value.call(this, i, self.val());
+ }
+
+ // Treat null/undefined as ""; convert numbers to string
+ if ( val == null ) {
+ val = "";
+ } else if ( typeof val === "number" ) {
+ val += "";
+ } else if ( jQuery.isArray(val) ) {
+ val = jQuery.map(val, function (value) {
+ return value == null ? "" : value + "";
+ });
+ }
+
+ if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) {
+ this.checked = jQuery.inArray( self.val(), val ) >= 0;
+
+ } else if ( jQuery.nodeName( this, "select" ) ) {
+ var values = jQuery.makeArray(val);
+
+ jQuery( "option", this ).each(function() {
+ this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
+ });
+
+ if ( !values.length ) {
+ this.selectedIndex = -1;
+ }
+
+ } else {
+ this.value = val;
+ }
+ });
+ }
+});
+
+jQuery.extend({
+ attrFn: {
+ val: true,
+ css: true,
+ html: true,
+ text: true,
+ data: true,
+ width: true,
+ height: true,
+ offset: true
+ },
+
+ attr: function( elem, name, value, pass ) {
+ // don't set attributes on text and comment nodes
+ if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
+ return undefined;
+ }
+
+ if ( pass && name in jQuery.attrFn ) {
+ return jQuery(elem)[name](value);
+ }
+
+ var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ),
+ // Whether we are setting (or getting)
+ set = value !== undefined;
+
+ // Try to normalize/fix the name
+ name = notxml && jQuery.props[ name ] || name;
+
+ // These attributes require special treatment
+ var special = rspecialurl.test( name );
+
+ // Safari mis-reports the default selected property of an option
+ // Accessing the parent's selectedIndex property fixes it
+ if ( name === "selected" && !jQuery.support.optSelected ) {
+ var parent = elem.parentNode;
+ if ( parent ) {
+ parent.selectedIndex;
+
+ // Make sure that it also works with optgroups, see #5701
+ if ( parent.parentNode ) {
+ parent.parentNode.selectedIndex;
+ }
+ }
+ }
+
+ // If applicable, access the attribute via the DOM 0 way
+ // 'in' checks fail in Blackberry 4.7 #6931
+ if ( (name in elem || elem[ name ] !== undefined) && notxml && !special ) {
+ if ( set ) {
+ // We can't allow the type property to be changed (since it causes problems in IE)
+ if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) {
+ jQuery.error( "type property can't be changed" );
+ }
+
+ if ( value === null ) {
+ if ( elem.nodeType === 1 ) {
+ elem.removeAttribute( name );
+ }
+
+ } else {
+ elem[ name ] = value;
+ }
+ }
+
+ // browsers index elements by id/name on forms, give priority to attributes.
+ if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) {
+ return elem.getAttributeNode( name ).nodeValue;
+ }
+
+ // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
+ // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
+ if ( name === "tabIndex" ) {
+ var attributeNode = elem.getAttributeNode( "tabIndex" );
+
+ return attributeNode && attributeNode.specified ?
+ attributeNode.value :
+ rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
+ 0 :
+ undefined;
+ }
+
+ return elem[ name ];
+ }
+
+ if ( !jQuery.support.style && notxml && name === "style" ) {
+ if ( set ) {
+ elem.style.cssText = "" + value;
+ }
+
+ return elem.style.cssText;
+ }
+
+ if ( set ) {
+ // convert the value to a string (all browsers do this but IE) see #1070
+ elem.setAttribute( name, "" + value );
+ }
+
+ // Ensure that missing attributes return undefined
+ // Blackberry 4.7 returns "" from getAttribute #6938
+ if ( !elem.attributes[ name ] && (elem.hasAttribute && !elem.hasAttribute( name )) ) {
+ return undefined;
+ }
+
+ var attr = !jQuery.support.hrefNormalized && notxml && special ?
+ // Some attributes require a special call on IE
+ elem.getAttribute( name, 2 ) :
+ elem.getAttribute( name );
+
+ // Non-existent attributes return null, we normalize to undefined
+ return attr === null ? undefined : attr;
+ }
+});
+
+
+
+
+var rnamespaces = /\.(.*)$/,
+ rformElems = /^(?:textarea|input|select)$/i,
+ rperiod = /\./g,
+ rspace = / /g,
+ rescape = /[^\w\s.|`]/g,
+ fcleanup = function( nm ) {
+ return nm.replace(rescape, "\\$&");
+ },
+ focusCounts = { focusin: 0, focusout: 0 };
+
+/*
+ * A number of helper functions used for managing events.
+ * Many of the ideas behind this code originated from
+ * Dean Edwards' addEvent library.
+ */
+jQuery.event = {
+
+ // Bind an event to an element
+ // Original by Dean Edwards
+ add: function( elem, types, handler, data ) {
+ if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+ return;
+ }
+
+ // For whatever reason, IE has trouble passing the window object
+ // around, causing it to be cloned in the process
+ if ( jQuery.isWindow( elem ) && ( elem !== window && !elem.frameElement ) ) {
+ elem = window;
+ }
+
+ if ( handler === false ) {
+ handler = returnFalse;
+ } else if ( !handler ) {
+ // Fixes bug #7229. Fix recommended by jdalton
+ return;
+ }
+
+ var handleObjIn, handleObj;
+
+ if ( handler.handler ) {
+ handleObjIn = handler;
+ handler = handleObjIn.handler;
+ }
+
+ // Make sure that the function being executed has a unique ID
+ if ( !handler.guid ) {
+ handler.guid = jQuery.guid++;
+ }
+
+ // Init the element's event structure
+ var elemData = jQuery.data( elem );
+
+ // If no elemData is found then we must be trying to bind to one of the
+ // banned noData elements
+ if ( !elemData ) {
+ return;
+ }
+
+ // Use a key less likely to result in collisions for plain JS objects.
+ // Fixes bug #7150.
+ var eventKey = elem.nodeType ? "events" : "__events__",
+ events = elemData[ eventKey ],
+ eventHandle = elemData.handle;
+
+ if ( typeof events === "function" ) {
+ // On plain objects events is a fn that holds the the data
+ // which prevents this data from being JSON serialized
+ // the function does not need to be called, it just contains the data
+ eventHandle = events.handle;
+ events = events.events;
+
+ } else if ( !events ) {
+ if ( !elem.nodeType ) {
+ // On plain objects, create a fn that acts as the holder
+ // of the values to avoid JSON serialization of event data
+ elemData[ eventKey ] = elemData = function(){};
+ }
+
+ elemData.events = events = {};
+ }
+
+ if ( !eventHandle ) {
+ elemData.handle = eventHandle = function() {
+ // Handle the second event of a trigger and when
+ // an event is called after a page has unloaded
+ return typeof jQuery !== "undefined" && !jQuery.event.triggered ?
+ jQuery.event.handle.apply( eventHandle.elem, arguments ) :
+ undefined;
+ };
+ }
+
+ // Add elem as a property of the handle function
+ // This is to prevent a memory leak with non-native events in IE.
+ eventHandle.elem = elem;
+
+ // Handle multiple events separated by a space
+ // jQuery(...).bind("mouseover mouseout", fn);
+ types = types.split(" ");
+
+ var type, i = 0, namespaces;
+
+ while ( (type = types[ i++ ]) ) {
+ handleObj = handleObjIn ?
+ jQuery.extend({}, handleObjIn) :
+ { handler: handler, data: data };
+
+ // Namespaced event handlers
+ if ( type.indexOf(".") > -1 ) {
+ namespaces = type.split(".");
+ type = namespaces.shift();
+ handleObj.namespace = namespaces.slice(0).sort().join(".");
+
+ } else {
+ namespaces = [];
+ handleObj.namespace = "";
+ }
+
+ handleObj.type = type;
+ if ( !handleObj.guid ) {
+ handleObj.guid = handler.guid;
+ }
+
+ // Get the current list of functions bound to this event
+ var handlers = events[ type ],
+ special = jQuery.event.special[ type ] || {};
+
+ // Init the event handler queue
+ if ( !handlers ) {
+ handlers = events[ type ] = [];
+
+ // Check for a special event handler
+ // Only use addEventListener/attachEvent if the special
+ // events handler returns false
+ if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
+ // Bind the global event handler to the element
+ if ( elem.addEventListener ) {
+ elem.addEventListener( type, eventHandle, false );
+
+ } else if ( elem.attachEvent ) {
+ elem.attachEvent( "on" + type, eventHandle );
+ }
+ }
+ }
+
+ if ( special.add ) {
+ special.add.call( elem, handleObj );
+
+ if ( !handleObj.handler.guid ) {
+ handleObj.handler.guid = handler.guid;
+ }
+ }
+
+ // Add the function to the element's handler list
+ handlers.push( handleObj );
+
+ // Keep track of which events have been used, for global triggering
+ jQuery.event.global[ type ] = true;
+ }
+
+ // Nullify elem to prevent memory leaks in IE
+ elem = null;
+ },
+
+ global: {},
+
+ // Detach an event or set of events from an element
+ remove: function( elem, types, handler, pos ) {
+ // don't do events on text and comment nodes
+ if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+ return;
+ }
+
+ if ( handler === false ) {
+ handler = returnFalse;
+ }
+
+ var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,
+ eventKey = elem.nodeType ? "events" : "__events__",
+ elemData = jQuery.data( elem ),
+ events = elemData && elemData[ eventKey ];
+
+ if ( !elemData || !events ) {
+ return;
+ }
+
+ if ( typeof events === "function" ) {
+ elemData = events;
+ events = events.events;
+ }
+
+ // types is actually an event object here
+ if ( types && types.type ) {
+ handler = types.handler;
+ types = types.type;
+ }
+
+ // Unbind all events for the element
+ if ( !types || typeof types === "string" && types.charAt(0) === "." ) {
+ types = types || "";
+
+ for ( type in events ) {
+ jQuery.event.remove( elem, type + types );
+ }
+
+ return;
+ }
+
+ // Handle multiple events separated by a space
+ // jQuery(...).unbind("mouseover mouseout", fn);
+ types = types.split(" ");
+
+ while ( (type = types[ i++ ]) ) {
+ origType = type;
+ handleObj = null;
+ all = type.indexOf(".") < 0;
+ namespaces = [];
+
+ if ( !all ) {
+ // Namespaced event handlers
+ namespaces = type.split(".");
+ type = namespaces.shift();
+
+ namespace = new RegExp("(^|\\.)" +
+ jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)");
+ }
+
+ eventType = events[ type ];
+
+ if ( !eventType ) {
+ continue;
+ }
+
+ if ( !handler ) {
+ for ( j = 0; j < eventType.length; j++ ) {
+ handleObj = eventType[ j ];
+
+ if ( all || namespace.test( handleObj.namespace ) ) {
+ jQuery.event.remove( elem, origType, handleObj.handler, j );
+ eventType.splice( j--, 1 );
+ }
+ }
+
+ continue;
+ }
+
+ special = jQuery.event.special[ type ] || {};
+
+ for ( j = pos || 0; j < eventType.length; j++ ) {
+ handleObj = eventType[ j ];
+
+ if ( handler.guid === handleObj.guid ) {
+ // remove the given handler for the given type
+ if ( all || namespace.test( handleObj.namespace ) ) {
+ if ( pos == null ) {
+ eventType.splice( j--, 1 );
+ }
+
+ if ( special.remove ) {
+ special.remove.call( elem, handleObj );
+ }
+ }
+
+ if ( pos != null ) {
+ break;
+ }
+ }
+ }
+
+ // remove generic event handler if no more handlers exist
+ if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {
+ if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
+ jQuery.removeEvent( elem, type, elemData.handle );
+ }
+
+ ret = null;
+ delete events[ type ];
+ }
+ }
+
+ // Remove the expando if it's no longer used
+ if ( jQuery.isEmptyObject( events ) ) {
+ var handle = elemData.handle;
+ if ( handle ) {
+ handle.elem = null;
+ }
+
+ delete elemData.events;
+ delete elemData.handle;
+
+ if ( typeof elemData === "function" ) {
+ jQuery.removeData( elem, eventKey );
+
+ } else if ( jQuery.isEmptyObject( elemData ) ) {
+ jQuery.removeData( elem );
+ }
+ }
+ },
+
+ // bubbling is internal
+ trigger: function( event, data, elem /*, bubbling */ ) {
+ // Event object or event type
+ var type = event.type || event,
+ bubbling = arguments[3];
+
+ if ( !bubbling ) {
+ event = typeof event === "object" ?
+ // jQuery.Event object
+ event[ jQuery.expando ] ? event :
+ // Object literal
+ jQuery.extend( jQuery.Event(type), event ) :
+ // Just the event type (string)
+ jQuery.Event(type);
+
+ if ( type.indexOf("!") >= 0 ) {
+ event.type = type = type.slice(0, -1);
+ event.exclusive = true;
+ }
+
+ // Handle a global trigger
+ if ( !elem ) {
+ // Don't bubble custom events when global (to avoid too much overhead)
+ event.stopPropagation();
+
+ // Only trigger if we've ever bound an event for it
+ if ( jQuery.event.global[ type ] ) {
+ jQuery.each( jQuery.cache, function() {
+ if ( this.events && this.events[type] ) {
+ jQuery.event.trigger( event, data, this.handle.elem );
+ }
+ });
+ }
+ }
+
+ // Handle triggering a single element
+
+ // don't do events on text and comment nodes
+ if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
+ return undefined;
+ }
+
+ // Clean up in case it is reused
+ event.result = undefined;
+ event.target = elem;
+
+ // Clone the incoming data, if any
+ data = jQuery.makeArray( data );
+ data.unshift( event );
+ }
+
+ event.currentTarget = elem;
+
+ // Trigger the event, it is assumed that "handle" is a function
+ var handle = elem.nodeType ?
+ jQuery.data( elem, "handle" ) :
+ (jQuery.data( elem, "__events__" ) || {}).handle;
+
+ if ( handle ) {
+ handle.apply( elem, data );
+ }
+
+ var parent = elem.parentNode || elem.ownerDocument;
+
+ // Trigger an inline bound script
+ try {
+ if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) {
+ if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) {
+ event.result = false;
+ event.preventDefault();
+ }
+ }
+
+ // prevent IE from throwing an error for some elements with some event types, see #3533
+ } catch (inlineError) {}
+
+ if ( !event.isPropagationStopped() && parent ) {
+ jQuery.event.trigger( event, data, parent, true );
+
+ } else if ( !event.isDefaultPrevented() ) {
+ var old,
+ target = event.target,
+ targetType = type.replace( rnamespaces, "" ),
+ isClick = jQuery.nodeName( target, "a" ) && targetType === "click",
+ special = jQuery.event.special[ targetType ] || {};
+
+ if ( (!special._default || special._default.call( elem, event ) === false) &&
+ !isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) {
+
+ try {
+ if ( target[ targetType ] ) {
+ // Make sure that we don't accidentally re-trigger the onFOO events
+ old = target[ "on" + targetType ];
+
+ if ( old ) {
+ target[ "on" + targetType ] = null;
+ }
+
+ jQuery.event.triggered = true;
+ target[ targetType ]();
+ }
+
+ // prevent IE from throwing an error for some elements with some event types, see #3533
+ } catch (triggerError) {}
+
+ if ( old ) {
+ target[ "on" + targetType ] = old;
+ }
+
+ jQuery.event.triggered = false;
+ }
+ }
+ },
+
+ handle: function( event ) {
+ var all, handlers, namespaces, namespace_re, events,
+ namespace_sort = [],
+ args = jQuery.makeArray( arguments );
+
+ event = args[0] = jQuery.event.fix( event || window.event );
+ event.currentTarget = this;
+
+ // Namespaced event handlers
+ all = event.type.indexOf(".") < 0 && !event.exclusive;
+
+ if ( !all ) {
+ namespaces = event.type.split(".");
+ event.type = namespaces.shift();
+ namespace_sort = namespaces.slice(0).sort();
+ namespace_re = new RegExp("(^|\\.)" + namespace_sort.join("\\.(?:.*\\.)?") + "(\\.|$)");
+ }
+
+ event.namespace = event.namespace || namespace_sort.join(".");
+
+ events = jQuery.data(this, this.nodeType ? "events" : "__events__");
+
+ if ( typeof events === "function" ) {
+ events = events.events;
+ }
+
+ handlers = (events || {})[ event.type ];
+
+ if ( events && handlers ) {
+ // Clone the handlers to prevent manipulation
+ handlers = handlers.slice(0);
+
+ for ( var j = 0, l = handlers.length; j < l; j++ ) {
+ var handleObj = handlers[ j ];
+
+ // Filter the functions by class
+ if ( all || namespace_re.test( handleObj.namespace ) ) {
+ // Pass in a reference to the handler function itself
+ // So that we can later remove it
+ event.handler = handleObj.handler;
+ event.data = handleObj.data;
+ event.handleObj = handleObj;
+
+ var ret = handleObj.handler.apply( this, args );
+
+ if ( ret !== undefined ) {
+ event.result = ret;
+ if ( ret === false ) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ }
+
+ if ( event.isImmediatePropagationStopped() ) {
+ break;
+ }
+ }
+ }
+ }
+
+ return event.result;
+ },
+
+ props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
+
+ fix: function( event ) {
+ if ( event[ jQuery.expando ] ) {
+ return event;
+ }
+
+ // store a copy of the original event object
+ // and "clone" to set read-only properties
+ var originalEvent = event;
+ event = jQuery.Event( originalEvent );
+
+ for ( var i = this.props.length, prop; i; ) {
+ prop = this.props[ --i ];
+ event[ prop ] = originalEvent[ prop ];
+ }
+
+ // Fix target property, if necessary
+ if ( !event.target ) {
+ // Fixes #1925 where srcElement might not be defined either
+ event.target = event.srcElement || document;
+ }
+
+ // check if target is a textnode (safari)
+ if ( event.target.nodeType === 3 ) {
+ event.target = event.target.parentNode;
+ }
+
+ // Add relatedTarget, if necessary
+ if ( !event.relatedTarget && event.fromElement ) {
+ event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;
+ }
+
+ // Calculate pageX/Y if missing and clientX/Y available
+ if ( event.pageX == null && event.clientX != null ) {
+ var doc = document.documentElement,
+ body = document.body;
+
+ event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
+ event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
+ }
+
+ // Add which for key events
+ if ( event.which == null && (event.charCode != null || event.keyCode != null) ) {
+ event.which = event.charCode != null ? event.charCode : event.keyCode;
+ }
+
+ // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
+ if ( !event.metaKey && event.ctrlKey ) {
+ event.metaKey = event.ctrlKey;
+ }
+
+ // Add which for click: 1 === left; 2 === middle; 3 === right
+ // Note: button is not normalized, so don't use it
+ if ( !event.which && event.button !== undefined ) {
+ event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
+ }
+
+ return event;
+ },
+
+ // Deprecated, use jQuery.guid instead
+ guid: 1E8,
+
+ // Deprecated, use jQuery.proxy instead
+ proxy: jQuery.proxy,
+
+ special: {
+ ready: {
+ // Make sure the ready event is setup
+ setup: jQuery.bindReady,
+ teardown: jQuery.noop
+ },
+
+ live: {
+ add: function( handleObj ) {
+ jQuery.event.add( this,
+ liveConvert( handleObj.origType, handleObj.selector ),
+ jQuery.extend({}, handleObj, {handler: liveHandler, guid: handleObj.handler.guid}) );
+ },
+
+ remove: function( handleObj ) {
+ jQuery.event.remove( this, liveConvert( handleObj.origType, handleObj.selector ), handleObj );
+ }
+ },
+
+ beforeunload: {
+ setup: function( data, namespaces, eventHandle ) {
+ // We only want to do this special case on windows
+ if ( jQuery.isWindow( this ) ) {
+ this.onbeforeunload = eventHandle;
+ }
+ },
+
+ teardown: function( namespaces, eventHandle ) {
+ if ( this.onbeforeunload === eventHandle ) {
+ this.onbeforeunload = null;
+ }
+ }
+ }
+ }
+};
+
+jQuery.removeEvent = document.removeEventListener ?
+ function( elem, type, handle ) {
+ if ( elem.removeEventListener ) {
+ elem.removeEventListener( type, handle, false );
+ }
+ } :
+ function( elem, type, handle ) {
+ if ( elem.detachEvent ) {
+ elem.detachEvent( "on" + type, handle );
+ }
+ };
+
+jQuery.Event = function( src ) {
+ // Allow instantiation without the 'new' keyword
+ if ( !this.preventDefault ) {
+ return new jQuery.Event( src );
+ }
+
+ // Event object
+ if ( src && src.type ) {
+ this.originalEvent = src;
+ this.type = src.type;
+ // Event type
+ } else {
+ this.type = src;
+ }
+
+ // timeStamp is buggy for some events on Firefox(#3843)
+ // So we won't rely on the native value
+ this.timeStamp = jQuery.now();
+
+ // Mark it as fixed
+ this[ jQuery.expando ] = true;
+};
+
+function returnFalse() {
+ return false;
+}
+function returnTrue() {
+ return true;
+}
+
+// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
+// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
+jQuery.Event.prototype = {
+ preventDefault: function() {
+ this.isDefaultPrevented = returnTrue;
+
+ var e = this.originalEvent;
+ if ( !e ) {
+ return;
+ }
+
+ // if preventDefault exists run it on the original event
+ if ( e.preventDefault ) {
+ e.preventDefault();
+
+ // otherwise set the returnValue property of the original event to false (IE)
+ } else {
+ e.returnValue = false;
+ }
+ },
+ stopPropagation: function() {
+ this.isPropagationStopped = returnTrue;
+
+ var e = this.originalEvent;
+ if ( !e ) {
+ return;
+ }
+ // if stopPropagation exists run it on the original event
+ if ( e.stopPropagation ) {
+ e.stopPropagation();
+ }
+ // otherwise set the cancelBubble property of the original event to true (IE)
+ e.cancelBubble = true;
+ },
+ stopImmediatePropagation: function() {
+ this.isImmediatePropagationStopped = returnTrue;
+ this.stopPropagation();
+ },
+ isDefaultPrevented: returnFalse,
+ isPropagationStopped: returnFalse,
+ isImmediatePropagationStopped: returnFalse
+};
+
+// Checks if an event happened on an element within another element
+// Used in jQuery.event.special.mouseenter and mouseleave handlers
+var withinElement = function( event ) {
+ // Check if mouse(over|out) are still within the same parent element
+ var parent = event.relatedTarget;
+
+ // Firefox sometimes assigns relatedTarget a XUL element
+ // which we cannot access the parentNode property of
+ try {
+ // Traverse up the tree
+ while ( parent && parent !== this ) {
+ parent = parent.parentNode;
+ }
+
+ if ( parent !== this ) {
+ // set the correct event type
+ event.type = event.data;
+
+ // handle event if we actually just moused on to a non sub-element
+ jQuery.event.handle.apply( this, arguments );
+ }
+
+ // assuming we've left the element since we most likely mousedover a xul element
+ } catch(e) { }
+},
+
+// In case of event delegation, we only need to rename the event.type,
+// liveHandler will take care of the rest.
+delegate = function( event ) {
+ event.type = event.data;
+ jQuery.event.handle.apply( this, arguments );
+};
+
+// Create mouseenter and mouseleave events
+jQuery.each({
+ mouseenter: "mouseover",
+ mouseleave: "mouseout"
+}, function( orig, fix ) {
+ jQuery.event.special[ orig ] = {
+ setup: function( data ) {
+ jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );
+ },
+ teardown: function( data ) {
+ jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );
+ }
+ };
+});
+
+// submit delegation
+if ( !jQuery.support.submitBubbles ) {
+
+ jQuery.event.special.submit = {
+ setup: function( data, namespaces ) {
+ if ( this.nodeName.toLowerCase() !== "form" ) {
+ jQuery.event.add(this, "click.specialSubmit", function( e ) {
+ var elem = e.target,
+ type = elem.type;
+
+ if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {
+ e.liveFired = undefined;
+ return trigger( "submit", this, arguments );
+ }
+ });
+
+ jQuery.event.add(this, "keypress.specialSubmit", function( e ) {
+ var elem = e.target,
+ type = elem.type;
+
+ if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {
+ e.liveFired = undefined;
+ return trigger( "submit", this, arguments );
+ }
+ });
+
+ } else {
+ return false;
+ }
+ },
+
+ teardown: function( namespaces ) {
+ jQuery.event.remove( this, ".specialSubmit" );
+ }
+ };
+
+}
+
+// change delegation, happens here so we have bind.
+if ( !jQuery.support.changeBubbles ) {
+
+ var changeFilters,
+
+ getVal = function( elem ) {
+ var type = elem.type, val = elem.value;
+
+ if ( type === "radio" || type === "checkbox" ) {
+ val = elem.checked;
+
+ } else if ( type === "select-multiple" ) {
+ val = elem.selectedIndex > -1 ?
+ jQuery.map( elem.options, function( elem ) {
+ return elem.selected;
+ }).join("-") :
+ "";
+
+ } else if ( elem.nodeName.toLowerCase() === "select" ) {
+ val = elem.selectedIndex;
+ }
+
+ return val;
+ },
+
+ testChange = function testChange( e ) {
+ var elem = e.target, data, val;
+
+ if ( !rformElems.test( elem.nodeName ) || elem.readOnly ) {
+ return;
+ }
+
+ data = jQuery.data( elem, "_change_data" );
+ val = getVal(elem);
+
+ // the current data will be also retrieved by beforeactivate
+ if ( e.type !== "focusout" || elem.type !== "radio" ) {
+ jQuery.data( elem, "_change_data", val );
+ }
+
+ if ( data === undefined || val === data ) {
+ return;
+ }
+
+ if ( data != null || val ) {
+ e.type = "change";
+ e.liveFired = undefined;
+ return jQuery.event.trigger( e, arguments[1], elem );
+ }
+ };
+
+ jQuery.event.special.change = {
+ filters: {
+ focusout: testChange,
+
+ beforedeactivate: testChange,
+
+ click: function( e ) {
+ var elem = e.target, type = elem.type;
+
+ if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) {
+ return testChange.call( this, e );
+ }
+ },
+
+ // Change has to be called before submit
+ // Keydown will be called before keypress, which is used in submit-event delegation
+ keydown: function( e ) {
+ var elem = e.target, type = elem.type;
+
+ if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") ||
+ (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||
+ type === "select-multiple" ) {
+ return testChange.call( this, e );
+ }
+ },
+
+ // Beforeactivate happens also before the previous element is blurred
+ // with this event you can't trigger a change event, but you can store
+ // information
+ beforeactivate: function( e ) {
+ var elem = e.target;
+ jQuery.data( elem, "_change_data", getVal(elem) );
+ }
+ },
+
+ setup: function( data, namespaces ) {
+ if ( this.type === "file" ) {
+ return false;
+ }
+
+ for ( var type in changeFilters ) {
+ jQuery.event.add( this, type + ".specialChange", changeFilters[type] );
+ }
+
+ return rformElems.test( this.nodeName );
+ },
+
+ teardown: function( namespaces ) {
+ jQuery.event.remove( this, ".specialChange" );
+
+ return rformElems.test( this.nodeName );
+ }
+ };
+
+ changeFilters = jQuery.event.special.change.filters;
+
+ // Handle when the input is .focus()'d
+ changeFilters.focus = changeFilters.beforeactivate;
+}
+
+function trigger( type, elem, args ) {
+ args[0].type = type;
+ return jQuery.event.handle.apply( elem, args );
+}
+
+// Create "bubbling" focus and blur events
+if ( document.addEventListener ) {
+ jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
+ jQuery.event.special[ fix ] = {
+ setup: function() {
+ if ( focusCounts[fix]++ === 0 ) {
+ document.addEventListener( orig, handler, true );
+ }
+ },
+ teardown: function() {
+ if ( --focusCounts[fix] === 0 ) {
+ document.removeEventListener( orig, handler, true );
+ }
+ }
+ };
+
+ function handler( e ) {
+ e = jQuery.event.fix( e );
+ e.type = fix;
+ return jQuery.event.trigger( e, null, e.target );
+ }
+ });
+}
+
+jQuery.each(["bind", "one"], function( i, name ) {
+ jQuery.fn[ name ] = function( type, data, fn ) {
+ // Handle object literals
+ if ( typeof type === "object" ) {
+ for ( var key in type ) {
+ this[ name ](key, data, type[key], fn);
+ }
+ return this;
+ }
+
+ if ( jQuery.isFunction( data ) || data === false ) {
+ fn = data;
+ data = undefined;
+ }
+
+ var handler = name === "one" ? jQuery.proxy( fn, function( event ) {
+ jQuery( this ).unbind( event, handler );
+ return fn.apply( this, arguments );
+ }) : fn;
+
+ if ( type === "unload" && name !== "one" ) {
+ this.one( type, data, fn );
+
+ } else {
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ jQuery.event.add( this[i], type, handler, data );
+ }
+ }
+
+ return this;
+ };
+});
+
+jQuery.fn.extend({
+ unbind: function( type, fn ) {
+ // Handle object literals
+ if ( typeof type === "object" && !type.preventDefault ) {
+ for ( var key in type ) {
+ this.unbind(key, type[key]);
+ }
+
+ } else {
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ jQuery.event.remove( this[i], type, fn );
+ }
+ }
+
+ return this;
+ },
+
+ delegate: function( selector, types, data, fn ) {
+ return this.live( types, data, fn, selector );
+ },
+
+ undelegate: function( selector, types, fn ) {
+ if ( arguments.length === 0 ) {
+ return this.unbind( "live" );
+
+ } else {
+ return this.die( types, null, fn, selector );
+ }
+ },
+
+ trigger: function( type, data ) {
+ return this.each(function() {
+ jQuery.event.trigger( type, data, this );
+ });
+ },
+
+ triggerHandler: function( type, data ) {
+ if ( this[0] ) {
+ var event = jQuery.Event( type );
+ event.preventDefault();
+ event.stopPropagation();
+ jQuery.event.trigger( event, data, this[0] );
+ return event.result;
+ }
+ },
+
+ toggle: function( fn ) {
+ // Save reference to arguments for access in closure
+ var args = arguments,
+ i = 1;
+
+ // link all the functions, so any of them can unbind this click handler
+ while ( i < args.length ) {
+ jQuery.proxy( fn, args[ i++ ] );
+ }
+
+ return this.click( jQuery.proxy( fn, function( event ) {
+ // Figure out which function to execute
+ var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
+ jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
+
+ // Make sure that clicks stop
+ event.preventDefault();
+
+ // and execute the function
+ return args[ lastToggle ].apply( this, arguments ) || false;
+ }));
+ },
+
+ hover: function( fnOver, fnOut ) {
+ return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
+ }
+});
+
+var liveMap = {
+ focus: "focusin",
+ blur: "focusout",
+ mouseenter: "mouseover",
+ mouseleave: "mouseout"
+};
+
+jQuery.each(["live", "die"], function( i, name ) {
+ jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {
+ var type, i = 0, match, namespaces, preType,
+ selector = origSelector || this.selector,
+ context = origSelector ? this : jQuery( this.context );
+
+ if ( typeof types === "object" && !types.preventDefault ) {
+ for ( var key in types ) {
+ context[ name ]( key, data, types[key], selector );
+ }
+
+ return this;
+ }
+
+ if ( jQuery.isFunction( data ) ) {
+ fn = data;
+ data = undefined;
+ }
+
+ types = (types || "").split(" ");
+
+ while ( (type = types[ i++ ]) != null ) {
+ match = rnamespaces.exec( type );
+ namespaces = "";
+
+ if ( match ) {
+ namespaces = match[0];
+ type = type.replace( rnamespaces, "" );
+ }
+
+ if ( type === "hover" ) {
+ types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );
+ continue;
+ }
+
+ preType = type;
+
+ if ( type === "focus" || type === "blur" ) {
+ types.push( liveMap[ type ] + namespaces );
+ type = type + namespaces;
+
+ } else {
+ type = (liveMap[ type ] || type) + namespaces;
+ }
+
+ if ( name === "live" ) {
+ // bind live handler
+ for ( var j = 0, l = context.length; j < l; j++ ) {
+ jQuery.event.add( context[j], "live." + liveConvert( type, selector ),
+ { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );
+ }
+
+ } else {
+ // unbind live handler
+ context.unbind( "live." + liveConvert( type, selector ), fn );
+ }
+ }
+
+ return this;
+ };
+});
+
+function liveHandler( event ) {
+ var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret,
+ elems = [],
+ selectors = [],
+ events = jQuery.data( this, this.nodeType ? "events" : "__events__" );
+
+ if ( typeof events === "function" ) {
+ events = events.events;
+ }
+
+ // Make sure we avoid non-left-click bubbling in Firefox (#3861)
+ if ( event.liveFired === this || !events || !events.live || event.button && event.type === "click" ) {
+ return;
+ }
+
+ if ( event.namespace ) {
+ namespace = new RegExp("(^|\\.)" + event.namespace.split(".").join("\\.(?:.*\\.)?") + "(\\.|$)");
+ }
+
+ event.liveFired = this;
+
+ var live = events.live.slice(0);
+
+ for ( j = 0; j < live.length; j++ ) {
+ handleObj = live[j];
+
+ if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {
+ selectors.push( handleObj.selector );
+
+ } else {
+ live.splice( j--, 1 );
+ }
+ }
+
+ match = jQuery( event.target ).closest( selectors, event.currentTarget );
+
+ for ( i = 0, l = match.length; i < l; i++ ) {
+ close = match[i];
+
+ for ( j = 0; j < live.length; j++ ) {
+ handleObj = live[j];
+
+ if ( close.selector === handleObj.selector && (!namespace || namespace.test( handleObj.namespace )) ) {
+ elem = close.elem;
+ related = null;
+
+ // Those two events require additional checking
+ if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {
+ event.type = handleObj.preType;
+ related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];
+ }
+
+ if ( !related || related !== elem ) {
+ elems.push({ elem: elem, handleObj: handleObj, level: close.level });
+ }
+ }
+ }
+ }
+
+ for ( i = 0, l = elems.length; i < l; i++ ) {
+ match = elems[i];
+
+ if ( maxLevel && match.level > maxLevel ) {
+ break;
+ }
+
+ event.currentTarget = match.elem;
+ event.data = match.handleObj.data;
+ event.handleObj = match.handleObj;
+
+ ret = match.handleObj.origHandler.apply( match.elem, arguments );
+
+ if ( ret === false || event.isPropagationStopped() ) {
+ maxLevel = match.level;
+
+ if ( ret === false ) {
+ stop = false;
+ }
+ if ( event.isImmediatePropagationStopped() ) {
+ break;
+ }
+ }
+ }
+
+ return stop;
+}
+
+function liveConvert( type, selector ) {
+ return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspace, "&");
+}
+
+jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
+ "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
+ "change select submit keydown keypress keyup error").split(" "), function( i, name ) {
+
+ // Handle event binding
+ jQuery.fn[ name ] = function( data, fn ) {
+ if ( fn == null ) {
+ fn = data;
+ data = null;
+ }
+
+ return arguments.length > 0 ?
+ this.bind( name, data, fn ) :
+ this.trigger( name );
+ };
+
+ if ( jQuery.attrFn ) {
+ jQuery.attrFn[ name ] = true;
+ }
+});
+
+// Prevent memory leaks in IE
+// Window isn't included so as not to unbind existing unload events
+// More info:
+// - http://isaacschlueter.com/2006/10/msie-memory-leaks/
+if ( window.attachEvent && !window.addEventListener ) {
+ jQuery(window).bind("unload", function() {
+ for ( var id in jQuery.cache ) {
+ if ( jQuery.cache[ id ].handle ) {
+ // Try/Catch is to handle iframes being unloaded, see #4280
+ try {
+ jQuery.event.remove( jQuery.cache[ id ].handle.elem );
+ } catch(e) {}
+ }
+ }
+ });
+}
+
+
+/*!
+ * Sizzle CSS Selector Engine - v1.0
+ * Copyright 2009, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ * More information: http://sizzlejs.com/
+ */
+(function(){
+
+var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
+ done = 0,
+ toString = Object.prototype.toString,
+ hasDuplicate = false,
+ baseHasDuplicate = true;
+
+// Here we check if the JavaScript engine is using some sort of
+// optimization where it does not always call our comparision
+// function. If that is the case, discard the hasDuplicate value.
+// Thus far that includes Google Chrome.
+[0, 0].sort(function() {
+ baseHasDuplicate = false;
+ return 0;
+});
+
+var Sizzle = function( selector, context, results, seed ) {
+ results = results || [];
+ context = context || document;
+
+ var origContext = context;
+
+ if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
+ return [];
+ }
+
+ if ( !selector || typeof selector !== "string" ) {
+ return results;
+ }
+
+ var m, set, checkSet, extra, ret, cur, pop, i,
+ prune = true,
+ contextXML = Sizzle.isXML( context ),
+ parts = [],
+ soFar = selector;
+
+ // Reset the position of the chunker regexp (start from head)
+ do {
+ chunker.exec( "" );
+ m = chunker.exec( soFar );
+
+ if ( m ) {
+ soFar = m[3];
+
+ parts.push( m[1] );
+
+ if ( m[2] ) {
+ extra = m[3];
+ break;
+ }
+ }
+ } while ( m );
+
+ if ( parts.length > 1 && origPOS.exec( selector ) ) {
+
+ if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
+ set = posProcess( parts[0] + parts[1], context );
+
+ } else {
+ set = Expr.relative[ parts[0] ] ?
+ [ context ] :
+ Sizzle( parts.shift(), context );
+
+ while ( parts.length ) {
+ selector = parts.shift();
+
+ if ( Expr.relative[ selector ] ) {
+ selector += parts.shift();
+ }
+
+ set = posProcess( selector, set );
+ }
+ }
+
+ } else {
+ // Take a shortcut and set the context if the root selector is an ID
+ // (but not if it'll be faster if the inner selector is an ID)
+ if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
+ Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
+
+ ret = Sizzle.find( parts.shift(), context, contextXML );
+ context = ret.expr ?
+ Sizzle.filter( ret.expr, ret.set )[0] :
+ ret.set[0];
+ }
+
+ if ( context ) {
+ ret = seed ?
+ { expr: parts.pop(), set: makeArray(seed) } :
+ Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
+
+ set = ret.expr ?
+ Sizzle.filter( ret.expr, ret.set ) :
+ ret.set;
+
+ if ( parts.length > 0 ) {
+ checkSet = makeArray( set );
+
+ } else {
+ prune = false;
+ }
+
+ while ( parts.length ) {
+ cur = parts.pop();
+ pop = cur;
+
+ if ( !Expr.relative[ cur ] ) {
+ cur = "";
+ } else {
+ pop = parts.pop();
+ }
+
+ if ( pop == null ) {
+ pop = context;
+ }
+
+ Expr.relative[ cur ]( checkSet, pop, contextXML );
+ }
+
+ } else {
+ checkSet = parts = [];
+ }
+ }
+
+ if ( !checkSet ) {
+ checkSet = set;
+ }
+
+ if ( !checkSet ) {
+ Sizzle.error( cur || selector );
+ }
+
+ if ( toString.call(checkSet) === "[object Array]" ) {
+ if ( !prune ) {
+ results.push.apply( results, checkSet );
+
+ } else if ( context && context.nodeType === 1 ) {
+ for ( i = 0; checkSet[i] != null; i++ ) {
+ if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
+ results.push( set[i] );
+ }
+ }
+
+ } else {
+ for ( i = 0; checkSet[i] != null; i++ ) {
+ if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
+ results.push( set[i] );
+ }
+ }
+ }
+
+ } else {
+ makeArray( checkSet, results );
+ }
+
+ if ( extra ) {
+ Sizzle( extra, origContext, results, seed );
+ Sizzle.uniqueSort( results );
+ }
+
+ return results;
+};
+
+Sizzle.uniqueSort = function( results ) {
+ if ( sortOrder ) {
+ hasDuplicate = baseHasDuplicate;
+ results.sort( sortOrder );
+
+ if ( hasDuplicate ) {
+ for ( var i = 1; i < results.length; i++ ) {
+ if ( results[i] === results[ i - 1 ] ) {
+ results.splice( i--, 1 );
+ }
+ }
+ }
+ }
+
+ return results;
+};
+
+Sizzle.matches = function( expr, set ) {
+ return Sizzle( expr, null, null, set );
+};
+
+Sizzle.matchesSelector = function( node, expr ) {
+ return Sizzle( expr, null, null, [node] ).length > 0;
+};
+
+Sizzle.find = function( expr, context, isXML ) {
+ var set;
+
+ if ( !expr ) {
+ return [];
+ }
+
+ for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
+ var match,
+ type = Expr.order[i];
+
+ if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
+ var left = match[1];
+ match.splice( 1, 1 );
+
+ if ( left.substr( left.length - 1 ) !== "\\" ) {
+ match[1] = (match[1] || "").replace(/\\/g, "");
+ set = Expr.find[ type ]( match, context, isXML );
+
+ if ( set != null ) {
+ expr = expr.replace( Expr.match[ type ], "" );
+ break;
+ }
+ }
+ }
+ }
+
+ if ( !set ) {
+ set = context.getElementsByTagName( "*" );
+ }
+
+ return { set: set, expr: expr };
+};
+
+Sizzle.filter = function( expr, set, inplace, not ) {
+ var match, anyFound,
+ old = expr,
+ result = [],
+ curLoop = set,
+ isXMLFilter = set && set[0] && Sizzle.isXML( set[0] );
+
+ while ( expr && set.length ) {
+ for ( var type in Expr.filter ) {
+ if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {
+ var found, item,
+ filter = Expr.filter[ type ],
+ left = match[1];
+
+ anyFound = false;
+
+ match.splice(1,1);
+
+ if ( left.substr( left.length - 1 ) === "\\" ) {
+ continue;
+ }
+
+ if ( curLoop === result ) {
+ result = [];
+ }
+
+ if ( Expr.preFilter[ type ] ) {
+ match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
+
+ if ( !match ) {
+ anyFound = found = true;
+
+ } else if ( match === true ) {
+ continue;
+ }
+ }
+
+ if ( match ) {
+ for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
+ if ( item ) {
+ found = filter( item, match, i, curLoop );
+ var pass = not ^ !!found;
+
+ if ( inplace && found != null ) {
+ if ( pass ) {
+ anyFound = true;
+
+ } else {
+ curLoop[i] = false;
+ }
+
+ } else if ( pass ) {
+ result.push( item );
+ anyFound = true;
+ }
+ }
+ }
+ }
+
+ if ( found !== undefined ) {
+ if ( !inplace ) {
+ curLoop = result;
+ }
+
+ expr = expr.replace( Expr.match[ type ], "" );
+
+ if ( !anyFound ) {
+ return [];
+ }
+
+ break;
+ }
+ }
+ }
+
+ // Improper expression
+ if ( expr === old ) {
+ if ( anyFound == null ) {
+ Sizzle.error( expr );
+
+ } else {
+ break;
+ }
+ }
+
+ old = expr;
+ }
+
+ return curLoop;
+};
+
+Sizzle.error = function( msg ) {
+ throw "Syntax error, unrecognized expression: " + msg;
+};
+
+var Expr = Sizzle.selectors = {
+ order: [ "ID", "NAME", "TAG" ],
+
+ match: {
+ ID: /#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
+ CLASS: /\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,
+ NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,
+ ATTR: /\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
+ TAG: /^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,
+ CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+\-]*)\))?/,
+ POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,
+ PSEUDO: /:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/
+ },
+
+ leftMatch: {},
+
+ attrMap: {
+ "class": "className",
+ "for": "htmlFor"
+ },
+
+ attrHandle: {
+ href: function( elem ) {
+ return elem.getAttribute( "href" );
+ }
+ },
+
+ relative: {
+ "+": function(checkSet, part){
+ var isPartStr = typeof part === "string",
+ isTag = isPartStr && !/\W/.test( part ),
+ isPartStrNotTag = isPartStr && !isTag;
+
+ if ( isTag ) {
+ part = part.toLowerCase();
+ }
+
+ for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
+ if ( (elem = checkSet[i]) ) {
+ while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
+
+ checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?
+ elem || false :
+ elem === part;
+ }
+ }
+
+ if ( isPartStrNotTag ) {
+ Sizzle.filter( part, checkSet, true );
+ }
+ },
+
+ ">": function( checkSet, part ) {
+ var elem,
+ isPartStr = typeof part === "string",
+ i = 0,
+ l = checkSet.length;
+
+ if ( isPartStr && !/\W/.test( part ) ) {
+ part = part.toLowerCase();
+
+ for ( ; i < l; i++ ) {
+ elem = checkSet[i];
+
+ if ( elem ) {
+ var parent = elem.parentNode;
+ checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;
+ }
+ }
+
+ } else {
+ for ( ; i < l; i++ ) {
+ elem = checkSet[i];
+
+ if ( elem ) {
+ checkSet[i] = isPartStr ?
+ elem.parentNode :
+ elem.parentNode === part;
+ }
+ }
+
+ if ( isPartStr ) {
+ Sizzle.filter( part, checkSet, true );
+ }
+ }
+ },
+
+ "": function(checkSet, part, isXML){
+ var nodeCheck,
+ doneName = done++,
+ checkFn = dirCheck;
+
+ if ( typeof part === "string" && !/\W/.test(part) ) {
+ part = part.toLowerCase();
+ nodeCheck = part;
+ checkFn = dirNodeCheck;
+ }
+
+ checkFn( "parentNode", part, doneName, checkSet, nodeCheck, isXML );
+ },
+
+ "~": function( checkSet, part, isXML ) {
+ var nodeCheck,
+ doneName = done++,
+ checkFn = dirCheck;
+
+ if ( typeof part === "string" && !/\W/.test( part ) ) {
+ part = part.toLowerCase();
+ nodeCheck = part;
+ checkFn = dirNodeCheck;
+ }
+
+ checkFn( "previousSibling", part, doneName, checkSet, nodeCheck, isXML );
+ }
+ },
+
+ find: {
+ ID: function( match, context, isXML ) {
+ if ( typeof context.getElementById !== "undefined" && !isXML ) {
+ var m = context.getElementById(match[1]);
+ // Check parentNode to catch when Blackberry 4.6 returns
+ // nodes that are no longer in the document #6963
+ return m && m.parentNode ? [m] : [];
+ }
+ },
+
+ NAME: function( match, context ) {
+ if ( typeof context.getElementsByName !== "undefined" ) {
+ var ret = [],
+ results = context.getElementsByName( match[1] );
+
+ for ( var i = 0, l = results.length; i < l; i++ ) {
+ if ( results[i].getAttribute("name") === match[1] ) {
+ ret.push( results[i] );
+ }
+ }
+
+ return ret.length === 0 ? null : ret;
+ }
+ },
+
+ TAG: function( match, context ) {
+ return context.getElementsByTagName( match[1] );
+ }
+ },
+ preFilter: {
+ CLASS: function( match, curLoop, inplace, result, not, isXML ) {
+ match = " " + match[1].replace(/\\/g, "") + " ";
+
+ if ( isXML ) {
+ return match;
+ }
+
+ for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
+ if ( elem ) {
+ if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) ) {
+ if ( !inplace ) {
+ result.push( elem );
+ }
+
+ } else if ( inplace ) {
+ curLoop[i] = false;
+ }
+ }
+ }
+
+ return false;
+ },
+
+ ID: function( match ) {
+ return match[1].replace(/\\/g, "");
+ },
+
+ TAG: function( match, curLoop ) {
+ return match[1].toLowerCase();
+ },
+
+ CHILD: function( match ) {
+ if ( match[1] === "nth" ) {
+ // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
+ var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
+ match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||
+ !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
+
+ // calculate the numbers (first)n+(last) including if they are negative
+ match[2] = (test[1] + (test[2] || 1)) - 0;
+ match[3] = test[3] - 0;
+ }
+
+ // TODO: Move to normal caching system
+ match[0] = done++;
+
+ return match;
+ },
+
+ ATTR: function( match, curLoop, inplace, result, not, isXML ) {
+ var name = match[1].replace(/\\/g, "");
+
+ if ( !isXML && Expr.attrMap[name] ) {
+ match[1] = Expr.attrMap[name];
+ }
+
+ if ( match[2] === "~=" ) {
+ match[4] = " " + match[4] + " ";
+ }
+
+ return match;
+ },
+
+ PSEUDO: function( match, curLoop, inplace, result, not ) {
+ if ( match[1] === "not" ) {
+ // If we're dealing with a complex expression, or a simple one
+ if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
+ match[3] = Sizzle(match[3], null, null, curLoop);
+
+ } else {
+ var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
+
+ if ( !inplace ) {
+ result.push.apply( result, ret );
+ }
+
+ return false;
+ }
+
+ } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
+ return true;
+ }
+
+ return match;
+ },
+
+ POS: function( match ) {
+ match.unshift( true );
+
+ return match;
+ }
+ },
+
+ filters: {
+ enabled: function( elem ) {
+ return elem.disabled === false && elem.type !== "hidden";
+ },
+
+ disabled: function( elem ) {
+ return elem.disabled === true;
+ },
+
+ checked: function( elem ) {
+ return elem.checked === true;
+ },
+
+ selected: function( elem ) {
+ // Accessing this property makes selected-by-default
+ // options in Safari work properly
+ elem.parentNode.selectedIndex;
+
+ return elem.selected === true;
+ },
+
+ parent: function( elem ) {
+ return !!elem.firstChild;
+ },
+
+ empty: function( elem ) {
+ return !elem.firstChild;
+ },
+
+ has: function( elem, i, match ) {
+ return !!Sizzle( match[3], elem ).length;
+ },
+
+ header: function( elem ) {
+ return (/h\d/i).test( elem.nodeName );
+ },
+
+ text: function( elem ) {
+ return "text" === elem.type;
+ },
+ radio: function( elem ) {
+ return "radio" === elem.type;
+ },
+
+ checkbox: function( elem ) {
+ return "checkbox" === elem.type;
+ },
+
+ file: function( elem ) {
+ return "file" === elem.type;
+ },
+ password: function( elem ) {
+ return "password" === elem.type;
+ },
+
+ submit: function( elem ) {
+ return "submit" === elem.type;
+ },
+
+ image: function( elem ) {
+ return "image" === elem.type;
+ },
+
+ reset: function( elem ) {
+ return "reset" === elem.type;
+ },
+
+ button: function( elem ) {
+ return "button" === elem.type || elem.nodeName.toLowerCase() === "button";
+ },
+
+ input: function( elem ) {
+ return (/input|select|textarea|button/i).test( elem.nodeName );
+ }
+ },
+ setFilters: {
+ first: function( elem, i ) {
+ return i === 0;
+ },
+
+ last: function( elem, i, match, array ) {
+ return i === array.length - 1;
+ },
+
+ even: function( elem, i ) {
+ return i % 2 === 0;
+ },
+
+ odd: function( elem, i ) {
+ return i % 2 === 1;
+ },
+
+ lt: function( elem, i, match ) {
+ return i < match[3] - 0;
+ },
+
+ gt: function( elem, i, match ) {
+ return i > match[3] - 0;
+ },
+
+ nth: function( elem, i, match ) {
+ return match[3] - 0 === i;
+ },
+
+ eq: function( elem, i, match ) {
+ return match[3] - 0 === i;
+ }
+ },
+ filter: {
+ PSEUDO: function( elem, match, i, array ) {
+ var name = match[1],
+ filter = Expr.filters[ name ];
+
+ if ( filter ) {
+ return filter( elem, i, match, array );
+
+ } else if ( name === "contains" ) {
+ return (elem.textContent || elem.innerText || Sizzle.getText([ elem ]) || "").indexOf(match[3]) >= 0;
+
+ } else if ( name === "not" ) {
+ var not = match[3];
+
+ for ( var j = 0, l = not.length; j < l; j++ ) {
+ if ( not[j] === elem ) {
+ return false;
+ }
+ }
+
+ return true;
+
+ } else {
+ Sizzle.error( "Syntax error, unrecognized expression: " + name );
+ }
+ },
+
+ CHILD: function( elem, match ) {
+ var type = match[1],
+ node = elem;
+
+ switch ( type ) {
+ case "only":
+ case "first":
+ while ( (node = node.previousSibling) ) {
+ if ( node.nodeType === 1 ) {
+ return false;
+ }
+ }
+
+ if ( type === "first" ) {
+ return true;
+ }
+
+ node = elem;
+
+ case "last":
+ while ( (node = node.nextSibling) ) {
+ if ( node.nodeType === 1 ) {
+ return false;
+ }
+ }
+
+ return true;
+
+ case "nth":
+ var first = match[2],
+ last = match[3];
+
+ if ( first === 1 && last === 0 ) {
+ return true;
+ }
+
+ var doneName = match[0],
+ parent = elem.parentNode;
+
+ if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
+ var count = 0;
+
+ for ( node = parent.firstChild; node; node = node.nextSibling ) {
+ if ( node.nodeType === 1 ) {
+ node.nodeIndex = ++count;
+ }
+ }
+
+ parent.sizcache = doneName;
+ }
+
+ var diff = elem.nodeIndex - last;
+
+ if ( first === 0 ) {
+ return diff === 0;
+
+ } else {
+ return ( diff % first === 0 && diff / first >= 0 );
+ }
+ }
+ },
+
+ ID: function( elem, match ) {
+ return elem.nodeType === 1 && elem.getAttribute("id") === match;
+ },
+
+ TAG: function( elem, match ) {
+ return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;
+ },
+
+ CLASS: function( elem, match ) {
+ return (" " + (elem.className || elem.getAttribute("class")) + " ")
+ .indexOf( match ) > -1;
+ },
+
+ ATTR: function( elem, match ) {
+ var name = match[1],
+ result = Expr.attrHandle[ name ] ?
+ Expr.attrHandle[ name ]( elem ) :
+ elem[ name ] != null ?
+ elem[ name ] :
+ elem.getAttribute( name ),
+ value = result + "",
+ type = match[2],
+ check = match[4];
+
+ return result == null ?
+ type === "!=" :
+ type === "=" ?
+ value === check :
+ type === "*=" ?
+ value.indexOf(check) >= 0 :
+ type === "~=" ?
+ (" " + value + " ").indexOf(check) >= 0 :
+ !check ?
+ value && result !== false :
+ type === "!=" ?
+ value !== check :
+ type === "^=" ?
+ value.indexOf(check) === 0 :
+ type === "$=" ?
+ value.substr(value.length - check.length) === check :
+ type === "|=" ?
+ value === check || value.substr(0, check.length + 1) === check + "-" :
+ false;
+ },
+
+ POS: function( elem, match, i, array ) {
+ var name = match[2],
+ filter = Expr.setFilters[ name ];
+
+ if ( filter ) {
+ return filter( elem, i, match, array );
+ }
+ }
+ }
+};
+
+var origPOS = Expr.match.POS,
+ fescape = function(all, num){
+ return "\\" + (num - 0 + 1);
+ };
+
+for ( var type in Expr.match ) {
+ Expr.match[ type ] = new RegExp( Expr.match[ type ].source + (/(?![^\[]*\])(?![^\(]*\))/.source) );
+ Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, fescape) );
+}
+
+var makeArray = function( array, results ) {
+ array = Array.prototype.slice.call( array, 0 );
+
+ if ( results ) {
+ results.push.apply( results, array );
+ return results;
+ }
+
+ return array;
+};
+
+// Perform a simple check to determine if the browser is capable of
+// converting a NodeList to an array using builtin methods.
+// Also verifies that the returned array holds DOM nodes
+// (which is not the case in the Blackberry browser)
+try {
+ Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
+
+// Provide a fallback method if it does not work
+} catch( e ) {
+ makeArray = function( array, results ) {
+ var i = 0,
+ ret = results || [];
+
+ if ( toString.call(array) === "[object Array]" ) {
+ Array.prototype.push.apply( ret, array );
+
+ } else {
+ if ( typeof array.length === "number" ) {
+ for ( var l = array.length; i < l; i++ ) {
+ ret.push( array[i] );
+ }
+
+ } else {
+ for ( ; array[i]; i++ ) {
+ ret.push( array[i] );
+ }
+ }
+ }
+
+ return ret;
+ };
+}
+
+var sortOrder, siblingCheck;
+
+if ( document.documentElement.compareDocumentPosition ) {
+ sortOrder = function( a, b ) {
+ if ( a === b ) {
+ hasDuplicate = true;
+ return 0;
+ }
+
+ if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
+ return a.compareDocumentPosition ? -1 : 1;
+ }
+
+ return a.compareDocumentPosition(b) & 4 ? -1 : 1;
+ };
+
+} else {
+ sortOrder = function( a, b ) {
+ var al, bl,
+ ap = [],
+ bp = [],
+ aup = a.parentNode,
+ bup = b.parentNode,
+ cur = aup;
+
+ // The nodes are identical, we can exit early
+ if ( a === b ) {
+ hasDuplicate = true;
+ return 0;
+
+ // If the nodes are siblings (or identical) we can do a quick check
+ } else if ( aup === bup ) {
+ return siblingCheck( a, b );
+
+ // If no parents were found then the nodes are disconnected
+ } else if ( !aup ) {
+ return -1;
+
+ } else if ( !bup ) {
+ return 1;
+ }
+
+ // Otherwise they're somewhere else in the tree so we need
+ // to build up a full list of the parentNodes for comparison
+ while ( cur ) {
+ ap.unshift( cur );
+ cur = cur.parentNode;
+ }
+
+ cur = bup;
+
+ while ( cur ) {
+ bp.unshift( cur );
+ cur = cur.parentNode;
+ }
+
+ al = ap.length;
+ bl = bp.length;
+
+ // Start walking down the tree looking for a discrepancy
+ for ( var i = 0; i < al && i < bl; i++ ) {
+ if ( ap[i] !== bp[i] ) {
+ return siblingCheck( ap[i], bp[i] );
+ }
+ }
+
+ // We ended someplace up the tree so do a sibling check
+ return i === al ?
+ siblingCheck( a, bp[i], -1 ) :
+ siblingCheck( ap[i], b, 1 );
+ };
+
+ siblingCheck = function( a, b, ret ) {
+ if ( a === b ) {
+ return ret;
+ }
+
+ var cur = a.nextSibling;
+
+ while ( cur ) {
+ if ( cur === b ) {
+ return -1;
+ }
+
+ cur = cur.nextSibling;
+ }
+
+ return 1;
+ };
+}
+
+// Utility function for retreiving the text value of an array of DOM nodes
+Sizzle.getText = function( elems ) {
+ var ret = "", elem;
+
+ for ( var i = 0; elems[i]; i++ ) {
+ elem = elems[i];
+
+ // Get the text from text nodes and CDATA nodes
+ if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
+ ret += elem.nodeValue;
+
+ // Traverse everything else, except comment nodes
+ } else if ( elem.nodeType !== 8 ) {
+ ret += Sizzle.getText( elem.childNodes );
+ }
+ }
+
+ return ret;
+};
+
+// Check to see if the browser returns elements by name when
+// querying by getElementById (and provide a workaround)
+(function(){
+ // We're going to inject a fake input element with a specified name
+ var form = document.createElement("div"),
+ id = "script" + (new Date()).getTime(),
+ root = document.documentElement;
+
+ form.innerHTML = "<a name='" + id + "'/>";
+
+ // Inject it into the root element, check its status, and remove it quickly
+ root.insertBefore( form, root.firstChild );
+
+ // The workaround has to do additional checks after a getElementById
+ // Which slows things down for other browsers (hence the branching)
+ if ( document.getElementById( id ) ) {
+ Expr.find.ID = function( match, context, isXML ) {
+ if ( typeof context.getElementById !== "undefined" && !isXML ) {
+ var m = context.getElementById(match[1]);
+
+ return m ?
+ m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ?
+ [m] :
+ undefined :
+ [];
+ }
+ };
+
+ Expr.filter.ID = function( elem, match ) {
+ var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
+
+ return elem.nodeType === 1 && node && node.nodeValue === match;
+ };
+ }
+
+ root.removeChild( form );
+
+ // release memory in IE
+ root = form = null;
+})();
+
+(function(){
+ // Check to see if the browser returns only elements
+ // when doing getElementsByTagName("*")
+
+ // Create a fake element
+ var div = document.createElement("div");
+ div.appendChild( document.createComment("") );
+
+ // Make sure no comments are found
+ if ( div.getElementsByTagName("*").length > 0 ) {
+ Expr.find.TAG = function( match, context ) {
+ var results = context.getElementsByTagName( match[1] );
+
+ // Filter out possible comments
+ if ( match[1] === "*" ) {
+ var tmp = [];
+
+ for ( var i = 0; results[i]; i++ ) {
+ if ( results[i].nodeType === 1 ) {
+ tmp.push( results[i] );
+ }
+ }
+
+ results = tmp;
+ }
+
+ return results;
+ };
+ }
+
+ // Check to see if an attribute returns normalized href attributes
+ div.innerHTML = "<a href='#'></a>";
+
+ if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
+ div.firstChild.getAttribute("href") !== "#" ) {
+
+ Expr.attrHandle.href = function( elem ) {
+ return elem.getAttribute( "href", 2 );
+ };
+ }
+
+ // release memory in IE
+ div = null;
+})();
+
+if ( document.querySelectorAll ) {
+ (function(){
+ var oldSizzle = Sizzle,
+ div = document.createElement("div"),
+ id = "__sizzle__";
+
+ div.innerHTML = "<p class='TEST'></p>";
+
+ // Safari can't handle uppercase or unicode characters when
+ // in quirks mode.
+ if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
+ return;
+ }
+
+ Sizzle = function( query, context, extra, seed ) {
+ context = context || document;
+
+ // Make sure that attribute selectors are quoted
+ query = query.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
+
+ // Only use querySelectorAll on non-XML documents
+ // (ID selectors don't work in non-HTML documents)
+ if ( !seed && !Sizzle.isXML(context) ) {
+ if ( context.nodeType === 9 ) {
+ try {
+ return makeArray( context.querySelectorAll(query), extra );
+ } catch(qsaError) {}
+
+ // qSA works strangely on Element-rooted queries
+ // We can work around this by specifying an extra ID on the root
+ // and working up from there (Thanks to Andrew Dupont for the technique)
+ // IE 8 doesn't work on object elements
+ } else if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
+ var old = context.getAttribute( "id" ),
+ nid = old || id;
+
+ if ( !old ) {
+ context.setAttribute( "id", nid );
+ }
+
+ try {
+ return makeArray( context.querySelectorAll( "#" + nid + " " + query ), extra );
+
+ } catch(pseudoError) {
+ } finally {
+ if ( !old ) {
+ context.removeAttribute( "id" );
+ }
+ }
+ }
+ }
+
+ return oldSizzle(query, context, extra, seed);
+ };
+
+ for ( var prop in oldSizzle ) {
+ Sizzle[ prop ] = oldSizzle[ prop ];
+ }
+
+ // release memory in IE
+ div = null;
+ })();
+}
+
+(function(){
+ var html = document.documentElement,
+ matches = html.matchesSelector || html.mozMatchesSelector || html.webkitMatchesSelector || html.msMatchesSelector,
+ pseudoWorks = false;
+
+ try {
+ // This should fail with an exception
+ // Gecko does not error, returns false instead
+ matches.call( document.documentElement, "[test!='']:sizzle" );
+
+ } catch( pseudoError ) {
+ pseudoWorks = true;
+ }
+
+ if ( matches ) {
+ Sizzle.matchesSelector = function( node, expr ) {
+ // Make sure that attribute selectors are quoted
+ expr = expr.replace(/\=\s*([^'"\]]*)\s*\]/g, "='$1']");
+
+ if ( !Sizzle.isXML( node ) ) {
+ try {
+ if ( pseudoWorks || !Expr.match.PSEUDO.test( expr ) && !/!=/.test( expr ) ) {
+ return matches.call( node, expr );
+ }
+ } catch(e) {}
+ }
+
+ return Sizzle(expr, null, null, [node]).length > 0;
+ };
+ }
+})();
+
+(function(){
+ var div = document.createElement("div");
+
+ div.innerHTML = "<div class='test e'></div><div class='test'></div>";
+
+ // Opera can't find a second classname (in 9.6)
+ // Also, make sure that getElementsByClassName actually exists
+ if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {
+ return;
+ }
+
+ // Safari caches class attributes, doesn't catch changes (in 3.2)
+ div.lastChild.className = "e";
+
+ if ( div.getElementsByClassName("e").length === 1 ) {
+ return;
+ }
+
+ Expr.order.splice(1, 0, "CLASS");
+ Expr.find.CLASS = function( match, context, isXML ) {
+ if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
+ return context.getElementsByClassName(match[1]);
+ }
+ };
+
+ // release memory in IE
+ div = null;
+})();
+
+function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+
+ if ( elem ) {
+ var match = false;
+
+ elem = elem[dir];
+
+ while ( elem ) {
+ if ( elem.sizcache === doneName ) {
+ match = checkSet[elem.sizset];
+ break;
+ }
+
+ if ( elem.nodeType === 1 && !isXML ){
+ elem.sizcache = doneName;
+ elem.sizset = i;
+ }
+
+ if ( elem.nodeName.toLowerCase() === cur ) {
+ match = elem;
+ break;
+ }
+
+ elem = elem[dir];
+ }
+
+ checkSet[i] = match;
+ }
+ }
+}
+
+function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
+ var elem = checkSet[i];
+
+ if ( elem ) {
+ var match = false;
+
+ elem = elem[dir];
+
+ while ( elem ) {
+ if ( elem.sizcache === doneName ) {
+ match = checkSet[elem.sizset];
+ break;
+ }
+
+ if ( elem.nodeType === 1 ) {
+ if ( !isXML ) {
+ elem.sizcache = doneName;
+ elem.sizset = i;
+ }
+
+ if ( typeof cur !== "string" ) {
+ if ( elem === cur ) {
+ match = true;
+ break;
+ }
+
+ } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
+ match = elem;
+ break;
+ }
+ }
+
+ elem = elem[dir];
+ }
+
+ checkSet[i] = match;
+ }
+ }
+}
+
+if ( document.documentElement.contains ) {
+ Sizzle.contains = function( a, b ) {
+ return a !== b && (a.contains ? a.contains(b) : true);
+ };
+
+} else if ( document.documentElement.compareDocumentPosition ) {
+ Sizzle.contains = function( a, b ) {
+ return !!(a.compareDocumentPosition(b) & 16);
+ };
+
+} else {
+ Sizzle.contains = function() {
+ return false;
+ };
+}
+
+Sizzle.isXML = function( elem ) {
+ // documentElement is verified for cases where it doesn't yet exist
+ // (such as loading iframes in IE - #4833)
+ var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;
+
+ return documentElement ? documentElement.nodeName !== "HTML" : false;
+};
+
+var posProcess = function( selector, context ) {
+ var match,
+ tmpSet = [],
+ later = "",
+ root = context.nodeType ? [context] : context;
+
+ // Position selectors must be done after the filter
+ // And so must :not(positional) so we move all PSEUDOs to the end
+ while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
+ later += match[0];
+ selector = selector.replace( Expr.match.PSEUDO, "" );
+ }
+
+ selector = Expr.relative[selector] ? selector + "*" : selector;
+
+ for ( var i = 0, l = root.length; i < l; i++ ) {
+ Sizzle( selector, root[i], tmpSet );
+ }
+
+ return Sizzle.filter( later, tmpSet );
+};
+
+// EXPOSE
+jQuery.find = Sizzle;
+jQuery.expr = Sizzle.selectors;
+jQuery.expr[":"] = jQuery.expr.filters;
+jQuery.unique = Sizzle.uniqueSort;
+jQuery.text = Sizzle.getText;
+jQuery.isXMLDoc = Sizzle.isXML;
+jQuery.contains = Sizzle.contains;
+
+
+})();
+
+
+var runtil = /Until$/,
+ rparentsprev = /^(?:parents|prevUntil|prevAll)/,
+ // Note: This RegExp should be improved, or likely pulled from Sizzle
+ rmultiselector = /,/,
+ isSimple = /^.[^:#\[\.,]*$/,
+ slice = Array.prototype.slice,
+ POS = jQuery.expr.match.POS;
+
+jQuery.fn.extend({
+ find: function( selector ) {
+ var ret = this.pushStack( "", "find", selector ),
+ length = 0;
+
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ length = ret.length;
+ jQuery.find( selector, this[i], ret );
+
+ if ( i > 0 ) {
+ // Make sure that the results are unique
+ for ( var n = length; n < ret.length; n++ ) {
+ for ( var r = 0; r < length; r++ ) {
+ if ( ret[r] === ret[n] ) {
+ ret.splice(n--, 1);
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return ret;
+ },
+
+ has: function( target ) {
+ var targets = jQuery( target );
+ return this.filter(function() {
+ for ( var i = 0, l = targets.length; i < l; i++ ) {
+ if ( jQuery.contains( this, targets[i] ) ) {
+ return true;
+ }
+ }
+ });
+ },
+
+ not: function( selector ) {
+ return this.pushStack( winnow(this, selector, false), "not", selector);
+ },
+
+ filter: function( selector ) {
+ return this.pushStack( winnow(this, selector, true), "filter", selector );
+ },
+
+ is: function( selector ) {
+ return !!selector && jQuery.filter( selector, this ).length > 0;
+ },
+
+ closest: function( selectors, context ) {
+ var ret = [], i, l, cur = this[0];
+
+ if ( jQuery.isArray( selectors ) ) {
+ var match, selector,
+ matches = {},
+ level = 1;
+
+ if ( cur && selectors.length ) {
+ for ( i = 0, l = selectors.length; i < l; i++ ) {
+ selector = selectors[i];
+
+ if ( !matches[selector] ) {
+ matches[selector] = jQuery.expr.match.POS.test( selector ) ?
+ jQuery( selector, context || this.context ) :
+ selector;
+ }
+ }
+
+ while ( cur && cur.ownerDocument && cur !== context ) {
+ for ( selector in matches ) {
+ match = matches[selector];
+
+ if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) {
+ ret.push({ selector: selector, elem: cur, level: level });
+ }
+ }
+
+ cur = cur.parentNode;
+ level++;
+ }
+ }
+
+ return ret;
+ }
+
+ var pos = POS.test( selectors ) ?
+ jQuery( selectors, context || this.context ) : null;
+
+ for ( i = 0, l = this.length; i < l; i++ ) {
+ cur = this[i];
+
+ while ( cur ) {
+ if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
+ ret.push( cur );
+ break;
+
+ } else {
+ cur = cur.parentNode;
+ if ( !cur || !cur.ownerDocument || cur === context ) {
+ break;
+ }
+ }
+ }
+ }
+
+ ret = ret.length > 1 ? jQuery.unique(ret) : ret;
+
+ return this.pushStack( ret, "closest", selectors );
+ },
+
+ // Determine the position of an element within
+ // the matched set of elements
+ index: function( elem ) {
+ if ( !elem || typeof elem === "string" ) {
+ return jQuery.inArray( this[0],
+ // If it receives a string, the selector is used
+ // If it receives nothing, the siblings are used
+ elem ? jQuery( elem ) : this.parent().children() );
+ }
+ // Locate the position of the desired element
+ return jQuery.inArray(
+ // If it receives a jQuery object, the first element is used
+ elem.jquery ? elem[0] : elem, this );
+ },
+
+ add: function( selector, context ) {
+ var set = typeof selector === "string" ?
+ jQuery( selector, context || this.context ) :
+ jQuery.makeArray( selector ),
+ all = jQuery.merge( this.get(), set );
+
+ return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?
+ all :
+ jQuery.unique( all ) );
+ },
+
+ andSelf: function() {
+ return this.add( this.prevObject );
+ }
+});
+
+// A painfully simple check to see if an element is disconnected
+// from a document (should be improved, where feasible).
+function isDisconnected( node ) {
+ return !node || !node.parentNode || node.parentNode.nodeType === 11;
+}
+
+jQuery.each({
+ parent: function( elem ) {
+ var parent = elem.parentNode;
+ return parent && parent.nodeType !== 11 ? parent : null;
+ },
+ parents: function( elem ) {
+ return jQuery.dir( elem, "parentNode" );
+ },
+ parentsUntil: function( elem, i, until ) {
+ return jQuery.dir( elem, "parentNode", until );
+ },
+ next: function( elem ) {
+ return jQuery.nth( elem, 2, "nextSibling" );
+ },
+ prev: function( elem ) {
+ return jQuery.nth( elem, 2, "previousSibling" );
+ },
+ nextAll: function( elem ) {
+ return jQuery.dir( elem, "nextSibling" );
+ },
+ prevAll: function( elem ) {
+ return jQuery.dir( elem, "previousSibling" );
+ },
+ nextUntil: function( elem, i, until ) {
+ return jQuery.dir( elem, "nextSibling", until );
+ },
+ prevUntil: function( elem, i, until ) {
+ return jQuery.dir( elem, "previousSibling", until );
+ },
+ siblings: function( elem ) {
+ return jQuery.sibling( elem.parentNode.firstChild, elem );
+ },
+ children: function( elem ) {
+ return jQuery.sibling( elem.firstChild );
+ },
+ contents: function( elem ) {
+ return jQuery.nodeName( elem, "iframe" ) ?
+ elem.contentDocument || elem.contentWindow.document :
+ jQuery.makeArray( elem.childNodes );
+ }
+}, function( name, fn ) {
+ jQuery.fn[ name ] = function( until, selector ) {
+ var ret = jQuery.map( this, fn, until );
+
+ if ( !runtil.test( name ) ) {
+ selector = until;
+ }
+
+ if ( selector && typeof selector === "string" ) {
+ ret = jQuery.filter( selector, ret );
+ }
+
+ ret = this.length > 1 ? jQuery.unique( ret ) : ret;
+
+ if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {
+ ret = ret.reverse();
+ }
+
+ return this.pushStack( ret, name, slice.call(arguments).join(",") );
+ };
+});
+
+jQuery.extend({
+ filter: function( expr, elems, not ) {
+ if ( not ) {
+ expr = ":not(" + expr + ")";
+ }
+
+ return elems.length === 1 ?
+ jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :
+ jQuery.find.matches(expr, elems);
+ },
+
+ dir: function( elem, dir, until ) {
+ var matched = [],
+ cur = elem[ dir ];
+
+ while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
+ if ( cur.nodeType === 1 ) {
+ matched.push( cur );
+ }
+ cur = cur[dir];
+ }
+ return matched;
+ },
+
+ nth: function( cur, result, dir, elem ) {
+ result = result || 1;
+ var num = 0;
+
+ for ( ; cur; cur = cur[dir] ) {
+ if ( cur.nodeType === 1 && ++num === result ) {
+ break;
+ }
+ }
+
+ return cur;
+ },
+
+ sibling: function( n, elem ) {
+ var r = [];
+
+ for ( ; n; n = n.nextSibling ) {
+ if ( n.nodeType === 1 && n !== elem ) {
+ r.push( n );
+ }
+ }
+
+ return r;
+ }
+});
+
+// Implement the identical functionality for filter and not
+function winnow( elements, qualifier, keep ) {
+ if ( jQuery.isFunction( qualifier ) ) {
+ return jQuery.grep(elements, function( elem, i ) {
+ var retVal = !!qualifier.call( elem, i, elem );
+ return retVal === keep;
+ });
+
+ } else if ( qualifier.nodeType ) {
+ return jQuery.grep(elements, function( elem, i ) {
+ return (elem === qualifier) === keep;
+ });
+
+ } else if ( typeof qualifier === "string" ) {
+ var filtered = jQuery.grep(elements, function( elem ) {
+ return elem.nodeType === 1;
+ });
+
+ if ( isSimple.test( qualifier ) ) {
+ return jQuery.filter(qualifier, filtered, !keep);
+ } else {
+ qualifier = jQuery.filter( qualifier, filtered );
+ }
+ }
+
+ return jQuery.grep(elements, function( elem, i ) {
+ return (jQuery.inArray( elem, qualifier ) >= 0) === keep;
+ });
+}
+
+
+
+
+var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,
+ rleadingWhitespace = /^\s+/,
+ rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
+ rtagName = /<([\w:]+)/,
+ rtbody = /<tbody/i,
+ rhtml = /<|&#?\w+;/,
+ rnocache = /<(?:script|object|embed|option|style)/i,
+ // checked="checked" or checked (html5)
+ rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
+ raction = /\=([^="'>\s]+\/)>/g,
+ wrapMap = {
+ option: [ 1, "<select multiple='multiple'>", "</select>" ],
+ legend: [ 1, "<fieldset>", "</fieldset>" ],
+ thead: [ 1, "<table>", "</table>" ],
+ tr: [ 2, "<table><tbody>", "</tbody></table>" ],
+ td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
+ col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
+ area: [ 1, "<map>", "</map>" ],
+ _default: [ 0, "", "" ]
+ };
+
+wrapMap.optgroup = wrapMap.option;
+wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
+wrapMap.th = wrapMap.td;
+
+// IE can't serialize <link> and <script> tags normally
+if ( !jQuery.support.htmlSerialize ) {
+ wrapMap._default = [ 1, "div<div>", "</div>" ];
+}
+
+jQuery.fn.extend({
+ text: function( text ) {
+ if ( jQuery.isFunction(text) ) {
+ return this.each(function(i) {
+ var self = jQuery( this );
+
+ self.text( text.call(this, i, self.text()) );
+ });
+ }
+
+ if ( typeof text !== "object" && text !== undefined ) {
+ return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
+ }
+
+ return jQuery.text( this );
+ },
+
+ wrapAll: function( html ) {
+ if ( jQuery.isFunction( html ) ) {
+ return this.each(function(i) {
+ jQuery(this).wrapAll( html.call(this, i) );
+ });
+ }
+
+ if ( this[0] ) {
+ // The elements to wrap the target around
+ var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
+
+ if ( this[0].parentNode ) {
+ wrap.insertBefore( this[0] );
+ }
+
+ wrap.map(function() {
+ var elem = this;
+
+ while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
+ elem = elem.firstChild;
+ }
+
+ return elem;
+ }).append(this);
+ }
+
+ return this;
+ },
+
+ wrapInner: function( html ) {
+ if ( jQuery.isFunction( html ) ) {
+ return this.each(function(i) {
+ jQuery(this).wrapInner( html.call(this, i) );
+ });
+ }
+
+ return this.each(function() {
+ var self = jQuery( this ),
+ contents = self.contents();
+
+ if ( contents.length ) {
+ contents.wrapAll( html );
+
+ } else {
+ self.append( html );
+ }
+ });
+ },
+
+ wrap: function( html ) {
+ return this.each(function() {
+ jQuery( this ).wrapAll( html );
+ });
+ },
+
+ unwrap: function() {
+ return this.parent().each(function() {
+ if ( !jQuery.nodeName( this, "body" ) ) {
+ jQuery( this ).replaceWith( this.childNodes );
+ }
+ }).end();
+ },
+
+ append: function() {
+ return this.domManip(arguments, true, function( elem ) {
+ if ( this.nodeType === 1 ) {
+ this.appendChild( elem );
+ }
+ });
+ },
+
+ prepend: function() {
+ return this.domManip(arguments, true, function( elem ) {
+ if ( this.nodeType === 1 ) {
+ this.insertBefore( elem, this.firstChild );
+ }
+ });
+ },
+
+ before: function() {
+ if ( this[0] && this[0].parentNode ) {
+ return this.domManip(arguments, false, function( elem ) {
+ this.parentNode.insertBefore( elem, this );
+ });
+ } else if ( arguments.length ) {
+ var set = jQuery(arguments[0]);
+ set.push.apply( set, this.toArray() );
+ return this.pushStack( set, "before", arguments );
+ }
+ },
+
+ after: function() {
+ if ( this[0] && this[0].parentNode ) {
+ return this.domManip(arguments, false, function( elem ) {
+ this.parentNode.insertBefore( elem, this.nextSibling );
+ });
+ } else if ( arguments.length ) {
+ var set = this.pushStack( this, "after", arguments );
+ set.push.apply( set, jQuery(arguments[0]).toArray() );
+ return set;
+ }
+ },
+
+ // keepData is for internal use only--do not document
+ remove: function( selector, keepData ) {
+ for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
+ if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {
+ if ( !keepData && elem.nodeType === 1 ) {
+ jQuery.cleanData( elem.getElementsByTagName("*") );
+ jQuery.cleanData( [ elem ] );
+ }
+
+ if ( elem.parentNode ) {
+ elem.parentNode.removeChild( elem );
+ }
+ }
+ }
+
+ return this;
+ },
+
+ empty: function() {
+ for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {
+ // Remove element nodes and prevent memory leaks
+ if ( elem.nodeType === 1 ) {
+ jQuery.cleanData( elem.getElementsByTagName("*") );
+ }
+
+ // Remove any remaining nodes
+ while ( elem.firstChild ) {
+ elem.removeChild( elem.firstChild );
+ }
+ }
+
+ return this;
+ },
+
+ clone: function( events ) {
+ // Do the clone
+ var ret = this.map(function() {
+ if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
+ // IE copies events bound via attachEvent when
+ // using cloneNode. Calling detachEvent on the
+ // clone will also remove the events from the orignal
+ // In order to get around this, we use innerHTML.
+ // Unfortunately, this means some modifications to
+ // attributes in IE that are actually only stored
+ // as properties will not be copied (such as the
+ // the name attribute on an input).
+ var html = this.outerHTML,
+ ownerDocument = this.ownerDocument;
+
+ if ( !html ) {
+ var div = ownerDocument.createElement("div");
+ div.appendChild( this.cloneNode(true) );
+ html = div.innerHTML;
+ }
+
+ return jQuery.clean([html.replace(rinlinejQuery, "")
+ // Handle the case in IE 8 where action=/test/> self-closes a tag
+ .replace(raction, '="$1">')
+ .replace(rleadingWhitespace, "")], ownerDocument)[0];
+ } else {
+ return this.cloneNode(true);
+ }
+ });
+
+ // Copy the events from the original to the clone
+ if ( events === true ) {
+ cloneCopyEvent( this, ret );
+ cloneCopyEvent( this.find("*"), ret.find("*") );
+ }
+
+ // Return the cloned set
+ return ret;
+ },
+
+ html: function( value ) {
+ if ( value === undefined ) {
+ return this[0] && this[0].nodeType === 1 ?
+ this[0].innerHTML.replace(rinlinejQuery, "") :
+ null;
+
+ // See if we can take a shortcut and just use innerHTML
+ } else if ( typeof value === "string" && !rnocache.test( value ) &&
+ (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&
+ !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {
+
+ value = value.replace(rxhtmlTag, "<$1></$2>");
+
+ try {
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ // Remove element nodes and prevent memory leaks
+ if ( this[i].nodeType === 1 ) {
+ jQuery.cleanData( this[i].getElementsByTagName("*") );
+ this[i].innerHTML = value;
+ }
+ }
+
+ // If using innerHTML throws an exception, use the fallback method
+ } catch(e) {
+ this.empty().append( value );
+ }
+
+ } else if ( jQuery.isFunction( value ) ) {
+ this.each(function(i){
+ var self = jQuery( this );
+
+ self.html( value.call(this, i, self.html()) );
+ });
+
+ } else {
+ this.empty().append( value );
+ }
+
+ return this;
+ },
+
+ replaceWith: function( value ) {
+ if ( this[0] && this[0].parentNode ) {
+ // Make sure that the elements are removed from the DOM before they are inserted
+ // this can help fix replacing a parent with child elements
+ if ( jQuery.isFunction( value ) ) {
+ return this.each(function(i) {
+ var self = jQuery(this), old = self.html();
+ self.replaceWith( value.call( this, i, old ) );
+ });
+ }
+
+ if ( typeof value !== "string" ) {
+ value = jQuery( value ).detach();
+ }
+
+ return this.each(function() {
+ var next = this.nextSibling,
+ parent = this.parentNode;
+
+ jQuery( this ).remove();
+
+ if ( next ) {
+ jQuery(next).before( value );
+ } else {
+ jQuery(parent).append( value );
+ }
+ });
+ } else {
+ return this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value );
+ }
+ },
+
+ detach: function( selector ) {
+ return this.remove( selector, true );
+ },
+
+ domManip: function( args, table, callback ) {
+ var results, first, fragment, parent,
+ value = args[0],
+ scripts = [];
+
+ // We can't cloneNode fragments that contain checked, in WebKit
+ if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {
+ return this.each(function() {
+ jQuery(this).domManip( args, table, callback, true );
+ });
+ }
+
+ if ( jQuery.isFunction(value) ) {
+ return this.each(function(i) {
+ var self = jQuery(this);
+ args[0] = value.call(this, i, table ? self.html() : undefined);
+ self.domManip( args, table, callback );
+ });
+ }
+
+ if ( this[0] ) {
+ parent = value && value.parentNode;
+
+ // If we're in a fragment, just use that instead of building a new one
+ if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {
+ results = { fragment: parent };
+
+ } else {
+ results = jQuery.buildFragment( args, this, scripts );
+ }
+
+ fragment = results.fragment;
+
+ if ( fragment.childNodes.length === 1 ) {
+ first = fragment = fragment.firstChild;
+ } else {
+ first = fragment.firstChild;
+ }
+
+ if ( first ) {
+ table = table && jQuery.nodeName( first, "tr" );
+
+ for ( var i = 0, l = this.length; i < l; i++ ) {
+ callback.call(
+ table ?
+ root(this[i], first) :
+ this[i],
+ i > 0 || results.cacheable || this.length > 1 ?
+ fragment.cloneNode(true) :
+ fragment
+ );
+ }
+ }
+
+ if ( scripts.length ) {
+ jQuery.each( scripts, evalScript );
+ }
+ }
+
+ return this;
+ }
+});
+
+function root( elem, cur ) {
+ return jQuery.nodeName(elem, "table") ?
+ (elem.getElementsByTagName("tbody")[0] ||
+ elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
+ elem;
+}
+
+function cloneCopyEvent(orig, ret) {
+ var i = 0;
+
+ ret.each(function() {
+ if ( this.nodeName !== (orig[i] && orig[i].nodeName) ) {
+ return;
+ }
+
+ var oldData = jQuery.data( orig[i++] ),
+ curData = jQuery.data( this, oldData ),
+ events = oldData && oldData.events;
+
+ if ( events ) {
+ delete curData.handle;
+ curData.events = {};
+
+ for ( var type in events ) {
+ for ( var handler in events[ type ] ) {
+ jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
+ }
+ }
+ }
+ });
+}
+
+jQuery.buildFragment = function( args, nodes, scripts ) {
+ var fragment, cacheable, cacheresults,
+ doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);
+
+ // Only cache "small" (1/2 KB) strings that are associated with the main document
+ // Cloning options loses the selected state, so don't cache them
+ // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment
+ // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
+ if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document &&
+ !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {
+
+ cacheable = true;
+ cacheresults = jQuery.fragments[ args[0] ];
+ if ( cacheresults ) {
+ if ( cacheresults !== 1 ) {
+ fragment = cacheresults;
+ }
+ }
+ }
+
+ if ( !fragment ) {
+ fragment = doc.createDocumentFragment();
+ jQuery.clean( args, doc, fragment, scripts );
+ }
+
+ if ( cacheable ) {
+ jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;
+ }
+
+ return { fragment: fragment, cacheable: cacheable };
+};
+
+jQuery.fragments = {};
+
+jQuery.each({
+ appendTo: "append",
+ prependTo: "prepend",
+ insertBefore: "before",
+ insertAfter: "after",
+ replaceAll: "replaceWith"
+}, function( name, original ) {
+ jQuery.fn[ name ] = function( selector ) {
+ var ret = [],
+ insert = jQuery( selector ),
+ parent = this.length === 1 && this[0].parentNode;
+
+ if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
+ insert[ original ]( this[0] );
+ return this;
+
+ } else {
+ for ( var i = 0, l = insert.length; i < l; i++ ) {
+ var elems = (i > 0 ? this.clone(true) : this).get();
+ jQuery( insert[i] )[ original ]( elems );
+ ret = ret.concat( elems );
+ }
+
+ return this.pushStack( ret, name, insert.selector );
+ }
+ };
+});
+
+jQuery.extend({
+ clean: function( elems, context, fragment, scripts ) {
+ context = context || document;
+
+ // !context.createElement fails in IE with an error but returns typeof 'object'
+ if ( typeof context.createElement === "undefined" ) {
+ context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
+ }
+
+ var ret = [];
+
+ for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
+ if ( typeof elem === "number" ) {
+ elem += "";
+ }
+
+ if ( !elem ) {
+ continue;
+ }
+
+ // Convert html string into DOM nodes
+ if ( typeof elem === "string" && !rhtml.test( elem ) ) {
+ elem = context.createTextNode( elem );
+
+ } else if ( typeof elem === "string" ) {
+ // Fix "XHTML"-style tags in all browsers
+ elem = elem.replace(rxhtmlTag, "<$1></$2>");
+
+ // Trim whitespace, otherwise indexOf won't work as expected
+ var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),
+ wrap = wrapMap[ tag ] || wrapMap._default,
+ depth = wrap[0],
+ div = context.createElement("div");
+
+ // Go to html and back, then peel off extra wrappers
+ div.innerHTML = wrap[1] + elem + wrap[2];
+
+ // Move to the right depth
+ while ( depth-- ) {
+ div = div.lastChild;
+ }
+
+ // Remove IE's autoinserted <tbody> from table fragments
+ if ( !jQuery.support.tbody ) {
+
+ // String was a <table>, *may* have spurious <tbody>
+ var hasBody = rtbody.test(elem),
+ tbody = tag === "table" && !hasBody ?
+ div.firstChild && div.firstChild.childNodes :
+
+ // String was a bare <thead> or <tfoot>
+ wrap[1] === "<table>" && !hasBody ?
+ div.childNodes :
+ [];
+
+ for ( var j = tbody.length - 1; j >= 0 ; --j ) {
+ if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {
+ tbody[ j ].parentNode.removeChild( tbody[ j ] );
+ }
+ }
+
+ }
+
+ // IE completely kills leading whitespace when innerHTML is used
+ if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
+ div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );
+ }
+
+ elem = div.childNodes;
+ }
+
+ if ( elem.nodeType ) {
+ ret.push( elem );
+ } else {
+ ret = jQuery.merge( ret, elem );
+ }
+ }
+
+ if ( fragment ) {
+ for ( i = 0; ret[i]; i++ ) {
+ if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
+ scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
+
+ } else {
+ if ( ret[i].nodeType === 1 ) {
+ ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
+ }
+ fragment.appendChild( ret[i] );
+ }
+ }
+ }
+
+ return ret;
+ },
+
+ cleanData: function( elems ) {
+ var data, id, cache = jQuery.cache,
+ special = jQuery.event.special,
+ deleteExpando = jQuery.support.deleteExpando;
+
+ for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
+ if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
+ continue;
+ }
+
+ id = elem[ jQuery.expando ];
+
+ if ( id ) {
+ data = cache[ id ];
+
+ if ( data && data.events ) {
+ for ( var type in data.events ) {
+ if ( special[ type ] ) {
+ jQuery.event.remove( elem, type );
+
+ } else {
+ jQuery.removeEvent( elem, type, data.handle );
+ }
+ }
+ }
+
+ if ( deleteExpando ) {
+ delete elem[ jQuery.expando ];
+
+ } else if ( elem.removeAttribute ) {
+ elem.removeAttribute( jQuery.expando );
+ }
+
+ delete cache[ id ];
+ }
+ }
+ }
+});
+
+function evalScript( i, elem ) {
+ if ( elem.src ) {
+ jQuery.ajax({
+ url: elem.src,
+ async: false,
+ dataType: "script"
+ });
+ } else {
+ jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
+ }
+
+ if ( elem.parentNode ) {
+ elem.parentNode.removeChild( elem );
+ }
+}
+
+
+
+
+var ralpha = /alpha\([^)]*\)/i,
+ ropacity = /opacity=([^)]*)/,
+ rdashAlpha = /-([a-z])/ig,
+ rupper = /([A-Z])/g,
+ rnumpx = /^-?\d+(?:px)?$/i,
+ rnum = /^-?\d/,
+
+ cssShow = { position: "absolute", visibility: "hidden", display: "block" },
+ cssWidth = [ "Left", "Right" ],
+ cssHeight = [ "Top", "Bottom" ],
+ curCSS,
+
+ getComputedStyle,
+ currentStyle,
+
+ fcamelCase = function( all, letter ) {
+ return letter.toUpperCase();
+ };
+
+jQuery.fn.css = function( name, value ) {
+ // Setting 'undefined' is a no-op
+ if ( arguments.length === 2 && value === undefined ) {
+ return this;
+ }
+
+ return jQuery.access( this, name, value, true, function( elem, name, value ) {
+ return value !== undefined ?
+ jQuery.style( elem, name, value ) :
+ jQuery.css( elem, name );
+ });
+};
+
+jQuery.extend({
+ // Add in style property hooks for overriding the default
+ // behavior of getting and setting a style property
+ cssHooks: {
+ opacity: {
+ get: function( elem, computed ) {
+ if ( computed ) {
+ // We should always get a number back from opacity
+ var ret = curCSS( elem, "opacity", "opacity" );
+ return ret === "" ? "1" : ret;
+
+ } else {
+ return elem.style.opacity;
+ }
+ }
+ }
+ },
+
+ // Exclude the following css properties to add px
+ cssNumber: {
+ "zIndex": true,
+ "fontWeight": true,
+ "opacity": true,
+ "zoom": true,
+ "lineHeight": true
+ },
+
+ // Add in properties whose names you wish to fix before
+ // setting or getting the value
+ cssProps: {
+ // normalize float css property
+ "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
+ },
+
+ // Get and set the style property on a DOM Node
+ style: function( elem, name, value, extra ) {
+ // Don't set styles on text and comment nodes
+ if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
+ return;
+ }
+
+ // Make sure that we're working with the right name
+ var ret, origName = jQuery.camelCase( name ),
+ style = elem.style, hooks = jQuery.cssHooks[ origName ];
+
+ name = jQuery.cssProps[ origName ] || origName;
+
+ // Check if we're setting a value
+ if ( value !== undefined ) {
+ // Make sure that NaN and null values aren't set. See: #7116
+ if ( typeof value === "number" && isNaN( value ) || value == null ) {
+ return;
+ }
+
+ // If a number was passed in, add 'px' to the (except for certain CSS properties)
+ if ( typeof value === "number" && !jQuery.cssNumber[ origName ] ) {
+ value += "px";
+ }
+
+ // If a hook was provided, use that value, otherwise just set the specified value
+ if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {
+ // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
+ // Fixes bug #5509
+ try {
+ style[ name ] = value;
+ } catch(e) {}
+ }
+
+ } else {
+ // If a hook was provided get the non-computed value from there
+ if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
+ return ret;
+ }
+
+ // Otherwise just get the value from the style object
+ return style[ name ];
+ }
+ },
+
+ css: function( elem, name, extra ) {
+ // Make sure that we're working with the right name
+ var ret, origName = jQuery.camelCase( name ),
+ hooks = jQuery.cssHooks[ origName ];
+
+ name = jQuery.cssProps[ origName ] || origName;
+
+ // If a hook was provided get the computed value from there
+ if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {
+ return ret;
+
+ // Otherwise, if a way to get the computed value exists, use that
+ } else if ( curCSS ) {
+ return curCSS( elem, name, origName );
+ }
+ },
+
+ // A method for quickly swapping in/out CSS properties to get correct calculations
+ swap: function( elem, options, callback ) {
+ var old = {};
+
+ // Remember the old values, and insert the new ones
+ for ( var name in options ) {
+ old[ name ] = elem.style[ name ];
+ elem.style[ name ] = options[ name ];
+ }
+
+ callback.call( elem );
+
+ // Revert the old values
+ for ( name in options ) {
+ elem.style[ name ] = old[ name ];
+ }
+ },
+
+ camelCase: function( string ) {
+ return string.replace( rdashAlpha, fcamelCase );
+ }
+});
+
+// DEPRECATED, Use jQuery.css() instead
+jQuery.curCSS = jQuery.css;
+
+jQuery.each(["height", "width"], function( i, name ) {
+ jQuery.cssHooks[ name ] = {
+ get: function( elem, computed, extra ) {
+ var val;
+
+ if ( computed ) {
+ if ( elem.offsetWidth !== 0 ) {
+ val = getWH( elem, name, extra );
+
+ } else {
+ jQuery.swap( elem, cssShow, function() {
+ val = getWH( elem, name, extra );
+ });
+ }
+
+ if ( val <= 0 ) {
+ val = curCSS( elem, name, name );
+
+ if ( val === "0px" && currentStyle ) {
+ val = currentStyle( elem, name, name );
+ }
+
+ if ( val != null ) {
+ // Should return "auto" instead of 0, use 0 for
+ // temporary backwards-compat
+ return val === "" || val === "auto" ? "0px" : val;
+ }
+ }
+
+ if ( val < 0 || val == null ) {
+ val = elem.style[ name ];
+
+ // Should return "auto" instead of 0, use 0 for
+ // temporary backwards-compat
+ return val === "" || val === "auto" ? "0px" : val;
+ }
+
+ return typeof val === "string" ? val : val + "px";
+ }
+ },
+
+ set: function( elem, value ) {
+ if ( rnumpx.test( value ) ) {
+ // ignore negative width and height values #1599
+ value = parseFloat(value);
+
+ if ( value >= 0 ) {
+ return value + "px";
+ }
+
+ } else {
+ return value;
+ }
+ }
+ };
+});
+
+if ( !jQuery.support.opacity ) {
+ jQuery.cssHooks.opacity = {
+ get: function( elem, computed ) {
+ // IE uses filters for opacity
+ return ropacity.test((computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "") ?
+ (parseFloat(RegExp.$1) / 100) + "" :
+ computed ? "1" : "";
+ },
+
+ set: function( elem, value ) {
+ var style = elem.style;
+
+ // IE has trouble with opacity if it does not have layout
+ // Force it by setting the zoom level
+ style.zoom = 1;
+
+ // Set the alpha filter to set the opacity
+ var opacity = jQuery.isNaN(value) ?
+ "" :
+ "alpha(opacity=" + value * 100 + ")",
+ filter = style.filter || "";
+
+ style.filter = ralpha.test(filter) ?
+ filter.replace(ralpha, opacity) :
+ style.filter + ' ' + opacity;
+ }
+ };
+}
+
+if ( document.defaultView && document.defaultView.getComputedStyle ) {
+ getComputedStyle = function( elem, newName, name ) {
+ var ret, defaultView, computedStyle;
+
+ name = name.replace( rupper, "-$1" ).toLowerCase();
+
+ if ( !(defaultView = elem.ownerDocument.defaultView) ) {
+ return undefined;
+ }
+
+ if ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
+ ret = computedStyle.getPropertyValue( name );
+ if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
+ ret = jQuery.style( elem, name );
+ }
+ }
+
+ return ret;
+ };
+}
+
+if ( document.documentElement.currentStyle ) {
+ currentStyle = function( elem, name ) {
+ var left, rsLeft,
+ ret = elem.currentStyle && elem.currentStyle[ name ],
+ style = elem.style;
+
+ // From the awesome hack by Dean Edwards
+ // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
+
+ // If we're not dealing with a regular pixel number
+ // but a number that has a weird ending, we need to convert it to pixels
+ if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
+ // Remember the original values
+ left = style.left;
+ rsLeft = elem.runtimeStyle.left;
+
+ // Put in the new values to get a computed value out
+ elem.runtimeStyle.left = elem.currentStyle.left;
+ style.left = name === "fontSize" ? "1em" : (ret || 0);
+ ret = style.pixelLeft + "px";
+
+ // Revert the changed values
+ style.left = left;
+ elem.runtimeStyle.left = rsLeft;
+ }
+
+ return ret === "" ? "auto" : ret;
+ };
+}
+
+curCSS = getComputedStyle || currentStyle;
+
+function getWH( elem, name, extra ) {
+ var which = name === "width" ? cssWidth : cssHeight,
+ val = name === "width" ? elem.offsetWidth : elem.offsetHeight;
+
+ if ( extra === "border" ) {
+ return val;
+ }
+
+ jQuery.each( which, function() {
+ if ( !extra ) {
+ val -= parseFloat(jQuery.css( elem, "padding" + this )) || 0;
+ }
+
+ if ( extra === "margin" ) {
+ val += parseFloat(jQuery.css( elem, "margin" + this )) || 0;
+
+ } else {
+ val -= parseFloat(jQuery.css( elem, "border" + this + "Width" )) || 0;
+ }
+ });
+
+ return val;
+}
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+ jQuery.expr.filters.hidden = function( elem ) {
+ var width = elem.offsetWidth,
+ height = elem.offsetHeight;
+
+ return (width === 0 && height === 0) || (!jQuery.support.reliableHiddenOffsets && (elem.style.display || jQuery.css( elem, "display" )) === "none");
+ };
+
+ jQuery.expr.filters.visible = function( elem ) {
+ return !jQuery.expr.filters.hidden( elem );
+ };
+}
+
+
+
+
+var jsc = jQuery.now(),
+ rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
+ rselectTextarea = /^(?:select|textarea)/i,
+ rinput = /^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,
+ rnoContent = /^(?:GET|HEAD)$/,
+ rbracket = /\[\]$/,
+ jsre = /\=\?(&|$)/,
+ rquery = /\?/,
+ rts = /([?&])_=[^&]*/,
+ rurl = /^(\w+:)?\/\/([^\/?#]+)/,
+ r20 = /%20/g,
+ rhash = /#.*$/,
+
+ // Keep a copy of the old load method
+ _load = jQuery.fn.load;
+
+jQuery.fn.extend({
+ load: function( url, params, callback ) {
+ if ( typeof url !== "string" && _load ) {
+ return _load.apply( this, arguments );
+
+ // Don't do a request if no elements are being requested
+ } else if ( !this.length ) {
+ return this;
+ }
+
+ var off = url.indexOf(" ");
+ if ( off >= 0 ) {
+ var selector = url.slice(off, url.length);
+ url = url.slice(0, off);
+ }
+
+ // Default to a GET request
+ var type = "GET";
+
+ // If the second parameter was provided
+ if ( params ) {
+ // If it's a function
+ if ( jQuery.isFunction( params ) ) {
+ // We assume that it's the callback
+ callback = params;
+ params = null;
+
+ // Otherwise, build a param string
+ } else if ( typeof params === "object" ) {
+ params = jQuery.param( params, jQuery.ajaxSettings.traditional );
+ type = "POST";
+ }
+ }
+
+ var self = this;
+
+ // Request the remote document
+ jQuery.ajax({
+ url: url,
+ type: type,
+ dataType: "html",
+ data: params,
+ complete: function( res, status ) {
+ // If successful, inject the HTML into all the matched elements
+ if ( status === "success" || status === "notmodified" ) {
+ // See if a selector was specified
+ self.html( selector ?
+ // Create a dummy div to hold the results
+ jQuery("<div>")
+ // inject the contents of the document in, removing the scripts
+ // to avoid any 'Permission Denied' errors in IE
+ .append(res.responseText.replace(rscript, ""))
+
+ // Locate the specified elements
+ .find(selector) :
+
+ // If not, just inject the full result
+ res.responseText );
+ }
+
+ if ( callback ) {
+ self.each( callback, [res.responseText, status, res] );
+ }
+ }
+ });
+
+ return this;
+ },
+
+ serialize: function() {
+ return jQuery.param(this.serializeArray());
+ },
+
+ serializeArray: function() {
+ return this.map(function() {
+ return this.elements ? jQuery.makeArray(this.elements) : this;
+ })
+ .filter(function() {
+ return this.name && !this.disabled &&
+ (this.checked || rselectTextarea.test(this.nodeName) ||
+ rinput.test(this.type));
+ })
+ .map(function( i, elem ) {
+ var val = jQuery(this).val();
+
+ return val == null ?
+ null :
+ jQuery.isArray(val) ?
+ jQuery.map( val, function( val, i ) {
+ return { name: elem.name, value: val };
+ }) :
+ { name: elem.name, value: val };
+ }).get();
+ }
+});
+
+// Attach a bunch of functions for handling common AJAX events
+jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), function( i, o ) {
+ jQuery.fn[o] = function( f ) {
+ return this.bind(o, f);
+ };
+});
+
+jQuery.extend({
+ get: function( url, data, callback, type ) {
+ // shift arguments if data argument was omited
+ if ( jQuery.isFunction( data ) ) {
+ type = type || callback;
+ callback = data;
+ data = null;
+ }
+
+ return jQuery.ajax({
+ type: "GET",
+ url: url,
+ data: data,
+ success: callback,
+ dataType: type
+ });
+ },
+
+ getScript: function( url, callback ) {
+ return jQuery.get(url, null, callback, "script");
+ },
+
+ getJSON: function( url, data, callback ) {
+ return jQuery.get(url, data, callback, "json");
+ },
+
+ post: function( url, data, callback, type ) {
+ // shift arguments if data argument was omited
+ if ( jQuery.isFunction( data ) ) {
+ type = type || callback;
+ callback = data;
+ data = {};
+ }
+
+ return jQuery.ajax({
+ type: "POST",
+ url: url,
+ data: data,
+ success: callback,
+ dataType: type
+ });
+ },
+
+ ajaxSetup: function( settings ) {
+ jQuery.extend( jQuery.ajaxSettings, settings );
+ },
+
+ ajaxSettings: {
+ url: location.href,
+ global: true,
+ type: "GET",
+ contentType: "application/x-www-form-urlencoded",
+ processData: true,
+ async: true,
+ /*
+ timeout: 0,
+ data: null,
+ username: null,
+ password: null,
+ traditional: false,
+ */
+ // This function can be overriden by calling jQuery.ajaxSetup
+ xhr: function() {
+ return new window.XMLHttpRequest();
+ },
+ accepts: {
+ xml: "application/xml, text/xml",
+ html: "text/html",
+ script: "text/javascript, application/javascript",
+ json: "application/json, text/javascript",
+ text: "text/plain",
+ _default: "*/*"
+ }
+ },
+
+ ajax: function( origSettings ) {
+ var s = jQuery.extend(true, {}, jQuery.ajaxSettings, origSettings),
+ jsonp, status, data, type = s.type.toUpperCase(), noContent = rnoContent.test(type);
+
+ s.url = s.url.replace( rhash, "" );
+
+ // Use original (not extended) context object if it was provided
+ s.context = origSettings && origSettings.context != null ? origSettings.context : s;
+
+ // convert data if not already a string
+ if ( s.data && s.processData && typeof s.data !== "string" ) {
+ s.data = jQuery.param( s.data, s.traditional );
+ }
+
+ // Handle JSONP Parameter Callbacks
+ if ( s.dataType === "jsonp" ) {
+ if ( type === "GET" ) {
+ if ( !jsre.test( s.url ) ) {
+ s.url += (rquery.test( s.url ) ? "&" : "?") + (s.jsonp || "callback") + "=?";
+ }
+ } else if ( !s.data || !jsre.test(s.data) ) {
+ s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
+ }
+ s.dataType = "json";
+ }
+
+ // Build temporary JSONP function
+ if ( s.dataType === "json" && (s.data && jsre.test(s.data) || jsre.test(s.url)) ) {
+ jsonp = s.jsonpCallback || ("jsonp" + jsc++);
+
+ // Replace the =? sequence both in the query string and the data
+ if ( s.data ) {
+ s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
+ }
+
+ s.url = s.url.replace(jsre, "=" + jsonp + "$1");
+
+ // We need to make sure
+ // that a JSONP style response is executed properly
+ s.dataType = "script";
+
+ // Handle JSONP-style loading
+ var customJsonp = window[ jsonp ];
+
+ window[ jsonp ] = function( tmp ) {
+ if ( jQuery.isFunction( customJsonp ) ) {
+ customJsonp( tmp );
+
+ } else {
+ // Garbage collect
+ window[ jsonp ] = undefined;
+
+ try {
+ delete window[ jsonp ];
+ } catch( jsonpError ) {}
+ }
+
+ data = tmp;
+ jQuery.handleSuccess( s, xhr, status, data );
+ jQuery.handleComplete( s, xhr, status, data );
+
+ if ( head ) {
+ head.removeChild( script );
+ }
+ };
+ }
+
+ if ( s.dataType === "script" && s.cache === null ) {
+ s.cache = false;
+ }
+
+ if ( s.cache === false && noContent ) {
+ var ts = jQuery.now();
+
+ // try replacing _= if it is there
+ var ret = s.url.replace(rts, "$1_=" + ts);
+
+ // if nothing was replaced, add timestamp to the end
+ s.url = ret + ((ret === s.url) ? (rquery.test(s.url) ? "&" : "?") + "_=" + ts : "");
+ }
+
+ // If data is available, append data to url for GET/HEAD requests
+ if ( s.data && noContent ) {
+ s.url += (rquery.test(s.url) ? "&" : "?") + s.data;
+ }
+
+ // Watch for a new set of requests
+ if ( s.global && jQuery.active++ === 0 ) {
+ jQuery.event.trigger( "ajaxStart" );
+ }
+
+ // Matches an absolute URL, and saves the domain
+ var parts = rurl.exec( s.url ),
+ remote = parts && (parts[1] && parts[1].toLowerCase() !== location.protocol || parts[2].toLowerCase() !== location.host);
+
+ // If we're requesting a remote document
+ // and trying to load JSON or Script with a GET
+ if ( s.dataType === "script" && type === "GET" && remote ) {
+ var head = document.getElementsByTagName("head")[0] || document.documentElement;
+ var script = document.createElement("script");
+ if ( s.scriptCharset ) {
+ script.charset = s.scriptCharset;
+ }
+ script.src = s.url;
+
+ // Handle Script loading
+ if ( !jsonp ) {
+ var done = false;
+
+ // Attach handlers for all browsers
+ script.onload = script.onreadystatechange = function() {
+ if ( !done && (!this.readyState ||
+ this.readyState === "loaded" || this.readyState === "complete") ) {
+ done = true;
+ jQuery.handleSuccess( s, xhr, status, data );
+ jQuery.handleComplete( s, xhr, status, data );
+
+ // Handle memory leak in IE
+ script.onload = script.onreadystatechange = null;
+ if ( head && script.parentNode ) {
+ head.removeChild( script );
+ }
+ }
+ };
+ }
+
+ // Use insertBefore instead of appendChild to circumvent an IE6 bug.
+ // This arises when a base node is used (#2709 and #4378).
+ head.insertBefore( script, head.firstChild );
+
+ // We handle everything using the script element injection
+ return undefined;
+ }
+
+ var requestDone = false;
+
+ // Create the request object
+ var xhr = s.xhr();
+
+ if ( !xhr ) {
+ return;
+ }
+
+ // Open the socket
+ // Passing null username, generates a login popup on Opera (#2865)
+ if ( s.username ) {
+ xhr.open(type, s.url, s.async, s.username, s.password);
+ } else {
+ xhr.open(type, s.url, s.async);
+ }
+
+ // Need an extra try/catch for cross domain requests in Firefox 3
+ try {
+ // Set content-type if data specified and content-body is valid for this type
+ if ( (s.data != null && !noContent) || (origSettings && origSettings.contentType) ) {
+ xhr.setRequestHeader("Content-Type", s.contentType);
+ }
+
+ // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+ if ( s.ifModified ) {
+ if ( jQuery.lastModified[s.url] ) {
+ xhr.setRequestHeader("If-Modified-Since", jQuery.lastModified[s.url]);
+ }
+
+ if ( jQuery.etag[s.url] ) {
+ xhr.setRequestHeader("If-None-Match", jQuery.etag[s.url]);
+ }
+ }
+
+ // Set header so the called script knows that it's an XMLHttpRequest
+ // Only send the header if it's not a remote XHR
+ if ( !remote ) {
+ xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+ }
+
+ // Set the Accepts header for the server, depending on the dataType
+ xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
+ s.accepts[ s.dataType ] + ", */*; q=0.01" :
+ s.accepts._default );
+ } catch( headerError ) {}
+
+ // Allow custom headers/mimetypes and early abort
+ if ( s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false ) {
+ // Handle the global AJAX counter
+ if ( s.global && jQuery.active-- === 1 ) {
+ jQuery.event.trigger( "ajaxStop" );
+ }
+
+ // close opended socket
+ xhr.abort();
+ return false;
+ }
+
+ if ( s.global ) {
+ jQuery.triggerGlobal( s, "ajaxSend", [xhr, s] );
+ }
+
+ // Wait for a response to come back
+ var onreadystatechange = xhr.onreadystatechange = function( isTimeout ) {
+ // The request was aborted
+ if ( !xhr || xhr.readyState === 0 || isTimeout === "abort" ) {
+ // Opera doesn't call onreadystatechange before this point
+ // so we simulate the call
+ if ( !requestDone ) {
+ jQuery.handleComplete( s, xhr, status, data );
+ }
+
+ requestDone = true;
+ if ( xhr ) {
+ xhr.onreadystatechange = jQuery.noop;
+ }
+
+ // The transfer is complete and the data is available, or the request timed out
+ } else if ( !requestDone && xhr && (xhr.readyState === 4 || isTimeout === "timeout") ) {
+ requestDone = true;
+ xhr.onreadystatechange = jQuery.noop;
+
+ status = isTimeout === "timeout" ?
+ "timeout" :
+ !jQuery.httpSuccess( xhr ) ?
+ "error" :
+ s.ifModified && jQuery.httpNotModified( xhr, s.url ) ?
+ "notmodified" :
+ "success";
+
+ var errMsg;
+
+ if ( status === "success" ) {
+ // Watch for, and catch, XML document parse errors
+ try {
+ // process the data (runs the xml through httpData regardless of callback)
+ data = jQuery.httpData( xhr, s.dataType, s );
+ } catch( parserError ) {
+ status = "parsererror";
+ errMsg = parserError;
+ }
+ }
+
+ // Make sure that the request was successful or notmodified
+ if ( status === "success" || status === "notmodified" ) {
+ // JSONP handles its own success callback
+ if ( !jsonp ) {
+ jQuery.handleSuccess( s, xhr, status, data );
+ }
+ } else {
+ jQuery.handleError( s, xhr, status, errMsg );
+ }
+
+ // Fire the complete handlers
+ if ( !jsonp ) {
+ jQuery.handleComplete( s, xhr, status, data );
+ }
+
+ if ( isTimeout === "timeout" ) {
+ xhr.abort();
+ }
+
+ // Stop memory leaks
+ if ( s.async ) {
+ xhr = null;
+ }
+ }
+ };
+
+ // Override the abort handler, if we can (IE 6 doesn't allow it, but that's OK)
+ // Opera doesn't fire onreadystatechange at all on abort
+ try {
+ var oldAbort = xhr.abort;
+ xhr.abort = function() {
+ if ( xhr ) {
+ // oldAbort has no call property in IE7 so
+ // just do it this way, which works in all
+ // browsers
+ Function.prototype.call.call( oldAbort, xhr );
+ }
+
+ onreadystatechange( "abort" );
+ };
+ } catch( abortError ) {}
+
+ // Timeout checker
+ if ( s.async && s.timeout > 0 ) {
+ setTimeout(function() {
+ // Check to see if the request is still happening
+ if ( xhr && !requestDone ) {
+ onreadystatechange( "timeout" );
+ }
+ }, s.timeout);
+ }
+
+ // Send the data
+ try {
+ xhr.send( noContent || s.data == null ? null : s.data );
+
+ } catch( sendError ) {
+ jQuery.handleError( s, xhr, null, sendError );
+
+ // Fire the complete handlers
+ jQuery.handleComplete( s, xhr, status, data );
+ }
+
+ // firefox 1.5 doesn't fire statechange for sync requests
+ if ( !s.async ) {
+ onreadystatechange();
+ }
+
+ // return XMLHttpRequest to allow aborting the request etc.
+ return xhr;
+ },
+
+ // Serialize an array of form elements or a set of
+ // key/values into a query string
+ param: function( a, traditional ) {
+ var s = [],
+ add = function( key, value ) {
+ // If value is a function, invoke it and return its value
+ value = jQuery.isFunction(value) ? value() : value;
+ s[ s.length ] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
+ };
+
+ // Set traditional to true for jQuery <= 1.3.2 behavior.
+ if ( traditional === undefined ) {
+ traditional = jQuery.ajaxSettings.traditional;
+ }
+
+ // If an array was passed in, assume that it is an array of form elements.
+ if ( jQuery.isArray(a) || a.jquery ) {
+ // Serialize the form elements
+ jQuery.each( a, function() {
+ add( this.name, this.value );
+ });
+
+ } else {
+ // If traditional, encode the "old" way (the way 1.3.2 or older
+ // did it), otherwise encode params recursively.
+ for ( var prefix in a ) {
+ buildParams( prefix, a[prefix], traditional, add );
+ }
+ }
+
+ // Return the resulting serialization
+ return s.join("&").replace(r20, "+");
+ }
+});
+
+function buildParams( prefix, obj, traditional, add ) {
+ if ( jQuery.isArray(obj) && obj.length ) {
+ // Serialize array item.
+ jQuery.each( obj, function( i, v ) {
+ if ( traditional || rbracket.test( prefix ) ) {
+ // Treat each array item as a scalar.
+ add( prefix, v );
+
+ } else {
+ // If array item is non-scalar (array or object), encode its
+ // numeric index to resolve deserialization ambiguity issues.
+ // Note that rack (as of 1.0.0) can't currently deserialize
+ // nested arrays properly, and attempting to do so may cause
+ // a server error. Possible fixes are to modify rack's
+ // deserialization algorithm or to provide an option or flag
+ // to force array serialization to be shallow.
+ buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v, traditional, add );
+ }
+ });
+
+ } else if ( !traditional && obj != null && typeof obj === "object" ) {
+ if ( jQuery.isEmptyObject( obj ) ) {
+ add( prefix, "" );
+
+ // Serialize object item.
+ } else {
+ jQuery.each( obj, function( k, v ) {
+ buildParams( prefix + "[" + k + "]", v, traditional, add );
+ });
+ }
+
+ } else {
+ // Serialize scalar item.
+ add( prefix, obj );
+ }
+}
+
+// This is still on the jQuery object... for now
+// Want to move this to jQuery.ajax some day
+jQuery.extend({
+
+ // Counter for holding the number of active queries
+ active: 0,
+
+ // Last-Modified header cache for next request
+ lastModified: {},
+ etag: {},
+
+ handleError: function( s, xhr, status, e ) {
+ // If a local callback was specified, fire it
+ if ( s.error ) {
+ s.error.call( s.context, xhr, status, e );
+ }
+
+ // Fire the global callback
+ if ( s.global ) {
+ jQuery.triggerGlobal( s, "ajaxError", [xhr, s, e] );
+ }
+ },
+
+ handleSuccess: function( s, xhr, status, data ) {
+ // If a local callback was specified, fire it and pass it the data
+ if ( s.success ) {
+ s.success.call( s.context, data, status, xhr );
+ }
+
+ // Fire the global callback
+ if ( s.global ) {
+ jQuery.triggerGlobal( s, "ajaxSuccess", [xhr, s] );
+ }
+ },
+
+ handleComplete: function( s, xhr, status ) {
+ // Process result
+ if ( s.complete ) {
+ s.complete.call( s.context, xhr, status );
+ }
+
+ // The request was completed
+ if ( s.global ) {
+ jQuery.triggerGlobal( s, "ajaxComplete", [xhr, s] );
+ }
+
+ // Handle the global AJAX counter
+ if ( s.global && jQuery.active-- === 1 ) {
+ jQuery.event.trigger( "ajaxStop" );
+ }
+ },
+
+ triggerGlobal: function( s, type, args ) {
+ (s.context && s.context.url == null ? jQuery(s.context) : jQuery.event).trigger(type, args);
+ },
+
+ // Determines if an XMLHttpRequest was successful or not
+ httpSuccess: function( xhr ) {
+ try {
+ // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
+ return !xhr.status && location.protocol === "file:" ||
+ xhr.status >= 200 && xhr.status < 300 ||
+ xhr.status === 304 || xhr.status === 1223;
+ } catch(e) {}
+
+ return false;
+ },
+
+ // Determines if an XMLHttpRequest returns NotModified
+ httpNotModified: function( xhr, url ) {
+ var lastModified = xhr.getResponseHeader("Last-Modified"),
+ etag = xhr.getResponseHeader("Etag");
+
+ if ( lastModified ) {
+ jQuery.lastModified[url] = lastModified;
+ }
+
+ if ( etag ) {
+ jQuery.etag[url] = etag;
+ }
+
+ return xhr.status === 304;
+ },
+
+ httpData: function( xhr, type, s ) {
+ var ct = xhr.getResponseHeader("content-type") || "",
+ xml = type === "xml" || !type && ct.indexOf("xml") >= 0,
+ data = xml ? xhr.responseXML : xhr.responseText;
+
+ if ( xml && data.documentElement.nodeName === "parsererror" ) {
+ jQuery.error( "parsererror" );
+ }
+
+ // Allow a pre-filtering function to sanitize the response
+ // s is checked to keep backwards compatibility
+ if ( s && s.dataFilter ) {
+ data = s.dataFilter( data, type );
+ }
+
+ // The filter can actually parse the response
+ if ( typeof data === "string" ) {
+ // Get the JavaScript object, if JSON is used.
+ if ( type === "json" || !type && ct.indexOf("json") >= 0 ) {
+ data = jQuery.parseJSON( data );
+
+ // If the type is "script", eval it in global context
+ } else if ( type === "script" || !type && ct.indexOf("javascript") >= 0 ) {
+ jQuery.globalEval( data );
+ }
+ }
+
+ return data;
+ }
+
+});
+
+/*
+ * Create the request object; Microsoft failed to properly
+ * implement the XMLHttpRequest in IE7 (can't request local files),
+ * so we use the ActiveXObject when it is available
+ * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
+ * we need a fallback.
+ */
+if ( window.ActiveXObject ) {
+ jQuery.ajaxSettings.xhr = function() {
+ if ( window.location.protocol !== "file:" ) {
+ try {
+ return new window.XMLHttpRequest();
+ } catch(xhrError) {}
+ }
+
+ try {
+ return new window.ActiveXObject("Microsoft.XMLHTTP");
+ } catch(activeError) {}
+ };
+}
+
+// Does this browser support XHR requests?
+jQuery.support.ajax = !!jQuery.ajaxSettings.xhr();
+
+
+
+
+var elemdisplay = {},
+ rfxtypes = /^(?:toggle|show|hide)$/,
+ rfxnum = /^([+\-]=)?([\d+.\-]+)(.*)$/,
+ timerId,
+ fxAttrs = [
+ // height animations
+ [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],
+ // width animations
+ [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
+ // opacity animations
+ [ "opacity" ]
+ ];
+
+jQuery.fn.extend({
+ show: function( speed, easing, callback ) {
+ var elem, display;
+
+ if ( speed || speed === 0 ) {
+ return this.animate( genFx("show", 3), speed, easing, callback);
+
+ } else {
+ for ( var i = 0, j = this.length; i < j; i++ ) {
+ elem = this[i];
+ display = elem.style.display;
+
+ // Reset the inline display of this element to learn if it is
+ // being hidden by cascaded rules or not
+ if ( !jQuery.data(elem, "olddisplay") && display === "none" ) {
+ display = elem.style.display = "";
+ }
+
+ // Set elements which have been overridden with display: none
+ // in a stylesheet to whatever the default browser style is
+ // for such an element
+ if ( display === "" && jQuery.css( elem, "display" ) === "none" ) {
+ jQuery.data(elem, "olddisplay", defaultDisplay(elem.nodeName));
+ }
+ }
+
+ // Set the display of most of the elements in a second loop
+ // to avoid the constant reflow
+ for ( i = 0; i < j; i++ ) {
+ elem = this[i];
+ display = elem.style.display;
+
+ if ( display === "" || display === "none" ) {
+ elem.style.display = jQuery.data(elem, "olddisplay") || "";
+ }
+ }
+
+ return this;
+ }
+ },
+
+ hide: function( speed, easing, callback ) {
+ if ( speed || speed === 0 ) {
+ return this.animate( genFx("hide", 3), speed, easing, callback);
+
+ } else {
+ for ( var i = 0, j = this.length; i < j; i++ ) {
+ var display = jQuery.css( this[i], "display" );
+
+ if ( display !== "none" ) {
+ jQuery.data( this[i], "olddisplay", display );
+ }
+ }
+
+ // Set the display of the elements in a second loop
+ // to avoid the constant reflow
+ for ( i = 0; i < j; i++ ) {
+ this[i].style.display = "none";
+ }
+
+ return this;
+ }
+ },
+
+ // Save the old toggle function
+ _toggle: jQuery.fn.toggle,
+
+ toggle: function( fn, fn2, callback ) {
+ var bool = typeof fn === "boolean";
+
+ if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {
+ this._toggle.apply( this, arguments );
+
+ } else if ( fn == null || bool ) {
+ this.each(function() {
+ var state = bool ? fn : jQuery(this).is(":hidden");
+ jQuery(this)[ state ? "show" : "hide" ]();
+ });
+
+ } else {
+ this.animate(genFx("toggle", 3), fn, fn2, callback);
+ }
+
+ return this;
+ },
+
+ fadeTo: function( speed, to, easing, callback ) {
+ return this.filter(":hidden").css("opacity", 0).show().end()
+ .animate({opacity: to}, speed, easing, callback);
+ },
+
+ animate: function( prop, speed, easing, callback ) {
+ var optall = jQuery.speed(speed, easing, callback);
+
+ if ( jQuery.isEmptyObject( prop ) ) {
+ return this.each( optall.complete );
+ }
+
+ return this[ optall.queue === false ? "each" : "queue" ](function() {
+ // XXX 'this' does not always have a nodeName when running the
+ // test suite
+
+ var opt = jQuery.extend({}, optall), p,
+ isElement = this.nodeType === 1,
+ hidden = isElement && jQuery(this).is(":hidden"),
+ self = this;
+
+ for ( p in prop ) {
+ var name = jQuery.camelCase( p );
+
+ if ( p !== name ) {
+ prop[ name ] = prop[ p ];
+ delete prop[ p ];
+ p = name;
+ }
+
+ if ( prop[p] === "hide" && hidden || prop[p] === "show" && !hidden ) {
+ return opt.complete.call(this);
+ }
+
+ if ( isElement && ( p === "height" || p === "width" ) ) {
+ // Make sure that nothing sneaks out
+ // Record all 3 overflow attributes because IE does not
+ // change the overflow attribute when overflowX and
+ // overflowY are set to the same value
+ opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ];
+
+ // Set display property to inline-block for height/width
+ // animations on inline elements that are having width/height
+ // animated
+ if ( jQuery.css( this, "display" ) === "inline" &&
+ jQuery.css( this, "float" ) === "none" ) {
+ if ( !jQuery.support.inlineBlockNeedsLayout ) {
+ this.style.display = "inline-block";
+
+ } else {
+ var display = defaultDisplay(this.nodeName);
+
+ // inline-level elements accept inline-block;
+ // block-level elements need to be inline with layout
+ if ( display === "inline" ) {
+ this.style.display = "inline-block";
+
+ } else {
+ this.style.display = "inline";
+ this.style.zoom = 1;
+ }
+ }
+ }
+ }
+
+ if ( jQuery.isArray( prop[p] ) ) {
+ // Create (if needed) and add to specialEasing
+ (opt.specialEasing = opt.specialEasing || {})[p] = prop[p][1];
+ prop[p] = prop[p][0];
+ }
+ }
+
+ if ( opt.overflow != null ) {
+ this.style.overflow = "hidden";
+ }
+
+ opt.curAnim = jQuery.extend({}, prop);
+
+ jQuery.each( prop, function( name, val ) {
+ var e = new jQuery.fx( self, opt, name );
+
+ if ( rfxtypes.test(val) ) {
+ e[ val === "toggle" ? hidden ? "show" : "hide" : val ]( prop );
+
+ } else {
+ var parts = rfxnum.exec(val),
+ start = e.cur() || 0;
+
+ if ( parts ) {
+ var end = parseFloat( parts[2] ),
+ unit = parts[3] || "px";
+
+ // We need to compute starting value
+ if ( unit !== "px" ) {
+ jQuery.style( self, name, (end || 1) + unit);
+ start = ((end || 1) / e.cur()) * start;
+ jQuery.style( self, name, start + unit);
+ }
+
+ // If a +=/-= token was provided, we're doing a relative animation
+ if ( parts[1] ) {
+ end = ((parts[1] === "-=" ? -1 : 1) * end) + start;
+ }
+
+ e.custom( start, end, unit );
+
+ } else {
+ e.custom( start, val, "" );
+ }
+ }
+ });
+
+ // For JS strict compliance
+ return true;
+ });
+ },
+
+ stop: function( clearQueue, gotoEnd ) {
+ var timers = jQuery.timers;
+
+ if ( clearQueue ) {
+ this.queue([]);
+ }
+
+ this.each(function() {
+ // go in reverse order so anything added to the queue during the loop is ignored
+ for ( var i = timers.length - 1; i >= 0; i-- ) {
+ if ( timers[i].elem === this ) {
+ if (gotoEnd) {
+ // force the next step to be the last
+ timers[i](true);
+ }
+
+ timers.splice(i, 1);
+ }
+ }
+ });
+
+ // start the next in the queue if the last step wasn't forced
+ if ( !gotoEnd ) {
+ this.dequeue();
+ }
+
+ return this;
+ }
+
+});
+
+function genFx( type, num ) {
+ var obj = {};
+
+ jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {
+ obj[ this ] = type;
+ });
+
+ return obj;
+}
+
+// Generate shortcuts for custom animations
+jQuery.each({
+ slideDown: genFx("show", 1),
+ slideUp: genFx("hide", 1),
+ slideToggle: genFx("toggle", 1),
+ fadeIn: { opacity: "show" },
+ fadeOut: { opacity: "hide" },
+ fadeToggle: { opacity: "toggle" }
+}, function( name, props ) {
+ jQuery.fn[ name ] = function( speed, easing, callback ) {
+ return this.animate( props, speed, easing, callback );
+ };
+});
+
+jQuery.extend({
+ speed: function( speed, easing, fn ) {
+ var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : {
+ complete: fn || !fn && easing ||
+ jQuery.isFunction( speed ) && speed,
+ duration: speed,
+ easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
+ };
+
+ opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
+ opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default;
+
+ // Queueing
+ opt.old = opt.complete;
+ opt.complete = function() {
+ if ( opt.queue !== false ) {
+ jQuery(this).dequeue();
+ }
+ if ( jQuery.isFunction( opt.old ) ) {
+ opt.old.call( this );
+ }
+ };
+
+ return opt;
+ },
+
+ easing: {
+ linear: function( p, n, firstNum, diff ) {
+ return firstNum + diff * p;
+ },
+ swing: function( p, n, firstNum, diff ) {
+ return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
+ }
+ },
+
+ timers: [],
+
+ fx: function( elem, options, prop ) {
+ this.options = options;
+ this.elem = elem;
+ this.prop = prop;
+
+ if ( !options.orig ) {
+ options.orig = {};
+ }
+ }
+
+});
+
+jQuery.fx.prototype = {
+ // Simple function for setting a style value
+ update: function() {
+ if ( this.options.step ) {
+ this.options.step.call( this.elem, this.now, this );
+ }
+
+ (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );
+ },
+
+ // Get the current size
+ cur: function() {
+ if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {
+ return this.elem[ this.prop ];
+ }
+
+ var r = parseFloat( jQuery.css( this.elem, this.prop ) );
+ return r && r > -10000 ? r : 0;
+ },
+
+ // Start an animation from one number to another
+ custom: function( from, to, unit ) {
+ var self = this,
+ fx = jQuery.fx;
+
+ this.startTime = jQuery.now();
+ this.start = from;
+ this.end = to;
+ this.unit = unit || this.unit || "px";
+ this.now = this.start;
+ this.pos = this.state = 0;
+
+ function t( gotoEnd ) {
+ return self.step(gotoEnd);
+ }
+
+ t.elem = this.elem;
+
+ if ( t() && jQuery.timers.push(t) && !timerId ) {
+ timerId = setInterval(fx.tick, fx.interval);
+ }
+ },
+
+ // Simple 'show' function
+ show: function() {
+ // Remember where we started, so that we can go back to it later
+ this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
+ this.options.show = true;
+
+ // Begin the animation
+ // Make sure that we start at a small width/height to avoid any
+ // flash of content
+ this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur());
+
+ // Start by showing the element
+ jQuery( this.elem ).show();
+ },
+
+ // Simple 'hide' function
+ hide: function() {
+ // Remember where we started, so that we can go back to it later
+ this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );
+ this.options.hide = true;
+
+ // Begin the animation
+ this.custom(this.cur(), 0);
+ },
+
+ // Each step of an animation
+ step: function( gotoEnd ) {
+ var t = jQuery.now(), done = true;
+
+ if ( gotoEnd || t >= this.options.duration + this.startTime ) {
+ this.now = this.end;
+ this.pos = this.state = 1;
+ this.update();
+
+ this.options.curAnim[ this.prop ] = true;
+
+ for ( var i in this.options.curAnim ) {
+ if ( this.options.curAnim[i] !== true ) {
+ done = false;
+ }
+ }
+
+ if ( done ) {
+ // Reset the overflow
+ if ( this.options.overflow != null && !jQuery.support.shrinkWrapBlocks ) {
+ var elem = this.elem,
+ options = this.options;
+
+ jQuery.each( [ "", "X", "Y" ], function (index, value) {
+ elem.style[ "overflow" + value ] = options.overflow[index];
+ } );
+ }
+
+ // Hide the element if the "hide" operation was done
+ if ( this.options.hide ) {
+ jQuery(this.elem).hide();
+ }
+
+ // Reset the properties, if the item has been hidden or shown
+ if ( this.options.hide || this.options.show ) {
+ for ( var p in this.options.curAnim ) {
+ jQuery.style( this.elem, p, this.options.orig[p] );
+ }
+ }
+
+ // Execute the complete function
+ this.options.complete.call( this.elem );
+ }
+
+ return false;
+
+ } else {
+ var n = t - this.startTime;
+ this.state = n / this.options.duration;
+
+ // Perform the easing function, defaults to swing
+ var specialEasing = this.options.specialEasing && this.options.specialEasing[this.prop];
+ var defaultEasing = this.options.easing || (jQuery.easing.swing ? "swing" : "linear");
+ this.pos = jQuery.easing[specialEasing || defaultEasing](this.state, n, 0, 1, this.options.duration);
+ this.now = this.start + ((this.end - this.start) * this.pos);
+
+ // Perform the next step of the animation
+ this.update();
+ }
+
+ return true;
+ }
+};
+
+jQuery.extend( jQuery.fx, {
+ tick: function() {
+ var timers = jQuery.timers;
+
+ for ( var i = 0; i < timers.length; i++ ) {
+ if ( !timers[i]() ) {
+ timers.splice(i--, 1);
+ }
+ }
+
+ if ( !timers.length ) {
+ jQuery.fx.stop();
+ }
+ },
+
+ interval: 13,
+
+ stop: function() {
+ clearInterval( timerId );
+ timerId = null;
+ },
+
+ speeds: {
+ slow: 600,
+ fast: 200,
+ // Default speed
+ _default: 400
+ },
+
+ step: {
+ opacity: function( fx ) {
+ jQuery.style( fx.elem, "opacity", fx.now );
+ },
+
+ _default: function( fx ) {
+ if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {
+ fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit;
+ } else {
+ fx.elem[ fx.prop ] = fx.now;
+ }
+ }
+ }
+});
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+ jQuery.expr.filters.animated = function( elem ) {
+ return jQuery.grep(jQuery.timers, function( fn ) {
+ return elem === fn.elem;
+ }).length;
+ };
+}
+
+function defaultDisplay( nodeName ) {
+ if ( !elemdisplay[ nodeName ] ) {
+ var elem = jQuery("<" + nodeName + ">").appendTo("body"),
+ display = elem.css("display");
+
+ elem.remove();
+
+ if ( display === "none" || display === "" ) {
+ display = "block";
+ }
+
+ elemdisplay[ nodeName ] = display;
+ }
+
+ return elemdisplay[ nodeName ];
+}
+
+
+
+
+var rtable = /^t(?:able|d|h)$/i,
+ rroot = /^(?:body|html)$/i;
+
+if ( "getBoundingClientRect" in document.documentElement ) {
+ jQuery.fn.offset = function( options ) {
+ var elem = this[0], box;
+
+ if ( options ) {
+ return this.each(function( i ) {
+ jQuery.offset.setOffset( this, options, i );
+ });
+ }
+
+ if ( !elem || !elem.ownerDocument ) {
+ return null;
+ }
+
+ if ( elem === elem.ownerDocument.body ) {
+ return jQuery.offset.bodyOffset( elem );
+ }
+
+ try {
+ box = elem.getBoundingClientRect();
+ } catch(e) {}
+
+ var doc = elem.ownerDocument,
+ docElem = doc.documentElement;
+
+ // Make sure we're not dealing with a disconnected DOM node
+ if ( !box || !jQuery.contains( docElem, elem ) ) {
+ return box || { top: 0, left: 0 };
+ }
+
+ var body = doc.body,
+ win = getWindow(doc),
+ clientTop = docElem.clientTop || body.clientTop || 0,
+ clientLeft = docElem.clientLeft || body.clientLeft || 0,
+ scrollTop = (win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop ),
+ scrollLeft = (win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft),
+ top = box.top + scrollTop - clientTop,
+ left = box.left + scrollLeft - clientLeft;
+
+ return { top: top, left: left };
+ };
+
+} else {
+ jQuery.fn.offset = function( options ) {
+ var elem = this[0];
+
+ if ( options ) {
+ return this.each(function( i ) {
+ jQuery.offset.setOffset( this, options, i );
+ });
+ }
+
+ if ( !elem || !elem.ownerDocument ) {
+ return null;
+ }
+
+ if ( elem === elem.ownerDocument.body ) {
+ return jQuery.offset.bodyOffset( elem );
+ }
+
+ jQuery.offset.initialize();
+
+ var computedStyle,
+ offsetParent = elem.offsetParent,
+ prevOffsetParent = elem,
+ doc = elem.ownerDocument,
+ docElem = doc.documentElement,
+ body = doc.body,
+ defaultView = doc.defaultView,
+ prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,
+ top = elem.offsetTop,
+ left = elem.offsetLeft;
+
+ while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {
+ if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
+ break;
+ }
+
+ computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;
+ top -= elem.scrollTop;
+ left -= elem.scrollLeft;
+
+ if ( elem === offsetParent ) {
+ top += elem.offsetTop;
+ left += elem.offsetLeft;
+
+ if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) {
+ top += parseFloat( computedStyle.borderTopWidth ) || 0;
+ left += parseFloat( computedStyle.borderLeftWidth ) || 0;
+ }
+
+ prevOffsetParent = offsetParent;
+ offsetParent = elem.offsetParent;
+ }
+
+ if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {
+ top += parseFloat( computedStyle.borderTopWidth ) || 0;
+ left += parseFloat( computedStyle.borderLeftWidth ) || 0;
+ }
+
+ prevComputedStyle = computedStyle;
+ }
+
+ if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {
+ top += body.offsetTop;
+ left += body.offsetLeft;
+ }
+
+ if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {
+ top += Math.max( docElem.scrollTop, body.scrollTop );
+ left += Math.max( docElem.scrollLeft, body.scrollLeft );
+ }
+
+ return { top: top, left: left };
+ };
+}
+
+jQuery.offset = {
+ initialize: function() {
+ var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.css(body, "marginTop") ) || 0,
+ html = "<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";
+
+ jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );
+
+ container.innerHTML = html;
+ body.insertBefore( container, body.firstChild );
+ innerDiv = container.firstChild;
+ checkDiv = innerDiv.firstChild;
+ td = innerDiv.nextSibling.firstChild.firstChild;
+
+ this.doesNotAddBorder = (checkDiv.offsetTop !== 5);
+ this.doesAddBorderForTableAndCells = (td.offsetTop === 5);
+
+ checkDiv.style.position = "fixed";
+ checkDiv.style.top = "20px";
+
+ // safari subtracts parent border width here which is 5px
+ this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);
+ checkDiv.style.position = checkDiv.style.top = "";
+
+ innerDiv.style.overflow = "hidden";
+ innerDiv.style.position = "relative";
+
+ this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);
+
+ this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);
+
+ body.removeChild( container );
+ body = container = innerDiv = checkDiv = table = td = null;
+ jQuery.offset.initialize = jQuery.noop;
+ },
+
+ bodyOffset: function( body ) {
+ var top = body.offsetTop,
+ left = body.offsetLeft;
+
+ jQuery.offset.initialize();
+
+ if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {
+ top += parseFloat( jQuery.css(body, "marginTop") ) || 0;
+ left += parseFloat( jQuery.css(body, "marginLeft") ) || 0;
+ }
+
+ return { top: top, left: left };
+ },
+
+ setOffset: function( elem, options, i ) {
+ var position = jQuery.css( elem, "position" );
+
+ // set position first, in-case top/left are set even on static elem
+ if ( position === "static" ) {
+ elem.style.position = "relative";
+ }
+
+ var curElem = jQuery( elem ),
+ curOffset = curElem.offset(),
+ curCSSTop = jQuery.css( elem, "top" ),
+ curCSSLeft = jQuery.css( elem, "left" ),
+ calculatePosition = (position === "absolute" && jQuery.inArray('auto', [curCSSTop, curCSSLeft]) > -1),
+ props = {}, curPosition = {}, curTop, curLeft;
+
+ // need to be able to calculate position if either top or left is auto and position is absolute
+ if ( calculatePosition ) {
+ curPosition = curElem.position();
+ }
+
+ curTop = calculatePosition ? curPosition.top : parseInt( curCSSTop, 10 ) || 0;
+ curLeft = calculatePosition ? curPosition.left : parseInt( curCSSLeft, 10 ) || 0;
+
+ if ( jQuery.isFunction( options ) ) {
+ options = options.call( elem, i, curOffset );
+ }
+
+ if (options.top != null) {
+ props.top = (options.top - curOffset.top) + curTop;
+ }
+ if (options.left != null) {
+ props.left = (options.left - curOffset.left) + curLeft;
+ }
+
+ if ( "using" in options ) {
+ options.using.call( elem, props );
+ } else {
+ curElem.css( props );
+ }
+ }
+};
+
+
+jQuery.fn.extend({
+ position: function() {
+ if ( !this[0] ) {
+ return null;
+ }
+
+ var elem = this[0],
+
+ // Get *real* offsetParent
+ offsetParent = this.offsetParent(),
+
+ // Get correct offsets
+ offset = this.offset(),
+ parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();
+
+ // Subtract element margins
+ // note: when an element has margin: auto the offsetLeft and marginLeft
+ // are the same in Safari causing offset.left to incorrectly be 0
+ offset.top -= parseFloat( jQuery.css(elem, "marginTop") ) || 0;
+ offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0;
+
+ // Add offsetParent borders
+ parentOffset.top += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0;
+ parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0;
+
+ // Subtract the two offsets
+ return {
+ top: offset.top - parentOffset.top,
+ left: offset.left - parentOffset.left
+ };
+ },
+
+ offsetParent: function() {
+ return this.map(function() {
+ var offsetParent = this.offsetParent || document.body;
+ while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {
+ offsetParent = offsetParent.offsetParent;
+ }
+ return offsetParent;
+ });
+ }
+});
+
+
+// Create scrollLeft and scrollTop methods
+jQuery.each( ["Left", "Top"], function( i, name ) {
+ var method = "scroll" + name;
+
+ jQuery.fn[ method ] = function(val) {
+ var elem = this[0], win;
+
+ if ( !elem ) {
+ return null;
+ }
+
+ if ( val !== undefined ) {
+ // Set the scroll offset
+ return this.each(function() {
+ win = getWindow( this );
+
+ if ( win ) {
+ win.scrollTo(
+ !i ? val : jQuery(win).scrollLeft(),
+ i ? val : jQuery(win).scrollTop()
+ );
+
+ } else {
+ this[ method ] = val;
+ }
+ });
+ } else {
+ win = getWindow( elem );
+
+ // Return the scroll offset
+ return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :
+ jQuery.support.boxModel && win.document.documentElement[ method ] ||
+ win.document.body[ method ] :
+ elem[ method ];
+ }
+ };
+});
+
+function getWindow( elem ) {
+ return jQuery.isWindow( elem ) ?
+ elem :
+ elem.nodeType === 9 ?
+ elem.defaultView || elem.parentWindow :
+ false;
+}
+
+
+
+
+// Create innerHeight, innerWidth, outerHeight and outerWidth methods
+jQuery.each([ "Height", "Width" ], function( i, name ) {
+
+ var type = name.toLowerCase();
+
+ // innerHeight and innerWidth
+ jQuery.fn["inner" + name] = function() {
+ return this[0] ?
+ parseFloat( jQuery.css( this[0], type, "padding" ) ) :
+ null;
+ };
+
+ // outerHeight and outerWidth
+ jQuery.fn["outer" + name] = function( margin ) {
+ return this[0] ?
+ parseFloat( jQuery.css( this[0], type, margin ? "margin" : "border" ) ) :
+ null;
+ };
+
+ jQuery.fn[ type ] = function( size ) {
+ // Get window width or height
+ var elem = this[0];
+ if ( !elem ) {
+ return size == null ? null : this;
+ }
+
+ if ( jQuery.isFunction( size ) ) {
+ return this.each(function( i ) {
+ var self = jQuery( this );
+ self[ type ]( size.call( this, i, self[ type ]() ) );
+ });
+ }
+
+ if ( jQuery.isWindow( elem ) ) {
+ // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
+ return elem.document.compatMode === "CSS1Compat" && elem.document.documentElement[ "client" + name ] ||
+ elem.document.body[ "client" + name ];
+
+ // Get document width or height
+ } else if ( elem.nodeType === 9 ) {
+ // Either scroll[Width/Height] or offset[Width/Height], whichever is greater
+ return Math.max(
+ elem.documentElement["client" + name],
+ elem.body["scroll" + name], elem.documentElement["scroll" + name],
+ elem.body["offset" + name], elem.documentElement["offset" + name]
+ );
+
+ // Get or set width or height on the element
+ } else if ( size === undefined ) {
+ var orig = jQuery.css( elem, type ),
+ ret = parseFloat( orig );
+
+ return jQuery.isNaN( ret ) ? orig : ret;
+
+ // Set the width or height on the element (default to pixels if value is unitless)
+ } else {
+ return this.css( type, typeof size === "string" ? size : size + "px" );
+ }
+ };
+
+});
+
+
+})(window);
diff --git a/railties/lib/rails/generators/rails/app/templates/public/javascripts/jquery_ujs.js b/railties/lib/rails/generators/rails/app/templates/public/javascripts/jquery_ujs.js
new file mode 100644
index 0000000000..43456a77f6
--- /dev/null
+++ b/railties/lib/rails/generators/rails/app/templates/public/javascripts/jquery_ujs.js
@@ -0,0 +1,132 @@
+jQuery(function ($) {
+ var csrf_token = $('meta[name=csrf-token]').attr('content'),
+ csrf_param = $('meta[name=csrf-param]').attr('content');
+
+ $.fn.extend({
+ /**
+ * Triggers a custom event on an element and returns the event result
+ * this is used to get around not being able to ensure callbacks are placed
+ * at the end of the chain.
+ *
+ * TODO: deprecate with jQuery 1.4.2 release, in favor of subscribing to our
+ * own events and placing ourselves at the end of the chain.
+ */
+ triggerAndReturn: function (name, data) {
+ var event = new $.Event(name);
+ this.trigger(event, data);
+
+ return event.result !== false;
+ },
+
+ /**
+ * Handles execution of remote calls firing overridable events along the way
+ */
+ callRemote: function () {
+ var el = this,
+ method = el.attr('method') || el.attr('data-method') || 'GET',
+ url = el.attr('action') || el.attr('href'),
+ dataType = el.attr('data-type') || 'script';
+
+ if (url === undefined) {
+ throw "No URL specified for remote call (action or href must be present).";
+ } else {
+ if (el.triggerAndReturn('ajax:before')) {
+ var data = el.is('form') ? el.serializeArray() : [];
+ $.ajax({
+ url: url,
+ data: data,
+ dataType: dataType,
+ type: method.toUpperCase(),
+ beforeSend: function (xhr) {
+ el.trigger('ajax:loading', xhr);
+ },
+ success: function (data, status, xhr) {
+ el.trigger('ajax:success', [data, status, xhr]);
+ },
+ complete: function (xhr) {
+ el.trigger('ajax:complete', xhr);
+ },
+ error: function (xhr, status, error) {
+ el.trigger('ajax:failure', [xhr, status, error]);
+ }
+ });
+ }
+
+ el.trigger('ajax:after');
+ }
+ }
+ });
+
+ /**
+ * confirmation handler
+ */
+ $('a[data-confirm],input[data-confirm]').live('click', function () {
+ var el = $(this);
+ if (el.triggerAndReturn('confirm')) {
+ if (!confirm(el.attr('data-confirm'))) {
+ return false;
+ }
+ }
+ });
+
+
+ /**
+ * remote handlers
+ */
+ $('form[data-remote]').live('submit', function (e) {
+ $(this).callRemote();
+ e.preventDefault();
+ });
+
+ $('a[data-remote],input[data-remote]').live('click', function (e) {
+ $(this).callRemote();
+ e.preventDefault();
+ });
+
+ $('a[data-method]:not([data-remote])').live('click', function (e){
+ var link = $(this),
+ href = link.attr('href'),
+ method = link.attr('data-method'),
+ form = $('<form method="post" action="'+href+'"></form>'),
+ metadata_input = '<input name="_method" value="'+method+'" type="hidden" />';
+
+ if (csrf_param != null && csrf_token != null) {
+ metadata_input += '<input name="'+csrf_param+'" value="'+csrf_token+'" type="hidden" />';
+ }
+
+ form.hide()
+ .append(metadata_input)
+ .appendTo('body');
+
+ e.preventDefault();
+ form.submit();
+ });
+
+ /**
+ * disable-with handlers
+ */
+ var disable_with_input_selector = 'input[data-disable-with]';
+ var disable_with_form_remote_selector = 'form[data-remote]:has(' + disable_with_input_selector + ')';
+ var disable_with_form_not_remote_selector = 'form:not([data-remote]):has(' + disable_with_input_selector + ')';
+
+ var disable_with_input_function = function () {
+ $(this).find(disable_with_input_selector).each(function () {
+ var input = $(this);
+ input.data('enable-with', input.val())
+ .attr('value', input.attr('data-disable-with'))
+ .attr('disabled', 'disabled');
+ });
+ };
+
+ $(disable_with_form_remote_selector).live('ajax:before', disable_with_input_function);
+ $(disable_with_form_not_remote_selector).live('submit', disable_with_input_function);
+
+ $(disable_with_form_remote_selector).live('ajax:complete', function () {
+ $(this).find(disable_with_input_selector).each(function () {
+ var input = $(this);
+ input.removeAttr('disabled')
+ .val(input.data('enable-with'));
+ });
+ });
+
+});
diff --git a/railties/lib/rails/generators/rails/app/templates/public/javascripts/prototype.js b/railties/lib/rails/generators/rails/app/templates/public/javascripts/prototype.js
index 06249a6ae3..474b2231bb 100644
--- a/railties/lib/rails/generators/rails/app/templates/public/javascripts/prototype.js
+++ b/railties/lib/rails/generators/rails/app/templates/public/javascripts/prototype.js
@@ -1,4 +1,4 @@
-/* Prototype JavaScript framework, version 1.7_rc2
+/* Prototype JavaScript framework, version 1.7
* (c) 2005-2010 Sam Stephenson
*
* Prototype is freely distributable under the terms of an MIT-style license.
@@ -8,7 +8,7 @@
var Prototype = {
- Version: '1.7_rc2',
+ Version: '1.7',
Browser: (function(){
var ua = navigator.userAgent;
@@ -166,10 +166,12 @@ var Class = (function() {
NUMBER_TYPE = 'Number',
STRING_TYPE = 'String',
OBJECT_TYPE = 'Object',
+ FUNCTION_CLASS = '[object Function]',
BOOLEAN_CLASS = '[object Boolean]',
NUMBER_CLASS = '[object Number]',
STRING_CLASS = '[object String]',
ARRAY_CLASS = '[object Array]',
+ DATE_CLASS = '[object Date]',
NATIVE_JSON_STRINGIFY_SUPPORT = window.JSON &&
typeof JSON.stringify === 'function' &&
JSON.stringify(0) === '0' &&
@@ -322,7 +324,7 @@ var Class = (function() {
}
function isFunction(object) {
- return typeof object === "function";
+ return _toString.call(object) === FUNCTION_CLASS;
}
function isString(object) {
@@ -333,6 +335,10 @@ var Class = (function() {
return _toString.call(object) === NUMBER_CLASS;
}
+ function isDate(object) {
+ return _toString.call(object) === DATE_CLASS;
+ }
+
function isUndefined(object) {
return typeof object === "undefined";
}
@@ -352,6 +358,7 @@ var Class = (function() {
isFunction: isFunction,
isString: isString,
isNumber: isNumber,
+ isDate: isDate,
isUndefined: isUndefined
});
})();
@@ -1079,9 +1086,10 @@ Array.from = $A;
slice = arrayProto.slice,
_each = arrayProto.forEach; // use native browser JS 1.6 implementation if available
- function each(iterator) {
- for (var i = 0, length = this.length; i < length; i++)
- iterator(this[i]);
+ function each(iterator, context) {
+ for (var i = 0, length = this.length >>> 0; i < length; i++) {
+ if (i in this) iterator.call(context, this[i], i, this);
+ }
}
if (!_each) _each = each;
@@ -1287,8 +1295,14 @@ var Hash = Class.create(Enumerable, (function() {
var key = encodeURIComponent(pair.key), values = pair.value;
if (values && typeof values == 'object') {
- if (Object.isArray(values))
- return results.concat(values.map(toQueryPair.curry(key)));
+ if (Object.isArray(values)) {
+ var queryValues = [];
+ for (var i = 0, len = values.length, value; i < len; i++) {
+ value = values[i];
+ queryValues.push(toQueryPair(key, value));
+ }
+ return results.concat(queryValues);
+ }
} else results.push(toQueryPair(key, values));
return results;
}).join('&');
@@ -1468,9 +1482,7 @@ Ajax.Base = Class.create({
this.options.method = this.options.method.toLowerCase();
- if (Object.isString(this.options.parameters))
- this.options.parameters = this.options.parameters.toQueryParams();
- else if (Object.isHash(this.options.parameters))
+ if (Object.isHash(this.options.parameters))
this.options.parameters = this.options.parameters.toObject();
}
});
@@ -1486,22 +1498,21 @@ Ajax.Request = Class.create(Ajax.Base, {
request: function(url) {
this.url = url;
this.method = this.options.method;
- var params = Object.clone(this.options.parameters);
+ var params = Object.isString(this.options.parameters) ?
+ this.options.parameters :
+ Object.toQueryString(this.options.parameters);
if (!['get', 'post'].include(this.method)) {
- params['_method'] = this.method;
+ params += (params ? '&' : '') + "_method=" + this.method;
this.method = 'post';
}
- this.parameters = params;
-
- if (params = Object.toQueryString(params)) {
- if (this.method == 'get')
- this.url += (this.url.include('?') ? '&' : '?') + params;
- else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent))
- params += '&_=';
+ if (params && this.method === 'get') {
+ this.url += (this.url.include('?') ? '&' : '?') + params;
}
+ this.parameters = params.toQueryParams();
+
try {
var response = new Ajax.Response(this);
if (this.options.onCreate) this.options.onCreate(response);
@@ -1570,11 +1581,12 @@ Ajax.Request = Class.create(Ajax.Base, {
success: function() {
var status = this.getStatus();
- return !status || (status >= 200 && status < 300);
+ return !status || (status >= 200 && status < 300) || status == 304;
},
getStatus: function() {
try {
+ if (this.transport.status === 1223) return 204;
return this.transport.status || 0;
} catch (e) { return 0 }
},
@@ -1849,6 +1861,11 @@ if (!Node.ELEMENT_NODE) {
(function(global) {
+ function shouldUseCache(tagName, attributes) {
+ if (tagName === 'select') return false;
+ if ('type' in attributes) return false;
+ return true;
+ }
var HAS_EXTENDED_CREATE_ELEMENT_SYNTAX = (function(){
try {
@@ -1866,13 +1883,19 @@ if (!Node.ELEMENT_NODE) {
attributes = attributes || { };
tagName = tagName.toLowerCase();
var cache = Element.cache;
+
if (HAS_EXTENDED_CREATE_ELEMENT_SYNTAX && attributes.name) {
tagName = '<' + tagName + ' name="' + attributes.name + '">';
delete attributes.name;
return Element.writeAttribute(document.createElement(tagName), attributes);
}
+
if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName));
- return Element.writeAttribute(cache[tagName].cloneNode(false), attributes);
+
+ var node = shouldUseCache(tagName, attributes) ?
+ cache[tagName].cloneNode(false) : document.createElement(tagName);
+
+ return Element.writeAttribute(node, attributes);
};
Object.extend(global.Element, element || { });
@@ -1883,7 +1906,7 @@ if (!Node.ELEMENT_NODE) {
Element.idCounter = 1;
Element.cache = { };
-function purgeElement(element) {
+Element._purgeElement = function(element) {
var uid = element._prototypeUID;
if (uid) {
Element.stopObserving(element);
@@ -1948,6 +1971,21 @@ Element.Methods = {
}
})();
+ var LINK_ELEMENT_INNERHTML_BUGGY = (function() {
+ try {
+ var el = document.createElement('div');
+ el.innerHTML = "<link>";
+ var isBuggy = (el.childNodes.length === 0);
+ el = null;
+ return isBuggy;
+ } catch(e) {
+ return true;
+ }
+ })();
+
+ var ANY_INNERHTML_BUGGY = SELECT_ELEMENT_INNERHTML_BUGGY ||
+ TABLE_ELEMENT_INNERHTML_BUGGY || LINK_ELEMENT_INNERHTML_BUGGY;
+
var SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING = (function () {
var s = document.createElement("script"),
isBuggy = false;
@@ -1962,8 +2000,10 @@ Element.Methods = {
return isBuggy;
})();
+
function update(element, content) {
element = $(element);
+ var purgeElement = Element._purgeElement;
var descendants = element.getElementsByTagName('*'),
i = descendants.length;
@@ -1984,7 +2024,7 @@ Element.Methods = {
return element;
}
- if (SELECT_ELEMENT_INNERHTML_BUGGY || TABLE_ELEMENT_INNERHTML_BUGGY) {
+ if (ANY_INNERHTML_BUGGY) {
if (tagName in Element._insertionTranslations.tags) {
while (element.firstChild) {
element.removeChild(element.firstChild);
@@ -1993,6 +2033,12 @@ Element.Methods = {
.each(function(node) {
element.appendChild(node)
});
+ } else if (LINK_ELEMENT_INNERHTML_BUGGY && Object.isString(content) && content.indexOf('<link') > -1) {
+ while (element.firstChild) {
+ element.removeChild(element.firstChild);
+ }
+ var nodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts(), true);
+ nodes.each(function(node) { element.appendChild(node) });
}
else {
element.innerHTML = content.stripScripts();
@@ -2402,117 +2448,6 @@ Element.Methods = {
return element;
},
- cumulativeOffset: function(element) {
- var valueT = 0, valueL = 0;
- if (element.parentNode) {
- do {
- valueT += element.offsetTop || 0;
- valueL += element.offsetLeft || 0;
- element = element.offsetParent;
- } while (element);
- }
- return Element._returnOffset(valueL, valueT);
- },
-
- positionedOffset: function(element) {
- var valueT = 0, valueL = 0;
- do {
- valueT += element.offsetTop || 0;
- valueL += element.offsetLeft || 0;
- element = element.offsetParent;
- if (element) {
- if (element.tagName.toUpperCase() == 'BODY') break;
- var p = Element.getStyle(element, 'position');
- if (p !== 'static') break;
- }
- } while (element);
- return Element._returnOffset(valueL, valueT);
- },
-
- absolutize: function(element) {
- element = $(element);
- if (Element.getStyle(element, 'position') == 'absolute') return element;
-
- var offsets = Element.positionedOffset(element),
- top = offsets[1],
- left = offsets[0],
- width = element.clientWidth,
- height = element.clientHeight;
-
- element._originalLeft = left - parseFloat(element.style.left || 0);
- element._originalTop = top - parseFloat(element.style.top || 0);
- element._originalWidth = element.style.width;
- element._originalHeight = element.style.height;
-
- element.style.position = 'absolute';
- element.style.top = top + 'px';
- element.style.left = left + 'px';
- element.style.width = width + 'px';
- element.style.height = height + 'px';
- return element;
- },
-
- relativize: function(element) {
- element = $(element);
- if (Element.getStyle(element, 'position') == 'relative') return element;
-
- element.style.position = 'relative';
- var top = parseFloat(element.style.top || 0) - (element._originalTop || 0),
- left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
-
- element.style.top = top + 'px';
- element.style.left = left + 'px';
- element.style.height = element._originalHeight;
- element.style.width = element._originalWidth;
- return element;
- },
-
- cumulativeScrollOffset: function(element) {
- var valueT = 0, valueL = 0;
- do {
- valueT += element.scrollTop || 0;
- valueL += element.scrollLeft || 0;
- element = element.parentNode;
- } while (element);
- return Element._returnOffset(valueL, valueT);
- },
-
- getOffsetParent: function(element) {
- if (element.offsetParent) return $(element.offsetParent);
- if (element == document.body) return $(element);
-
- while ((element = element.parentNode) && element != document.body)
- if (Element.getStyle(element, 'position') != 'static')
- return $(element);
-
- return $(document.body);
- },
-
- viewportOffset: function(forElement) {
- var valueT = 0,
- valueL = 0,
- element = forElement;
-
- do {
- valueT += element.offsetTop || 0;
- valueL += element.offsetLeft || 0;
-
- if (element.offsetParent == document.body &&
- Element.getStyle(element, 'position') == 'absolute') break;
-
- } while (element = element.offsetParent);
-
- element = forElement;
- do {
- if (!Prototype.Browser.Opera || (element.tagName && (element.tagName.toUpperCase() == 'BODY'))) {
- valueT -= element.scrollTop || 0;
- valueL -= element.scrollLeft || 0;
- }
- } while (element = element.parentNode);
-
- return Element._returnOffset(valueL, valueT);
- },
-
clonePosition: function(element, source) {
var options = Object.extend({
setLeft: true,
@@ -2566,8 +2501,6 @@ if (Prototype.Browser.Opera) {
Element.Methods.getStyle = Element.Methods.getStyle.wrap(
function(proceed, element, style) {
switch (style) {
- case 'left': case 'top': case 'right': case 'bottom':
- if (proceed(element, 'position') === 'static') return null;
case 'height': case 'width':
if (!Element.visible(element)) return null;
@@ -2603,37 +2536,6 @@ if (Prototype.Browser.Opera) {
}
else if (Prototype.Browser.IE) {
- Element.Methods.getOffsetParent = Element.Methods.getOffsetParent.wrap(
- function(proceed, element) {
- element = $(element);
- if (!element.parentNode) return $(document.body);
- var position = element.getStyle('position');
- if (position !== 'static') return proceed(element);
- element.setStyle({ position: 'relative' });
- var value = proceed(element);
- element.setStyle({ position: position });
- return value;
- }
- );
-
- $w('positionedOffset viewportOffset').each(function(method) {
- Element.Methods[method] = Element.Methods[method].wrap(
- function(proceed, element) {
- element = $(element);
- if (!element.parentNode) return Element._returnOffset(0, 0);
- var position = element.getStyle('position');
- if (position !== 'static') return proceed(element);
- var offsetParent = element.getOffsetParent();
- if (offsetParent && offsetParent.getStyle('position') === 'fixed')
- offsetParent.setStyle({ zoom: 1 });
- element.setStyle({ position: 'relative' });
- var value = proceed(element);
- element.setStyle({ position: position });
- return value;
- }
- );
- });
-
Element.Methods.getStyle = function(element, style) {
element = $(element);
style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize();
@@ -2862,20 +2764,6 @@ else if (Prototype.Browser.WebKit) {
return element;
};
-
- Element.Methods.cumulativeOffset = function(element) {
- var valueT = 0, valueL = 0;
- do {
- valueT += element.offsetTop || 0;
- valueL += element.offsetLeft || 0;
- if (element.offsetParent == document.body)
- if (Element.getStyle(element, 'position') == 'absolute') break;
-
- element = element.offsetParent;
- } while (element);
-
- return Element._returnOffset(valueL, valueT);
- };
}
if ('outerHTML' in document.documentElement) {
@@ -2914,11 +2802,20 @@ Element._returnOffset = function(l, t) {
return result;
};
-Element._getContentFromAnonymousElement = function(tagName, html) {
+Element._getContentFromAnonymousElement = function(tagName, html, force) {
var div = new Element('div'),
t = Element._insertionTranslations.tags[tagName];
- if (t) {
- div.innerHTML = t[0] + html + t[1];
+
+ var workaround = false;
+ if (t) workaround = true;
+ else if (force) {
+ workaround = true;
+ t = ['', '', 0];
+ }
+
+ if (workaround) {
+ div.innerHTML = '&nbsp;' + t[0] + html + t[1];
+ div.removeChild(div.firstChild);
for (var i = t[2]; i--; ) {
div = div.firstChild;
}
@@ -3077,7 +2974,8 @@ Element.addMethods = function(methods) {
"FORM": Object.clone(Form.Methods),
"INPUT": Object.clone(Form.Element.Methods),
"SELECT": Object.clone(Form.Element.Methods),
- "TEXTAREA": Object.clone(Form.Element.Methods)
+ "TEXTAREA": Object.clone(Form.Element.Methods),
+ "BUTTON": Object.clone(Form.Element.Methods)
});
}
@@ -3264,6 +3162,8 @@ Element.addMethods({
purge: function(element) {
if (!(element = $(element))) return;
+ var purgeElement = Element._purgeElement;
+
purgeElement(element);
var descendants = element.getElementsByTagName('*'),
@@ -3283,11 +3183,13 @@ Element.addMethods({
return (Number(match[1]) / 100);
}
- function getPixelValue(value, property) {
+ function getPixelValue(value, property, context) {
+ var element = null;
if (Object.isElement(value)) {
element = value;
value = element.getStyle(property);
}
+
if (value === null) {
return null;
}
@@ -3296,7 +3198,9 @@ Element.addMethods({
return window.parseFloat(value);
}
- if (/\d/.test(value) && element.runtimeStyle) {
+ var isPercentage = value.include('%'), isViewport = (context === document.viewport);
+
+ if (/\d/.test(value) && element && element.runtimeStyle && !(isPercentage && isViewport)) {
var style = element.style.left, rStyle = element.runtimeStyle.left;
element.runtimeStyle.left = element.currentStyle.left;
element.style.left = value || 0;
@@ -3307,18 +3211,33 @@ Element.addMethods({
return value;
}
- if (value.include('%')) {
+ if (element && isPercentage) {
+ context = context || element.parentNode;
var decimal = toDecimal(value);
- var whole;
- if (property.include('left') || property.include('right') ||
- property.include('width')) {
- whole = $(element.parentNode).measure('width');
- } else if (property.include('top') || property.include('bottom') ||
- property.include('height')) {
- whole = $(element.parentNode).measure('height');
+ var whole = null;
+ var position = element.getStyle('position');
+
+ var isHorizontal = property.include('left') || property.include('right') ||
+ property.include('width');
+
+ var isVertical = property.include('top') || property.include('bottom') ||
+ property.include('height');
+
+ if (context === document.viewport) {
+ if (isHorizontal) {
+ whole = document.viewport.getWidth();
+ } else if (isVertical) {
+ whole = document.viewport.getHeight();
+ }
+ } else {
+ if (isHorizontal) {
+ whole = $(context).measure('width');
+ } else if (isVertical) {
+ whole = $(context).measure('height');
+ }
}
- return whole * decimal;
+ return (whole === null) ? 0 : whole * decimal;
}
return 0;
@@ -3410,6 +3329,14 @@ Element.addMethods({
var position = element.getStyle('position'),
width = element.getStyle('width');
+ if (width === "0px" || width === null) {
+ element.style.display = 'block';
+ width = element.getStyle('width');
+ }
+
+ var context = (position === 'fixed') ? document.viewport :
+ element.parentNode;
+
element.setStyle({
position: 'absolute',
visibility: 'hidden',
@@ -3420,9 +3347,9 @@ Element.addMethods({
var newWidth;
if (width && (positionedWidth === width)) {
- newWidth = getPixelValue(width);
- } else if (width && (position === 'absolute' || position === 'fixed')) {
- newWidth = getPixelValue(width);
+ newWidth = getPixelValue(element, 'width', context);
+ } else if (position === 'absolute' || position === 'fixed') {
+ newWidth = getPixelValue(element, 'width', context);
} else {
var parent = element.parentNode, pLayout = $(parent).getLayout();
@@ -3453,6 +3380,7 @@ Element.addMethods({
if (!(property in COMPUTATIONS)) {
throw "Property not found.";
}
+
return this._set(property, COMPUTATIONS[property].call(this, this.element));
},
@@ -3505,7 +3433,10 @@ Element.addMethods({
if (!this._preComputing) this._begin();
var bHeight = this.get('border-box-height');
- if (bHeight <= 0) return 0;
+ if (bHeight <= 0) {
+ if (!this._preComputing) this._end();
+ return 0;
+ }
var bTop = this.get('border-top'),
bBottom = this.get('border-bottom');
@@ -3522,7 +3453,10 @@ Element.addMethods({
if (!this._preComputing) this._begin();
var bWidth = this.get('border-box-width');
- if (bWidth <= 0) return 0;
+ if (bWidth <= 0) {
+ if (!this._preComputing) this._end();
+ return 0;
+ }
var bLeft = this.get('border-left'),
bRight = this.get('border-right');
@@ -3552,11 +3486,17 @@ Element.addMethods({
},
'border-box-height': function(element) {
- return element.offsetHeight;
+ if (!this._preComputing) this._begin();
+ var height = element.offsetHeight;
+ if (!this._preComputing) this._end();
+ return height;
},
'border-box-width': function(element) {
- return element.offsetWidth;
+ if (!this._preComputing) this._begin();
+ var width = element.offsetWidth;
+ if (!this._preComputing) this._end();
+ return width;
},
'margin-box-height': function(element) {
@@ -3626,23 +3566,19 @@ Element.addMethods({
},
'border-top': function(element) {
- return Object.isNumber(element.clientTop) ? element.clientTop :
- getPixelValue(element, 'borderTopWidth');
+ return getPixelValue(element, 'borderTopWidth');
},
'border-bottom': function(element) {
- return Object.isNumber(element.clientBottom) ? element.clientBottom :
- getPixelValue(element, 'borderBottomWidth');
+ return getPixelValue(element, 'borderBottomWidth');
},
'border-left': function(element) {
- return Object.isNumber(element.clientLeft) ? element.clientLeft :
- getPixelValue(element, 'borderLeftWidth');
+ return getPixelValue(element, 'borderLeftWidth');
},
'border-right': function(element) {
- return Object.isNumber(element.clientRight) ? element.clientRight :
- getPixelValue(element, 'borderRightWidth');
+ return getPixelValue(element, 'borderRightWidth');
},
'margin-top': function(element) {
@@ -3721,23 +3657,52 @@ Element.addMethods({
}
function getDimensions(element) {
- var layout = $(element).getLayout();
- return {
- width: layout.get('width'),
- height: layout.get('height')
+ element = $(element);
+ var display = Element.getStyle(element, 'display');
+
+ if (display && display !== 'none') {
+ return { width: element.offsetWidth, height: element.offsetHeight };
+ }
+
+ var style = element.style;
+ var originalStyles = {
+ visibility: style.visibility,
+ position: style.position,
+ display: style.display
+ };
+
+ var newStyles = {
+ visibility: 'hidden',
+ display: 'block'
};
+
+ if (originalStyles.position !== 'fixed')
+ newStyles.position = 'absolute';
+
+ Element.setStyle(element, newStyles);
+
+ var dimensions = {
+ width: element.offsetWidth,
+ height: element.offsetHeight
+ };
+
+ Element.setStyle(element, originalStyles);
+
+ return dimensions;
}
function getOffsetParent(element) {
- if (isDetached(element)) return $(document.body);
+ element = $(element);
+
+ if (isDocument(element) || isDetached(element) || isBody(element) || isHtml(element))
+ return $(document.body);
var isInline = (Element.getStyle(element, 'display') === 'inline');
if (!isInline && element.offsetParent) return $(element.offsetParent);
- if (element === document.body) return $(element);
while ((element = element.parentNode) && element !== document.body) {
if (Element.getStyle(element, 'position') !== 'static') {
- return (element.nodeName === 'HTML') ? $(document.body) : $(element);
+ return isHtml(element) ? $(document.body) : $(element);
}
}
@@ -3746,16 +3711,21 @@ Element.addMethods({
function cumulativeOffset(element) {
+ element = $(element);
var valueT = 0, valueL = 0;
- do {
- valueT += element.offsetTop || 0;
- valueL += element.offsetLeft || 0;
- element = element.offsetParent;
- } while (element);
+ if (element.parentNode) {
+ do {
+ valueT += element.offsetTop || 0;
+ valueL += element.offsetLeft || 0;
+ element = element.offsetParent;
+ } while (element);
+ }
return new Element.Offset(valueL, valueT);
}
function positionedOffset(element) {
+ element = $(element);
+
var layout = element.getLayout();
var valueT = 0, valueL = 0;
@@ -3787,6 +3757,7 @@ Element.addMethods({
}
function viewportOffset(forElement) {
+ element = $(element);
var valueT = 0, valueL = 0, docBody = document.body;
var element = forElement;
@@ -3852,6 +3823,57 @@ Element.addMethods({
return element;
}
+ if (Prototype.Browser.IE) {
+ getOffsetParent = getOffsetParent.wrap(
+ function(proceed, element) {
+ element = $(element);
+
+ if (isDocument(element) || isDetached(element) || isBody(element) || isHtml(element))
+ return $(document.body);
+
+ var position = element.getStyle('position');
+ if (position !== 'static') return proceed(element);
+
+ element.setStyle({ position: 'relative' });
+ var value = proceed(element);
+ element.setStyle({ position: position });
+ return value;
+ }
+ );
+
+ positionedOffset = positionedOffset.wrap(function(proceed, element) {
+ element = $(element);
+ if (!element.parentNode) return new Element.Offset(0, 0);
+ var position = element.getStyle('position');
+ if (position !== 'static') return proceed(element);
+
+ var offsetParent = element.getOffsetParent();
+ if (offsetParent && offsetParent.getStyle('position') === 'fixed')
+ hasLayout(offsetParent);
+
+ element.setStyle({ position: 'relative' });
+ var value = proceed(element);
+ element.setStyle({ position: position });
+ return value;
+ });
+ } else if (Prototype.Browser.Webkit) {
+ cumulativeOffset = function(element) {
+ element = $(element);
+ var valueT = 0, valueL = 0;
+ do {
+ valueT += element.offsetTop || 0;
+ valueL += element.offsetLeft || 0;
+ if (element.offsetParent == document.body)
+ if (Element.getStyle(element, 'position') == 'absolute') break;
+
+ element = element.offsetParent;
+ } while (element);
+
+ return new Element.Offset(valueL, valueT);
+ };
+ }
+
+
Element.addMethods({
getLayout: getLayout,
measure: measure,
@@ -3869,6 +3891,14 @@ Element.addMethods({
return element.nodeName.toUpperCase() === 'BODY';
}
+ function isHtml(element) {
+ return element.nodeName.toUpperCase() === 'HTML';
+ }
+
+ function isDocument(element) {
+ return element.nodeType === Node.DOCUMENT_NODE;
+ }
+
function isDetached(element) {
return element !== document.body &&
!Element.descendantOf(element, document.body);
@@ -3880,32 +3910,10 @@ Element.addMethods({
element = $(element);
if (isDetached(element)) return new Element.Offset(0, 0);
- var rect = element.getBoundingClientRect(),
+ var rect = element.getBoundingClientRect(),
docEl = document.documentElement;
return new Element.Offset(rect.left - docEl.clientLeft,
rect.top - docEl.clientTop);
- },
-
- positionedOffset: function(element) {
- element = $(element);
- var parent = element.getOffsetParent();
- if (isDetached(element)) return new Element.Offset(0, 0);
-
- if (element.offsetParent &&
- element.offsetParent.nodeName.toUpperCase() === 'HTML') {
- return positionedOffset(element);
- }
-
- var eOffset = element.viewportOffset(),
- pOffset = isBody(parent) ? viewportOffset(parent) :
- parent.viewportOffset();
- var retOffset = eOffset.relativeTo(pOffset);
-
- var layout = element.getLayout();
- var top = retOffset.top - layout.get('margin-top');
- var left = retOffset.left - layout.get('margin-left');
-
- return new Element.Offset(left, top);
}
});
}
@@ -4962,24 +4970,34 @@ var Form = {
serializeElements: function(elements, options) {
if (typeof options != 'object') options = { hash: !!options };
else if (Object.isUndefined(options.hash)) options.hash = true;
- var key, value, submitted = false, submit = options.submit;
+ var key, value, submitted = false, submit = options.submit, accumulator, initial;
+
+ if (options.hash) {
+ initial = {};
+ accumulator = function(result, key, value) {
+ if (key in result) {
+ if (!Object.isArray(result[key])) result[key] = [result[key]];
+ result[key].push(value);
+ } else result[key] = value;
+ return result;
+ };
+ } else {
+ initial = '';
+ accumulator = function(result, key, value) {
+ return result + (result ? '&' : '') + encodeURIComponent(key) + '=' + encodeURIComponent(value);
+ }
+ }
- var data = elements.inject({ }, function(result, element) {
+ return elements.inject(initial, function(result, element) {
if (!element.disabled && element.name) {
key = element.name; value = $(element).getValue();
if (value != null && element.type != 'file' && (element.type != 'submit' || (!submitted &&
submit !== false && (!submit || key == submit) && (submitted = true)))) {
- if (key in result) {
- if (!Object.isArray(result[key])) result[key] = [result[key]];
- result[key].push(value);
- }
- else result[key] = value;
+ result = accumulator(result, key, value);
}
}
return result;
});
-
- return options.hash ? data : Object.toQueryString(data);
}
};
@@ -5046,7 +5064,8 @@ Form.Methods = {
focusFirstElement: function(form) {
form = $(form);
- form.findFirstElement().activate();
+ var element = form.findFirstElement();
+ if (element) element.activate();
return form;
},
@@ -5153,67 +5172,77 @@ var $F = Form.Element.Methods.getValue;
/*--------------------------------------------------------------------------*/
-Form.Element.Serializers = {
- input: function(element, value) {
+Form.Element.Serializers = (function() {
+ function input(element, value) {
switch (element.type.toLowerCase()) {
case 'checkbox':
case 'radio':
- return Form.Element.Serializers.inputSelector(element, value);
+ return inputSelector(element, value);
default:
- return Form.Element.Serializers.textarea(element, value);
+ return valueSelector(element, value);
}
- },
+ }
- inputSelector: function(element, value) {
- if (Object.isUndefined(value)) return element.checked ? element.value : null;
+ function inputSelector(element, value) {
+ if (Object.isUndefined(value))
+ return element.checked ? element.value : null;
else element.checked = !!value;
- },
+ }
- textarea: function(element, value) {
+ function valueSelector(element, value) {
if (Object.isUndefined(value)) return element.value;
else element.value = value;
- },
+ }
- select: function(element, value) {
+ function select(element, value) {
if (Object.isUndefined(value))
- return this[element.type == 'select-one' ?
- 'selectOne' : 'selectMany'](element);
- else {
- var opt, currentValue, single = !Object.isArray(value);
- for (var i = 0, length = element.length; i < length; i++) {
- opt = element.options[i];
- currentValue = this.optionValue(opt);
- if (single) {
- if (currentValue == value) {
- opt.selected = true;
- return;
- }
+ return (element.type === 'select-one' ? selectOne : selectMany)(element);
+
+ var opt, currentValue, single = !Object.isArray(value);
+ for (var i = 0, length = element.length; i < length; i++) {
+ opt = element.options[i];
+ currentValue = this.optionValue(opt);
+ if (single) {
+ if (currentValue == value) {
+ opt.selected = true;
+ return;
}
- else opt.selected = value.include(currentValue);
}
+ else opt.selected = value.include(currentValue);
}
- },
+ }
- selectOne: function(element) {
+ function selectOne(element) {
var index = element.selectedIndex;
- return index >= 0 ? this.optionValue(element.options[index]) : null;
- },
+ return index >= 0 ? optionValue(element.options[index]) : null;
+ }
- selectMany: function(element) {
+ function selectMany(element) {
var values, length = element.length;
if (!length) return null;
for (var i = 0, values = []; i < length; i++) {
var opt = element.options[i];
- if (opt.selected) values.push(this.optionValue(opt));
+ if (opt.selected) values.push(optionValue(opt));
}
return values;
- },
+ }
- optionValue: function(opt) {
- return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;
+ function optionValue(opt) {
+ return Element.hasAttribute(opt, 'value') ? opt.value : opt.text;
}
-};
+
+ return {
+ input: input,
+ inputSelector: inputSelector,
+ textarea: valueSelector,
+ select: select,
+ selectOne: selectOne,
+ selectMany: selectMany,
+ optionValue: optionValue,
+ button: valueSelector
+ };
+})();
/*--------------------------------------------------------------------------*/
@@ -5324,24 +5353,53 @@ Form.EventObserver = Class.create(Abstract.EventObserver, {
var MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED = 'onmouseenter' in docEl
&& 'onmouseleave' in docEl;
+
+
+ var isIELegacyEvent = function(event) { return false; };
+
+ if (window.attachEvent) {
+ if (window.addEventListener) {
+ isIELegacyEvent = function(event) {
+ return !(event instanceof window.Event);
+ };
+ } else {
+ isIELegacyEvent = function(event) { return true; };
+ }
+ }
+
var _isButton;
- if (Prototype.Browser.IE) {
- var buttonMap = { 0: 1, 1: 4, 2: 2 };
- _isButton = function(event, code) {
- return event.button === buttonMap[code];
- };
- } else if (Prototype.Browser.WebKit) {
- _isButton = function(event, code) {
- switch (code) {
- case 0: return event.which == 1 && !event.metaKey;
- case 1: return event.which == 1 && event.metaKey;
- default: return false;
+
+ function _isButtonForDOMEvents(event, code) {
+ return event.which ? (event.which === code + 1) : (event.button === code);
+ }
+
+ var legacyButtonMap = { 0: 1, 1: 4, 2: 2 };
+ function _isButtonForLegacyEvents(event, code) {
+ return event.button === legacyButtonMap[code];
+ }
+
+ function _isButtonForWebKit(event, code) {
+ switch (code) {
+ case 0: return event.which == 1 && !event.metaKey;
+ case 1: return event.which == 2 || (event.which == 1 && event.metaKey);
+ case 2: return event.which == 3;
+ default: return false;
+ }
+ }
+
+ if (window.attachEvent) {
+ if (!window.addEventListener) {
+ _isButton = _isButtonForLegacyEvents;
+ } else {
+ _isButton = function(event, code) {
+ return isIELegacyEvent(event) ? _isButtonForLegacyEvents(event, code) :
+ _isButtonForDOMEvents(event, code);
}
- };
+ }
+ } else if (Prototype.Browser.WebKit) {
+ _isButton = _isButtonForWebKit;
} else {
- _isButton = function(event, code) {
- return event.which ? (event.which === code + 1) : (event.button === code);
- };
+ _isButton = _isButtonForDOMEvents;
}
function isLeftClick(event) { return _isButton(event, 0) }
@@ -5371,6 +5429,7 @@ Form.EventObserver = Class.create(Abstract.EventObserver, {
function findElement(event, expression) {
var element = Event.element(event);
+
if (!expression) return element;
while (element) {
if (Object.isElement(element) && Prototype.Selector.match(element, expression)) {
@@ -5411,49 +5470,59 @@ Form.EventObserver = Class.create(Abstract.EventObserver, {
event.stopped = true;
}
+
Event.Methods = {
- isLeftClick: isLeftClick,
+ isLeftClick: isLeftClick,
isMiddleClick: isMiddleClick,
- isRightClick: isRightClick,
+ isRightClick: isRightClick,
- element: element,
+ element: element,
findElement: findElement,
- pointer: pointer,
+ pointer: pointer,
pointerX: pointerX,
pointerY: pointerY,
stop: stop
};
-
var methods = Object.keys(Event.Methods).inject({ }, function(m, name) {
m[name] = Event.Methods[name].methodize();
return m;
});
- if (Prototype.Browser.IE) {
+ if (window.attachEvent) {
function _relatedTarget(event) {
var element;
switch (event.type) {
- case 'mouseover': element = event.fromElement; break;
- case 'mouseout': element = event.toElement; break;
- default: return null;
+ case 'mouseover':
+ case 'mouseenter':
+ element = event.fromElement;
+ break;
+ case 'mouseout':
+ case 'mouseleave':
+ element = event.toElement;
+ break;
+ default:
+ return null;
}
return Element.extend(element);
}
- Object.extend(methods, {
+ var additionalMethods = {
stopPropagation: function() { this.cancelBubble = true },
preventDefault: function() { this.returnValue = false },
inspect: function() { return '[object Event]' }
- });
+ };
Event.extend = function(event, element) {
if (!event) return false;
- if (event._extendedByPrototype) return event;
+ if (!isIELegacyEvent(event)) return event;
+
+ if (event._extendedByPrototype) return event;
event._extendedByPrototype = Prototype.emptyFunction;
+
var pointer = Event.pointer(event);
Object.extend(event, {
@@ -5463,12 +5532,18 @@ Form.EventObserver = Class.create(Abstract.EventObserver, {
pageY: pointer.y
});
- return Object.extend(event, methods);
+ Object.extend(event, methods);
+ Object.extend(event, additionalMethods);
+
+ return event;
};
} else {
+ Event.extend = Prototype.K;
+ }
+
+ if (window.addEventListener) {
Event.prototype = window.Event.prototype || document.createEvent('HTMLEvents').__proto__;
Object.extend(Event.prototype, methods);
- Event.extend = Prototype.K;
}
function _createResponder(element, eventName, handler) {
@@ -5567,7 +5642,7 @@ Form.EventObserver = Class.create(Abstract.EventObserver, {
element.addEventListener("dataavailable", responder, false);
else {
element.attachEvent("ondataavailable", responder);
- element.attachEvent("onfilterchange", responder);
+ element.attachEvent("onlosecapture", responder);
}
} else {
var actualEventName = _getDOMEventName(eventName);
@@ -5605,7 +5680,13 @@ Form.EventObserver = Class.create(Abstract.EventObserver, {
return element;
}
- var responder = responders.find( function(r) { return r.handler === handler; });
+ var i = responders.length, responder;
+ while (i--) {
+ if (responders[i].handler === handler) {
+ responder = responders[i];
+ break;
+ }
+ }
if (!responder) return element;
if (eventName.include(':')) {
@@ -5613,7 +5694,7 @@ Form.EventObserver = Class.create(Abstract.EventObserver, {
element.removeEventListener("dataavailable", responder, false);
else {
element.detachEvent("ondataavailable", responder);
- element.detachEvent("onfilterchange", responder);
+ element.detachEvent("onlosecapture", responder);
}
} else {
var actualEventName = _getDOMEventName(eventName);
@@ -5640,10 +5721,10 @@ Form.EventObserver = Class.create(Abstract.EventObserver, {
var event;
if (document.createEvent) {
event = document.createEvent('HTMLEvents');
- event.initEvent('dataavailable', true, true);
+ event.initEvent('dataavailable', bubble, true);
} else {
event = document.createEventObject();
- event.eventType = bubble ? 'ondataavailable' : 'onfilterchange';
+ event.eventType = bubble ? 'ondataavailable' : 'onlosecapture';
}
event.eventName = eventName;
@@ -5677,7 +5758,7 @@ Form.EventObserver = Class.create(Abstract.EventObserver, {
},
handleEvent: function(event) {
- var element = event.findElement(this.selector);
+ var element = Event.findElement(event, this.selector);
if (element) this.callback.call(this.element, event, element);
}
});
diff --git a/railties/lib/rails/generators/rails/app/templates/public/javascripts/rails.js b/railties/lib/rails/generators/rails/app/templates/public/javascripts/prototype_ujs.js
index 4283ed8982..fc69f93c58 100644
--- a/railties/lib/rails/generators/rails/app/templates/public/javascripts/rails.js
+++ b/railties/lib/rails/generators/rails/app/templates/public/javascripts/prototype_ujs.js
@@ -14,33 +14,33 @@
}
function isForm(element) {
- return Object.isElement(element) && element.nodeName.toUpperCase() == 'FORM'
+ return Object.isElement(element) && element.nodeName.toUpperCase() == 'FORM';
}
function isInput(element) {
if (Object.isElement(element)) {
- var name = element.nodeName.toUpperCase()
- return name == 'INPUT' || name == 'SELECT' || name == 'TEXTAREA'
+ var name = element.nodeName.toUpperCase();
+ return name == 'INPUT' || name == 'SELECT' || name == 'TEXTAREA';
}
- else return false
+ else return false;
}
var submitBubbles = isEventSupported('submit'),
- changeBubbles = isEventSupported('change')
+ changeBubbles = isEventSupported('change');
if (!submitBubbles || !changeBubbles) {
// augment the Event.Handler class to observe custom events when needed
Event.Handler.prototype.initialize = Event.Handler.prototype.initialize.wrap(
function(init, element, eventName, selector, callback) {
- init(element, eventName, selector, callback)
+ init(element, eventName, selector, callback);
// is the handler being attached to an element that doesn't support this event?
if ( (!submitBubbles && this.eventName == 'submit' && !isForm(this.element)) ||
(!changeBubbles && this.eventName == 'change' && !isInput(this.element)) ) {
// "submit" => "emulated:submit"
- this.eventName = 'emulated:' + this.eventName
+ this.eventName = 'emulated:' + this.eventName;
}
}
- )
+ );
}
if (!submitBubbles) {
@@ -49,26 +49,26 @@
// special handler for the real "submit" event (one-time operation)
if (!form.retrieve('emulated:submit')) {
form.on('submit', function(submitEvent) {
- var emulated = form.fire('emulated:submit', submitEvent, true)
+ var emulated = form.fire('emulated:submit', submitEvent, true);
// if custom event received preventDefault, cancel the real one too
- if (emulated.returnValue === false) submitEvent.preventDefault()
- })
- form.store('emulated:submit', true)
+ if (emulated.returnValue === false) submitEvent.preventDefault();
+ });
+ form.store('emulated:submit', true);
}
- })
+ });
}
if (!changeBubbles) {
// discover form inputs on the page
- document.on('focusin', 'input, select, texarea', function(focusEvent, input) {
+ document.on('focusin', 'input, select, textarea', function(focusEvent, input) {
// special handler for real "change" events
if (!input.retrieve('emulated:change')) {
input.on('change', function(changeEvent) {
- input.fire('emulated:change', changeEvent, true)
- })
- input.store('emulated:change', true)
+ input.fire('emulated:change', changeEvent, true);
+ });
+ input.store('emulated:change', true);
}
- })
+ });
}
function handleRemote(element) {
@@ -80,7 +80,10 @@
if (element.tagName.toLowerCase() === 'form') {
method = element.readAttribute('method') || 'post';
url = element.readAttribute('action');
- params = element.serialize();
+ // serialize the form with respect to the submit button that was pressed
+ params = element.serialize({ submit: element.retrieve('rails:submit-button') });
+ // clear the pressed submit button information
+ element.store('rails:submit-button', null);
} else {
method = element.readAttribute('data-method') || 'get';
url = element.readAttribute('href');
@@ -100,6 +103,10 @@
element.fire("ajax:after");
}
+ function insertHiddenField(form, name, value) {
+ form.insert(new Element('input', { type: 'hidden', name: name, value: value }));
+ }
+
function handleMethod(element) {
var method = element.readAttribute('data-method'),
url = element.readAttribute('href'),
@@ -110,15 +117,11 @@
element.parentNode.insert(form);
if (method !== 'post') {
- var field = new Element('input', { type: 'hidden', name: '_method', value: method });
- form.insert(field);
+ insertHiddenField(form, '_method', method);
}
if (csrf_param) {
- var param = csrf_param.readAttribute('content'),
- token = csrf_token.readAttribute('content'),
- field = new Element('input', { type: 'hidden', name: param, value: token });
- form.insert(field);
+ insertHiddenField(form, csrf_param.readAttribute('content'), csrf_token.readAttribute('content'));
}
form.submit();
@@ -142,34 +145,34 @@
event.stop();
});
+ document.on("click", "form input[type=submit]", function(event, button) {
+ // register the pressed submit button
+ event.findElement('form').store('rails:submit-button', button.name || false);
+ });
+
document.on("submit", function(event) {
- var element = event.findElement(),
- message = element.readAttribute('data-confirm');
+ var form = event.findElement(),
+ message = form.readAttribute('data-confirm');
+
if (message && !confirm(message)) {
event.stop();
return false;
}
- var inputs = element.select("input[type=submit][data-disable-with]");
- inputs.each(function(input) {
- input.disabled = true;
- input.writeAttribute('data-original-value', input.value);
- input.value = input.readAttribute('data-disable-with');
+ form.select('input[type=submit][data-disable-with]').each(function(input) {
+ input.store('rails:original-value', input.getValue());
+ input.disable().setValue(input.readAttribute('data-disable-with'));
});
- var element = event.findElement("form[data-remote]");
- if (element) {
- handleRemote(element);
+ if (form.readAttribute('data-remote')) {
+ handleRemote(form);
event.stop();
}
});
- document.on("ajax:after", "form", function(event, element) {
- var inputs = element.select("input[type=submit][disabled=true][data-disable-with]");
- inputs.each(function(input) {
- input.value = input.readAttribute('data-original-value');
- input.removeAttribute('data-original-value');
- input.disabled = false;
+ document.on("ajax:after", "form", function(event, form) {
+ form.select('input[type=submit][data-disable-with]').each(function(input) {
+ input.setValue(input.retrieve('rails:original-value')).enable();
});
});
})();
diff --git a/railties/lib/rails/generators/rails/plugin/plugin_generator.rb b/railties/lib/rails/generators/rails/plugin/plugin_generator.rb
index 40ed2062d3..97f681d826 100644
--- a/railties/lib/rails/generators/rails/plugin/plugin_generator.rb
+++ b/railties/lib/rails/generators/rails/plugin/plugin_generator.rb
@@ -1,3 +1,4 @@
+
require 'rails/generators/rails/generator/generator_generator'
module Rails
@@ -5,6 +6,12 @@ module Rails
class PluginGenerator < NamedBase
class_option :tasks, :desc => "When supplied creates tasks base files."
+ def show_deprecation
+ return unless behavior == :invoke
+ message = "Plugin generator is deprecated, please use 'rails plugin new' command to generate plugin structure."
+ ActiveSupport::Deprecation.warn message
+ end
+
check_class_collision
def create_root_files
diff --git a/railties/lib/rails/generators/rails/plugin/templates/Rakefile.tt b/railties/lib/rails/generators/rails/plugin/templates/Rakefile.tt
index 733e321c94..77149ae351 100644
--- a/railties/lib/rails/generators/rails/plugin/templates/Rakefile.tt
+++ b/railties/lib/rails/generators/rails/plugin/templates/Rakefile.tt
@@ -1,4 +1,4 @@
-require 'rake'
+#!/usr/bin/env rake
require 'rake/testtask'
require 'rake/rdoctask'
diff --git a/railties/lib/rails/generators/rails/plugin_new/USAGE b/railties/lib/rails/generators/rails/plugin_new/USAGE
new file mode 100644
index 0000000000..9a7bf9f396
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/USAGE
@@ -0,0 +1,10 @@
+Description:
+ The 'rails plugin new' command creates a skeleton for developing any
+ kind of Rails extension with ability to run tests using dummy Rails
+ application.
+
+Example:
+ rails plugin new ~/Code/Ruby/blog
+
+ This generates a skeletal Rails plugin in ~/Code/Ruby/blog.
+ See the README in the newly created plugin to get going.
diff --git a/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb b/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb
new file mode 100644
index 0000000000..9c54b98238
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb
@@ -0,0 +1,249 @@
+require 'active_support/core_ext/hash/slice'
+require "rails/generators/rails/app/app_generator"
+
+module Rails
+ class PluginBuilder
+ def rakefile
+ template "Rakefile"
+ end
+
+ def app
+ directory "app" if options[:mountable]
+ end
+
+ def readme
+ copy_file "README.rdoc"
+ end
+
+ def gemfile
+ template "Gemfile"
+ end
+
+ def license
+ template "MIT-LICENSE"
+ end
+
+ def gemspec
+ template "%name%.gemspec"
+ end
+
+ def gitignore
+ copy_file "gitignore", ".gitignore"
+ end
+
+ def lib
+ template "lib/%name%.rb"
+ template "lib/tasks/%name%_tasks.rake"
+ if full?
+ template "lib/%name%/engine.rb"
+ end
+ end
+
+ def config
+ template "config/routes.rb" if mountable?
+ end
+
+ def test
+ template "test/test_helper.rb"
+ template "test/%name%_test.rb"
+ append_file "Rakefile", <<-EOF
+#{rakefile_test_tasks}
+
+task :default => :test
+ EOF
+ if full?
+ template "test/integration/navigation_test.rb"
+ end
+ end
+
+ def generate_test_dummy(force = false)
+ opts = (options || {}).slice(:skip_active_record, :skip_javascript, :database, :javascript)
+ opts[:force] = force
+
+ invoke Rails::Generators::AppGenerator,
+ [ File.expand_path(dummy_path, destination_root) ], opts
+ end
+
+ def test_dummy_config
+ template "rails/boot.rb", "#{dummy_path}/config/boot.rb", :force => true
+ template "rails/application.rb", "#{dummy_path}/config/application.rb", :force => true
+ if mountable?
+ template "rails/routes.rb", "#{dummy_path}/config/routes.rb", :force => true
+ end
+ end
+
+ def test_dummy_clean
+ inside dummy_path do
+ remove_file ".gitignore"
+ remove_file "db/seeds.rb"
+ remove_file "doc"
+ remove_file "Gemfile"
+ remove_file "lib/tasks"
+ remove_file "public/images/rails.png"
+ remove_file "public/index.html"
+ remove_file "public/robots.txt"
+ remove_file "README"
+ remove_file "test"
+ remove_file "vendor"
+ end
+ end
+
+ def script(force = false)
+ directory "script", :force => force do |content|
+ "#{shebang}\n" + content
+ end
+ chmod "script", 0755, :verbose => false
+ end
+ end
+
+ module Generators
+ class PluginNewGenerator < AppBase
+ add_shared_options_for "plugin"
+
+ alias_method :plugin_path, :app_path
+
+ class_option :dummy_path, :type => :string, :default => "test/dummy",
+ :desc => "Create dummy application at given path"
+
+ class_option :full, :type => :boolean, :default => false,
+ :desc => "Generate rails engine with integration tests"
+
+ class_option :mountable, :type => :boolean, :default => false,
+ :desc => "Generate mountable isolated application"
+
+ class_option :skip_gemspec, :type => :boolean, :default => false,
+ :desc => "Skip gemspec file"
+
+ def initialize(*args)
+ raise Error, "Options should be given after the plugin name. For details run: rails plugin --help" if args[0].blank?
+
+ super
+ end
+
+ public_task :create_root
+
+ def create_root_files
+ build(:readme)
+ build(:rakefile)
+ build(:gemspec) unless options[:skip_gemspec]
+ build(:license)
+ build(:gitignore) unless options[:skip_git]
+ build(:gemfile) unless options[:skip_gemfile]
+ end
+
+ def create_app_files
+ build(:app)
+ end
+
+ def create_config_files
+ build(:config)
+ end
+
+ def create_lib_files
+ build(:lib)
+ end
+
+ def create_script_files
+ build(:script)
+ end
+
+ def create_test_files
+ build(:test) unless options[:skip_test_unit]
+ end
+
+ def create_test_dummy_files
+ return if options[:skip_test_unit]
+ create_dummy_app
+ end
+
+ def finish_template
+ build(:leftovers)
+ end
+
+ public_task :apply_rails_template, :bundle_if_dev_or_edge
+
+ protected
+ def create_dummy_app(path = nil)
+ dummy_path(path) if path
+
+ say_status :vendor_app, dummy_path
+ mute do
+ build(:generate_test_dummy)
+ store_application_definition!
+ build(:test_dummy_config)
+ build(:test_dummy_clean)
+ # ensure that script/rails has proper dummy_path
+ build(:script, true)
+ end
+ end
+
+ def full?
+ options[:full] || options[:mountable]
+ end
+
+ def mountable?
+ options[:mountable]
+ end
+
+ def self.banner
+ "rails plugin new #{self.arguments.map(&:usage).join(' ')} [options]"
+ end
+
+ def name
+ @name ||= File.basename(destination_root)
+ end
+
+ def camelized
+ @camelized ||= name.gsub(/\W/, '_').squeeze('_').camelize
+ end
+
+ def valid_const?
+ if camelized =~ /^\d/
+ raise Error, "Invalid plugin name #{name}. Please give a name which does not start with numbers."
+ elsif RESERVED_NAMES.include?(name)
+ raise Error, "Invalid plugin name #{name}. Please give a name which does not match one of the reserved rails words."
+ elsif Object.const_defined?(camelized)
+ raise Error, "Invalid plugin name #{name}, constant #{camelized} is already in use. Please choose another application name."
+ end
+ end
+
+ def application_definition
+ @application_definition ||= begin
+
+ dummy_application_path = File.expand_path("#{dummy_path}/config/application.rb", destination_root)
+ unless options[:pretend] || !File.exists?(dummy_application_path)
+ contents = File.read(dummy_application_path)
+ contents[(contents.index("module Dummy"))..-1]
+ end
+ end
+ end
+ alias :store_application_definition! :application_definition
+
+ def get_builder_class
+ defined?(::PluginBuilder) ? ::PluginBuilder : Rails::PluginBuilder
+ end
+
+ def rakefile_test_tasks
+ <<-RUBY
+require 'rake/testtask'
+
+Rake::TestTask.new(:test) do |t|
+ t.libs << 'lib'
+ t.libs << 'test'
+ t.pattern = 'test/**/*_test.rb'
+ t.verbose = false
+end
+ RUBY
+ end
+
+ def dummy_path(path = nil)
+ @dummy_path = path if path
+ @dummy_path || options[:dummy_path]
+ end
+
+ def mute(&block)
+ shell.mute(&block)
+ end
+ end
+ end
+end
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/%name%.gemspec b/railties/lib/rails/generators/rails/plugin_new/templates/%name%.gemspec
new file mode 100644
index 0000000000..3d9bfb22c7
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/%name%.gemspec
@@ -0,0 +1,9 @@
+# Provide a simple gemspec so you can easily use your
+# project in your rails apps through git.
+Gem::Specification.new do |s|
+ s.name = "<%= name %>"
+ s.summary = "Insert <%= camelized %> summary."
+ s.description = "Insert <%= camelized %> description."
+ s.files = Dir["lib/**/*"] + ["MIT-LICENSE", "Rakefile", "README.rdoc"]
+ s.version = "0.0.1"
+end
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/Gemfile b/railties/lib/rails/generators/rails/plugin_new/templates/Gemfile
new file mode 100644
index 0000000000..29900c93dc
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/Gemfile
@@ -0,0 +1,11 @@
+source "http://rubygems.org"
+
+<%= rails_gemfile_entry -%>
+
+<% if full? -%>
+<%= database_gemfile_entry -%>
+<% end -%>
+
+if RUBY_VERSION < '1.9'
+ gem "ruby-debug", ">= 0.10.3"
+end
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/MIT-LICENSE b/railties/lib/rails/generators/rails/plugin_new/templates/MIT-LICENSE
new file mode 100644
index 0000000000..d7a9109894
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/MIT-LICENSE
@@ -0,0 +1,20 @@
+Copyright <%= Date.today.year %> YOURNAME
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/README.rdoc b/railties/lib/rails/generators/rails/plugin_new/templates/README.rdoc
new file mode 100644
index 0000000000..301d647731
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/README.rdoc
@@ -0,0 +1,3 @@
+= <%= camelized %>
+
+This project rocks and uses MIT-LICENSE. \ No newline at end of file
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/Rakefile b/railties/lib/rails/generators/rails/plugin_new/templates/Rakefile
new file mode 100755
index 0000000000..12350309bf
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/Rakefile
@@ -0,0 +1,16 @@
+#!/usr/bin/env rake
+begin
+ require 'bundler/setup'
+rescue LoadError
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
+end
+
+require 'rake/rdoctask'
+
+Rake::RDocTask.new(:rdoc) do |rdoc|
+ rdoc.rdoc_dir = 'rdoc'
+ rdoc.title = '<%= camelized %>'
+ rdoc.options << '--line-numbers' << '--inline-source'
+ rdoc.rdoc_files.include('README.rdoc')
+ rdoc.rdoc_files.include('lib/**/*.rb')
+end
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/app/controllers/%name%/application_controller.rb.tt b/railties/lib/rails/generators/rails/plugin_new/templates/app/controllers/%name%/application_controller.rb.tt
new file mode 100644
index 0000000000..448ad7f989
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/app/controllers/%name%/application_controller.rb.tt
@@ -0,0 +1,4 @@
+module <%= camelized %>
+ class ApplicationController < ActionController::Base
+ end
+end
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/app/helpers/%name%/application_helper.rb.tt b/railties/lib/rails/generators/rails/plugin_new/templates/app/helpers/%name%/application_helper.rb.tt
new file mode 100644
index 0000000000..40ae9f52c2
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/app/helpers/%name%/application_helper.rb.tt
@@ -0,0 +1,4 @@
+module <%= camelized %>
+ module ApplicationHelper
+ end
+end
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/config/routes.rb b/railties/lib/rails/generators/rails/plugin_new/templates/config/routes.rb
new file mode 100644
index 0000000000..42ddf380d8
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/config/routes.rb
@@ -0,0 +1,3 @@
+<%= camelized %>::Engine.routes.draw do
+
+end
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/gitignore b/railties/lib/rails/generators/rails/plugin_new/templates/gitignore
new file mode 100644
index 0000000000..1463de6dfb
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/gitignore
@@ -0,0 +1,6 @@
+.bundle/
+log/*.log
+pkg/
+test/dummy/db/*.sqlite3
+test/dummy/log/*.log
+test/dummy/tmp/ \ No newline at end of file
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/lib/%name%.rb b/railties/lib/rails/generators/rails/plugin_new/templates/lib/%name%.rb
new file mode 100644
index 0000000000..2d3bdc510c
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/lib/%name%.rb
@@ -0,0 +1,6 @@
+<% if full? -%>
+require "<%= name %>/engine"
+
+<% end -%>
+module <%= camelized %>
+end
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/lib/%name%/engine.rb b/railties/lib/rails/generators/rails/plugin_new/templates/lib/%name%/engine.rb
new file mode 100644
index 0000000000..9600ee0c3f
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/lib/%name%/engine.rb
@@ -0,0 +1,7 @@
+module <%= camelized %>
+ class Engine < Rails::Engine
+<% if mountable? -%>
+ isolate_namespace <%= camelized %>
+<% end -%>
+ end
+end
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/lib/tasks/%name%_tasks.rake b/railties/lib/rails/generators/rails/plugin_new/templates/lib/tasks/%name%_tasks.rake
new file mode 100644
index 0000000000..7121f5ae23
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/lib/tasks/%name%_tasks.rake
@@ -0,0 +1,4 @@
+# desc "Explaining what the task does"
+# task :<%= name %> do
+# # Task goes here
+# end
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/rails/application.rb b/railties/lib/rails/generators/rails/plugin_new/templates/rails/application.rb
new file mode 100644
index 0000000000..8b68280a5e
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/rails/application.rb
@@ -0,0 +1,16 @@
+require File.expand_path('../boot', __FILE__)
+
+<% unless options[:skip_active_record] -%>
+require 'rails/all'
+<% else -%>
+# require "active_record/railtie"
+require "action_controller/railtie"
+require "action_mailer/railtie"
+require "active_resource/railtie"
+require "rails/test_unit/railtie"
+<% end -%>
+
+Bundler.require
+require "<%= name %>"
+
+<%= application_definition %>
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/rails/boot.rb b/railties/lib/rails/generators/rails/plugin_new/templates/rails/boot.rb
new file mode 100644
index 0000000000..eba0681370
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/rails/boot.rb
@@ -0,0 +1,10 @@
+require 'rubygems'
+gemfile = File.expand_path('../../../../Gemfile', __FILE__)
+
+if File.exist?(gemfile)
+ ENV['BUNDLE_GEMFILE'] = gemfile
+ require 'bundler'
+ Bundler.setup
+end
+
+$:.unshift File.expand_path('../../../../lib', __FILE__) \ No newline at end of file
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/rails/routes.rb b/railties/lib/rails/generators/rails/plugin_new/templates/rails/routes.rb
new file mode 100644
index 0000000000..730ee31c3d
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/rails/routes.rb
@@ -0,0 +1,4 @@
+Rails.application.routes.draw do
+
+ mount <%= camelized %>::Engine => "/<%= name %>"
+end
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/script/rails.tt b/railties/lib/rails/generators/rails/plugin_new/templates/script/rails.tt
new file mode 100644
index 0000000000..ebd5a77dd5
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/script/rails.tt
@@ -0,0 +1,5 @@
+#!/usr/bin/env ruby
+# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
+
+ENGINE_PATH = File.expand_path('../..', __FILE__)
+load File.expand_path('../../<%= dummy_path %>/script/rails', __FILE__)
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/test/%name%_test.rb b/railties/lib/rails/generators/rails/plugin_new/templates/test/%name%_test.rb
new file mode 100644
index 0000000000..0a8bbd4aaf
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/test/%name%_test.rb
@@ -0,0 +1,7 @@
+require 'test_helper'
+
+class <%= camelized %>Test < ActiveSupport::TestCase
+ test "truth" do
+ assert_kind_of Module, <%= camelized %>
+ end
+end
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/test/integration/navigation_test.rb b/railties/lib/rails/generators/rails/plugin_new/templates/test/integration/navigation_test.rb
new file mode 100644
index 0000000000..d06fe7cbd0
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/test/integration/navigation_test.rb
@@ -0,0 +1,11 @@
+require 'test_helper'
+
+class NavigationTest < ActionDispatch::IntegrationTest
+ fixtures :all
+
+ # Replace this with your real tests.
+ test "the truth" do
+ assert true
+ end
+end
+
diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/test/test_helper.rb b/railties/lib/rails/generators/rails/plugin_new/templates/test/test_helper.rb
new file mode 100644
index 0000000000..7b61047e77
--- /dev/null
+++ b/railties/lib/rails/generators/rails/plugin_new/templates/test/test_helper.rb
@@ -0,0 +1,15 @@
+# Configure Rails Envinronment
+ENV["RAILS_ENV"] = "test"
+
+require File.expand_path("../dummy/config/environment.rb", __FILE__)
+require "rails/test_help"
+
+Rails.backtrace_cleaner.remove_silencers!
+
+<% if full? && !options[:skip_active_record] -%>
+# Run any available migration from application
+ActiveRecord::Migrator.migrate File.expand_path("../dummy/db/migrate/", __FILE__)
+<% end -%>
+
+# Load support files
+Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
diff --git a/railties/lib/rails/generators/rails/resource/resource_generator.rb b/railties/lib/rails/generators/rails/resource/resource_generator.rb
index 8a943013d3..c7345f3cfb 100644
--- a/railties/lib/rails/generators/rails/resource/resource_generator.rb
+++ b/railties/lib/rails/generators/rails/resource/resource_generator.rb
@@ -16,9 +16,9 @@ module Rails
def add_resource_route
return if options[:actions].present?
- route_config = class_path.collect{|namespace| "namespace :#{namespace} do " }.join(" ")
+ route_config = regular_class_path.collect{|namespace| "namespace :#{namespace} do " }.join(" ")
route_config << "resources :#{file_name.pluralize}"
- route_config << " end" * class_path.size
+ route_config << " end" * regular_class_path.size
route route_config
end
end
diff --git a/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb b/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb
index b21340f755..b5317a055b 100644
--- a/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb
+++ b/railties/lib/rails/generators/rails/scaffold_controller/templates/controller.rb
@@ -1,3 +1,4 @@
+<% module_namespacing do -%>
class <%= controller_class_name %>Controller < ApplicationController
# GET <%= route_url %>
# GET <%= route_url %>.xml
@@ -81,3 +82,4 @@ class <%= controller_class_name %>Controller < ApplicationController
end
end
end
+<% end -%>
diff --git a/railties/lib/rails/generators/resource_helpers.rb b/railties/lib/rails/generators/resource_helpers.rb
index 829f4b200a..d6ccfc496a 100644
--- a/railties/lib/rails/generators/resource_helpers.rb
+++ b/railties/lib/rails/generators/resource_helpers.rb
@@ -17,7 +17,7 @@ module Rails
def initialize(*args) #:nodoc:
super
- if name == name.pluralize && !options[:force_plural]
+ if name == name.pluralize && name.singularize != name.pluralize && !options[:force_plural]
unless ResourceHelpers.skip_warn
say "Plural version of the model detected, using singularized version. Override with --force-plural."
ResourceHelpers.skip_warn = true
@@ -34,7 +34,7 @@ module Rails
attr_reader :controller_name
def controller_class_path
- @class_path
+ class_path
end
def controller_file_name
@@ -46,7 +46,7 @@ module Rails
end
def controller_class_name
- @controller_class_name ||= (controller_class_path + [controller_file_name]).map!{ |m| m.camelize }.join('::')
+ (controller_class_path + [controller_file_name]).map!{ |m| m.camelize }.join('::')
end
def controller_i18n_scope
diff --git a/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb b/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb
index f23e495450..964d59d84c 100644
--- a/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb
+++ b/railties/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb
@@ -1,5 +1,6 @@
require 'test_helper'
+<% module_namespacing do -%>
class <%= controller_class_name %>ControllerTest < ActionController::TestCase
setup do
@<%= singular_table_name %> = <%= table_name %>(:one)
@@ -47,3 +48,4 @@ class <%= controller_class_name %>ControllerTest < ActionController::TestCase
assert_redirected_to <%= index_helper %>_path
end
end
+<% end -%>
diff --git a/railties/lib/rails/info.rb b/railties/lib/rails/info.rb
index 6cbd1f21c0..d05e031f56 100644
--- a/railties/lib/rails/info.rb
+++ b/railties/lib/rails/info.rb
@@ -1,5 +1,4 @@
require "cgi"
-require "active_support/core_ext/cgi"
module Rails
module Info
diff --git a/railties/lib/rails/rack/log_tailer.rb b/railties/lib/rails/rack/log_tailer.rb
index 011ac6cecc..830d840894 100644
--- a/railties/lib/rails/rack/log_tailer.rb
+++ b/railties/lib/rails/rack/log_tailer.rb
@@ -19,7 +19,7 @@ module Rails
def tail!
@file.seek @cursor
- if !@file.eof?
+ unless @file.eof?
contents = @file.read
@cursor = @file.tell
$stdout.print contents
diff --git a/railties/lib/rails/railtie.rb b/railties/lib/rails/railtie.rb
index c76bc83377..030a838dc1 100644
--- a/railties/lib/rails/railtie.rb
+++ b/railties/lib/rails/railtie.rb
@@ -97,7 +97,7 @@ module Rails
# If your railtie has rake tasks, you can tell Rails to load them through the method
# rake tasks:
#
- # class MyRailtie < Railtie
+ # class MyRailtie < Rails::Railtie
# rake_tasks do
# load "path/to/my_railtie.tasks"
# end
@@ -107,7 +107,7 @@ module Rails
# your generators at a different location, you can specify in your Railtie a block which
# will load them during normal generators lookup:
#
- # class MyRailtie < Railtie
+ # class MyRailtie < Rails::Railtie
# generators do
# require "path/to/my_railtie_generator"
# end
diff --git a/railties/lib/rails/tasks/framework.rake b/railties/lib/rails/tasks/framework.rake
index 745a32a1fa..5222b7bf50 100644
--- a/railties/lib/rails/tasks/framework.rake
+++ b/railties/lib/rails/tasks/framework.rake
@@ -60,7 +60,7 @@ namespace :rails do
# desc "Update Prototype javascripts from your current rails install"
task :javascripts do
- invoke_from_app_generator :create_prototype_files
+ invoke_from_app_generator :create_javascript_files
end
# desc "Adds new scripts to the application script/ directory"
diff --git a/railties/lib/rails/tasks/railties.rake b/railties/lib/rails/tasks/railties.rake
index e08bd9687d..16703879cf 100644
--- a/railties/lib/rails/tasks/railties.rake
+++ b/railties/lib/rails/tasks/railties.rake
@@ -1,20 +1,29 @@
namespace :railties do
- # desc "Create symlinks to railties public directories in application's public directory."
- task :create_symlinks => :environment do
- paths = Rails.application.config.static_asset_paths.dup
- app_public_path = Rails.application.paths["public"].first
+ namespace :install do
+ # desc "Copies missing assets from Railties (e.g. plugins, engines). You can specify Railties to use with FROM=railtie1,railtie2"
+ task :assets => :rails_env do
+ require 'rails/generators/base'
+ Rails.application.initialize!
- paths.each do |mount_path, path|
- symlink_path = File.join(app_public_path, mount_path)
- if File.exist?(symlink_path)
- File.symlink?(symlink_path) ? FileUtils.rm(symlink_path) : next
- end
+ to_load = ENV["FROM"].blank? ? :all : ENV["FROM"].split(",").map {|n| n.strip }
+ app_public_path = Rails.application.paths["public"].first
- next unless File.exist?(path)
+ Rails.application.railties.all do |railtie|
+ next unless to_load == :all || to_load.include?(railtie.railtie_name)
- File.symlink(path, symlink_path)
+ if railtie.respond_to?(:paths) && (path = railtie.paths["public"].first) &&
+ (assets_dir = railtie.config.compiled_asset_path) && File.exist?(path)
- puts "Created symlink #{symlink_path} -> #{path}"
+ Rails::Generators::Base.source_root(path)
+ copier = Rails::Generators::Base.new
+ Dir[File.join(path, "**/*")].each do |file|
+ relative = file.gsub(/^#{path}\//, '')
+ if File.file?(file)
+ copier.copy_file relative, File.join(app_public_path, assets_dir, relative)
+ end
+ end
+ end
+ end
end
end
end
diff --git a/railties/lib/rails/test_help.rb b/railties/lib/rails/test_help.rb
index 38f2f651f4..f81002328f 100644
--- a/railties/lib/rails/test_help.rb
+++ b/railties/lib/rails/test_help.rb
@@ -39,14 +39,3 @@ class ActionDispatch::IntegrationTest
@routes = Rails.application.routes
end
end
-
-begin
- require_library_or_gem 'ruby-debug'
- Debugger.start
- if Debugger.respond_to?(:settings)
- Debugger.settings[:autoeval] = true
- Debugger.settings[:autolist] = 1
- end
-rescue LoadError
- # ruby-debug wasn't available so neither can the debugging be
-end
diff --git a/railties/lib/rails/version.rb b/railties/lib/rails/version.rb
index 0213d46254..b076881c21 100644
--- a/railties/lib/rails/version.rb
+++ b/railties/lib/rails/version.rb
@@ -3,8 +3,8 @@ module Rails
MAJOR = 3
MINOR = 1
TINY = 0
- BUILD = "beta"
+ PRE = "beta"
- STRING = [MAJOR, MINOR, TINY, BUILD].join('.')
+ STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
end
end
diff --git a/railties/railties.gemspec b/railties/railties.gemspec
index d26c1bcdbc..c3793d3ac3 100644
--- a/railties/railties.gemspec
+++ b/railties/railties.gemspec
@@ -20,7 +20,7 @@ Gem::Specification.new do |s|
s.has_rdoc = false
s.add_dependency('rake', '>= 0.8.7')
- s.add_dependency('thor', '~> 0.14.3')
+ s.add_dependency('thor', '~> 0.14.4')
s.add_dependency('activesupport', version)
s.add_dependency('actionpack', version)
end
diff --git a/railties/test/application/generators_test.rb b/railties/test/application/generators_test.rb
index 551e966c85..8b840fffd0 100644
--- a/railties/test/application/generators_test.rb
+++ b/railties/test/application/generators_test.rb
@@ -25,6 +25,11 @@ module ApplicationTests
yield app_const.config
end
+ test "allow running plugin new generator inside Rails app directory" do
+ FileUtils.cd(rails_root){ `ruby script/rails plugin new vendor/plugins/bukkits` }
+ assert File.exist?(File.join(rails_root, "vendor/plugins/bukkits/test/dummy/config/application.rb"))
+ end
+
test "generators default values" do
with_bare_config do |c|
assert_equal(true, c.generators.colorize_logging)
diff --git a/railties/test/application/initializers/frameworks_test.rb b/railties/test/application/initializers/frameworks_test.rb
index 6970ea7b7a..475091f789 100644
--- a/railties/test/application/initializers/frameworks_test.rb
+++ b/railties/test/application/initializers/frameworks_test.rb
@@ -65,6 +65,66 @@ module ApplicationTests
assert_equal ["notify"], Foo.action_methods
end
+ test "allows to not load all helpers for controllers" do
+ add_to_config "config.action_controller.include_all_helpers = false"
+
+ app_file "app/controllers/application_controller.rb", <<-RUBY
+ class ApplicationController < ActionController::Base
+ end
+ RUBY
+
+ app_file "app/controllers/foo_controller.rb", <<-RUBY
+ class FooController < ApplicationController
+ def included_helpers
+ render :inline => "<%= from_app_helper -%> <%= from_foo_helper %>"
+ end
+
+ def not_included_helper
+ render :inline => "<%= respond_to?(:from_bar_helper) -%>"
+ end
+ end
+ RUBY
+
+ app_file "app/helpers/application_helper.rb", <<-RUBY
+ module ApplicationHelper
+ def from_app_helper
+ "from_app_helper"
+ end
+ end
+ RUBY
+
+ app_file "app/helpers/foo_helper.rb", <<-RUBY
+ module FooHelper
+ def from_foo_helper
+ "from_foo_helper"
+ end
+ end
+ RUBY
+
+ app_file "app/helpers/bar_helper.rb", <<-RUBY
+ module BarHelper
+ def from_bar_helper
+ "from_bar_helper"
+ end
+ end
+ RUBY
+
+ app_file "config/routes.rb", <<-RUBY
+ AppTemplate::Application.routes.draw do
+ match "/:controller(/:action)"
+ end
+ RUBY
+
+ require 'rack/test'
+ extend Rack::Test::Methods
+
+ get "/foo/included_helpers"
+ assert_equal "from_app_helper from_foo_helper", last_response.body
+
+ get "/foo/not_included_helper"
+ assert_equal "false", last_response.body
+ end
+
# AD
test "action_dispatch extensions are applied to ActionDispatch" do
add_to_config "config.action_dispatch.tld_length = 2"
diff --git a/railties/test/application/rake_test.rb b/railties/test/application/rake_test.rb
index 8e527236ea..23cd2378c7 100644
--- a/railties/test/application/rake_test.rb
+++ b/railties/test/application/rake_test.rb
@@ -34,9 +34,34 @@ module ApplicationTests
assert_match "SuperMiddleware", Dir.chdir(app_path){ `rake middleware` }
end
+ def test_initializers_are_executed_in_rake_tasks
+ add_to_config <<-RUBY
+ initializer "do_something" do
+ puts "Doing something..."
+ end
+
+ rake_tasks do
+ task :do_nothing => :environment do
+ end
+ end
+ RUBY
+
+ output = Dir.chdir(app_path){ `rake do_nothing` }
+ assert_match "Doing something...", output
+ end
+
def test_code_statistics_sanity
assert_match "Code LOC: 5 Test LOC: 0 Code to Test Ratio: 1:0.0",
Dir.chdir(app_path){ `rake stats` }
end
+
+ def test_rake_routes_output_strips_anchors_from_http_verbs
+ app_file "config/routes.rb", <<-RUBY
+ AppTemplate::Application.routes.draw do
+ get '/cart', :to => 'cart#show'
+ end
+ RUBY
+ assert_match 'cart GET /cart(.:format)', Dir.chdir(app_path){ `rake routes` }
+ end
end
end
diff --git a/railties/test/fixtures/lib/empty_builder.rb b/railties/test/fixtures/lib/app_builders/empty_builder.rb
index babd9c2461..babd9c2461 100644
--- a/railties/test/fixtures/lib/empty_builder.rb
+++ b/railties/test/fixtures/lib/app_builders/empty_builder.rb
diff --git a/railties/test/fixtures/lib/app_builders/simple_builder.rb b/railties/test/fixtures/lib/app_builders/simple_builder.rb
new file mode 100644
index 0000000000..993d3a2aa2
--- /dev/null
+++ b/railties/test/fixtures/lib/app_builders/simple_builder.rb
@@ -0,0 +1,7 @@
+class AppBuilder
+ def gitignore
+ create_file ".gitignore", <<-R.strip
+foobar
+ R
+ end
+end
diff --git a/railties/test/fixtures/lib/app_builders/tweak_builder.rb b/railties/test/fixtures/lib/app_builders/tweak_builder.rb
new file mode 100644
index 0000000000..cb50be01cb
--- /dev/null
+++ b/railties/test/fixtures/lib/app_builders/tweak_builder.rb
@@ -0,0 +1,7 @@
+class AppBuilder < Rails::AppBuilder
+ def gitignore
+ create_file ".gitignore", <<-R.strip
+foobar
+ R
+ end
+end
diff --git a/railties/test/fixtures/lib/create_test_dummy_template.rb b/railties/test/fixtures/lib/create_test_dummy_template.rb
new file mode 100644
index 0000000000..e4378bbd1a
--- /dev/null
+++ b/railties/test/fixtures/lib/create_test_dummy_template.rb
@@ -0,0 +1 @@
+create_dummy_app("spec/dummy")
diff --git a/railties/test/fixtures/lib/plugin_builders/empty_builder.rb b/railties/test/fixtures/lib/plugin_builders/empty_builder.rb
new file mode 100644
index 0000000000..5c5607621c
--- /dev/null
+++ b/railties/test/fixtures/lib/plugin_builders/empty_builder.rb
@@ -0,0 +1,2 @@
+class PluginBuilder
+end
diff --git a/railties/test/fixtures/lib/plugin_builders/simple_builder.rb b/railties/test/fixtures/lib/plugin_builders/simple_builder.rb
new file mode 100644
index 0000000000..08f6c5535d
--- /dev/null
+++ b/railties/test/fixtures/lib/plugin_builders/simple_builder.rb
@@ -0,0 +1,7 @@
+class PluginBuilder
+ def gitignore
+ create_file ".gitignore", <<-R.strip
+foobar
+ R
+ end
+end
diff --git a/railties/test/fixtures/lib/plugin_builders/spec_builder.rb b/railties/test/fixtures/lib/plugin_builders/spec_builder.rb
new file mode 100644
index 0000000000..aa18c7ddaa
--- /dev/null
+++ b/railties/test/fixtures/lib/plugin_builders/spec_builder.rb
@@ -0,0 +1,19 @@
+class PluginBuilder < Rails::PluginBuilder
+ def test
+ create_file "spec/spec_helper.rb"
+ append_file "Rakefile", <<-EOF
+# spec tasks in rakefile
+
+task :default => :spec
+ EOF
+ end
+
+ def generate_test_dummy
+ dummy_path("spec/dummy")
+ super
+ end
+
+ def skip_test_unit?
+ true
+ end
+end
diff --git a/railties/test/fixtures/lib/plugin_builders/tweak_builder.rb b/railties/test/fixtures/lib/plugin_builders/tweak_builder.rb
new file mode 100644
index 0000000000..1e801409a4
--- /dev/null
+++ b/railties/test/fixtures/lib/plugin_builders/tweak_builder.rb
@@ -0,0 +1,7 @@
+class PluginBuilder < Rails::PluginBuilder
+ def gitignore
+ create_file ".gitignore", <<-R.strip
+foobar
+ R
+ end
+end
diff --git a/railties/test/fixtures/lib/simple_builder.rb b/railties/test/fixtures/lib/simple_builder.rb
deleted file mode 100644
index 47dcdc0d96..0000000000
--- a/railties/test/fixtures/lib/simple_builder.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-class AppBuilder
- def configru
- create_file "config.ru", <<-R.strip
-run proc { |env| [200, { "Content-Type" => "text/html" }, ["Hello World"]] }
- R
- end
-end \ No newline at end of file
diff --git a/railties/test/fixtures/lib/tweak_builder.rb b/railties/test/fixtures/lib/tweak_builder.rb
deleted file mode 100644
index eed20ecc9b..0000000000
--- a/railties/test/fixtures/lib/tweak_builder.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-class AppBuilder < Rails::AppBuilder
- def configru
- create_file "config.ru", <<-R.strip
-run proc { |env| [200, { "Content-Type" => "text/html" }, ["Hello World"]] }
- R
- end
-end \ No newline at end of file
diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb
index 51277b805b..7faa674a81 100644
--- a/railties/test/generators/app_generator_test.rb
+++ b/railties/test/generators/app_generator_test.rb
@@ -1,6 +1,7 @@
require 'abstract_unit'
require 'generators/generators_test_helper'
require 'rails/generators/rails/app/app_generator'
+require 'generators/shared_generator_tests.rb'
DEFAULT_APP_FILES = %w(
.gitignore
@@ -40,36 +41,10 @@ DEFAULT_APP_FILES = %w(
class AppGeneratorTest < Rails::Generators::TestCase
include GeneratorsTestHelper
arguments [destination_root]
+ include SharedGeneratorTests
- def setup
- Rails.application = TestApp::Application
- super
- Rails::Generators::AppGenerator.instance_variable_set('@desc', nil)
- @bundle_command = File.basename(Thor::Util.ruby_command).sub(/ruby/, 'bundle')
-
- Kernel::silence_warnings do
- Thor::Base.shell.send(:attr_accessor, :always_force)
- @shell = Thor::Base.shell.new
- @shell.send(:always_force=, true)
- end
- end
-
- def teardown
- super
- Rails::Generators::AppGenerator.instance_variable_set('@desc', nil)
- Rails.application = TestApp::Application.instance
- end
-
- def test_application_skeleton_is_created
- run_generator
-
- DEFAULT_APP_FILES.each{ |path| assert_file path }
- end
-
- def test_application_generate_pretend
- run_generator ["testapp", "--pretend"]
-
- DEFAULT_APP_FILES.each{ |path| assert_no_file path }
+ def default_files
+ ::DEFAULT_APP_FILES
end
def test_application_controller_and_layout_files
@@ -78,36 +53,11 @@ class AppGeneratorTest < Rails::Generators::TestCase
assert_no_file "public/stylesheets/application.css"
end
- def test_options_before_application_name_raises_an_error
- content = capture(:stderr){ run_generator(["--skip-active-record", destination_root]) }
- assert_equal "Options should be given after the application name. For details run: rails --help\n", content
- end
-
- def test_name_collision_raises_an_error
- reserved_words = %w[application destroy plugin runner test]
- reserved_words.each do |reserved|
- content = capture(:stderr){ run_generator [File.join(destination_root, reserved)] }
- assert_equal "Invalid application name #{reserved}. Please give a name which does not match one of the reserved rails words.\n", content
- end
- end
-
- def test_invalid_database_option_raises_an_error
- content = capture(:stderr){ run_generator([destination_root, "-d", "unknown"]) }
- assert_match /Invalid value for \-\-database option/, content
- end
-
def test_invalid_application_name_raises_an_error
content = capture(:stderr){ run_generator [File.join(destination_root, "43-things")] }
assert_equal "Invalid application name 43-things. Please give a name which does not start with numbers.\n", content
end
- def test_application_name_raises_an_error_if_name_already_used_constant
- %w{ String Hash Class Module Set Symbol }.each do |ruby_class|
- content = capture(:stderr){ run_generator [File.join(destination_root, ruby_class)] }
- assert_equal "Invalid application name #{ruby_class}, constant #{ruby_class} is already in use. Please choose another application name.\n", content
- end
- end
-
def test_invalid_application_name_is_fixed
run_generator [File.join(destination_root, "things-43")]
assert_file "things-43/config/environment.rb", /Things43::Application\.initialize!/
@@ -133,11 +83,11 @@ class AppGeneratorTest < Rails::Generators::TestCase
assert_file "myapp_moved/config/environment.rb", /Myapp::Application\.initialize!/
assert_file "myapp_moved/config/initializers/session_store.rb", /_myapp_session/
end
-
+
def test_rails_update_generates_correct_session_key
app_root = File.join(destination_root, 'myapp')
run_generator [app_root]
-
+
Rails.application.config.root = app_root
Rails.application.class.stubs(:name).returns("Myapp")
Rails.application.stubs(:is_a?).returns(Rails::Application)
@@ -188,23 +138,28 @@ class AppGeneratorTest < Rails::Generators::TestCase
assert_file "test"
end
- def test_prototype_and_test_unit_are_skipped_if_required
- run_generator [destination_root, "--skip-prototype", "--skip-test-unit"]
+ def test_javascript_is_skipped_if_required
+ run_generator [destination_root, "--skip-javascript"]
assert_file "config/application.rb", /^\s+config\.action_view\.javascript_expansions\[:defaults\]\s+=\s+%w\(\)/
assert_file "public/javascripts/application.js"
assert_no_file "public/javascripts/prototype.js"
assert_no_file "public/javascripts/rails.js"
- assert_no_file "test"
end
- def test_shebang_is_added_to_rails_file
- run_generator [destination_root, "--ruby", "foo/bar/baz"]
- assert_file "script/rails", /#!foo\/bar\/baz/
+ def test_config_prototype_javascript_library
+ run_generator [destination_root, "-j", "prototype"]
+ assert_file "config/application.rb", /#\s+config\.action_view\.javascript_expansions\[:defaults\]\s+=\s+%w\(jquery rails\)/
+ assert_file "public/javascripts/application.js"
+ assert_file "public/javascripts/prototype.js"
+ assert_file "public/javascripts/rails.js", /prototype/
end
- def test_shebang_when_is_the_same_as_default_use_env
- run_generator [destination_root, "--ruby", Thor::Util.ruby_command]
- assert_file "script/rails", /#!\/usr\/bin\/env/
+ def test_config_jquery_javascript_library
+ run_generator [destination_root, "-j", "jquery"]
+ assert_file "config/application.rb", /^\s+config\.action_view\.javascript_expansions\[:defaults\]\s+=\s+%w\(jquery rails\)/
+ assert_file "public/javascripts/application.js"
+ assert_file "public/javascripts/jquery.js"
+ assert_file "public/javascripts/rails.js", /jQuery/
end
def test_template_from_dir_pwd
@@ -212,21 +167,6 @@ class AppGeneratorTest < Rails::Generators::TestCase
assert_match /It works from file!/, run_generator([destination_root, "-m", "lib/template.rb"])
end
- def test_template_raises_an_error_with_invalid_path
- content = capture(:stderr){ run_generator([destination_root, "-m", "non/existant/path"]) }
- assert_match /The template \[.*\] could not be loaded/, content
- assert_match /non\/existant\/path/, content
- end
-
- def test_template_is_executed_when_supplied
- path = "http://gist.github.com/103208.txt"
- template = %{ say "It works!" }
- template.instance_eval "def read; self; end" # Make the string respond to read
-
- generator([destination_root], :template => path).expects(:open).with(path, 'Accept' => 'application/x-thor-template').returns(template)
- assert_match /It works!/, silence(:stdout){ generator.invoke_all }
- end
-
def test_usage_read_from_file
File.expects(:read).returns("USAGE FROM FILE")
assert_equal "USAGE FROM FILE", Rails::Generators::AppGenerator.desc
@@ -246,17 +186,11 @@ class AppGeneratorTest < Rails::Generators::TestCase
assert_file 'lib/test_file.rb', 'heres test data'
end
- def test_dev_option
- generator([destination_root], :dev => true).expects(:run).with("#{@bundle_command} install")
- silence(:stdout){ generator.invoke_all }
- rails_path = File.expand_path('../../..', Rails.root)
- assert_file 'Gemfile', /^gem\s+["']rails["'],\s+:path\s+=>\s+["']#{Regexp.escape(rails_path)}["']$/
- end
-
- def test_edge_option
- generator([destination_root], :edge => true).expects(:run).with("#{@bundle_command} install")
- silence(:stdout){ generator.invoke_all }
- assert_file 'Gemfile', /^gem\s+["']rails["'],\s+:git\s+=>\s+["']#{Regexp.escape("git://github.com/rails/rails.git")}["']$/
+ def test_test_unit_is_removed_from_frameworks_if_skip_test_unit_is_given
+ run_generator [destination_root, "--skip-test-unit"]
+ assert_file "config/application.rb" do |file|
+ assert_match /config.generators.test_framework = false/, file
+ end
end
protected
@@ -272,62 +206,21 @@ class CustomAppGeneratorTest < Rails::Generators::TestCase
tests Rails::Generators::AppGenerator
arguments [destination_root]
+ include SharedCustomGeneratorTests
- def setup
- Rails.application = TestApp::Application
- super
- Rails::Generators::AppGenerator.instance_variable_set('@desc', nil)
- @bundle_command = File.basename(Thor::Util.ruby_command).sub(/ruby/, 'bundle')
- end
-
- def teardown
- super
- Rails::Generators::AppGenerator.instance_variable_set('@desc', nil)
- Object.class_eval { remove_const :AppBuilder if const_defined?(:AppBuilder) }
- Rails.application = TestApp::Application.instance
- end
-
- def test_builder_option_with_empty_app_builder
- FileUtils.cd(Rails.root)
- run_generator([destination_root, "-b", "#{Rails.root}/lib/empty_builder.rb"])
- DEFAULT_APP_FILES.each{ |path| assert_no_file path }
- end
-
- def test_builder_option_with_simple_app_builder
- FileUtils.cd(Rails.root)
- run_generator([destination_root, "-b", "#{Rails.root}/lib/simple_builder.rb"])
- (DEFAULT_APP_FILES - ['config.ru']).each{ |path| assert_no_file path }
- assert_file "config.ru", %[run proc { |env| [200, { "Content-Type" => "text/html" }, ["Hello World"]] }]
- end
-
- def test_builder_option_with_relative_path
- here = File.expand_path(File.dirname(__FILE__))
- FileUtils.cd(here)
- run_generator([destination_root, "-b", "../fixtures/lib/simple_builder.rb"])
- (DEFAULT_APP_FILES - ['config.ru']).each{ |path| assert_no_file path }
- assert_file "config.ru", %[run proc { |env| [200, { "Content-Type" => "text/html" }, ["Hello World"]] }]
+protected
+ def default_files
+ ::DEFAULT_APP_FILES
end
- def test_builder_option_with_tweak_app_builder
- FileUtils.cd(Rails.root)
- run_generator([destination_root, "-b", "#{Rails.root}/lib/tweak_builder.rb"])
- DEFAULT_APP_FILES.each{ |path| assert_file path }
- assert_file "config.ru", %[run proc { |env| [200, { "Content-Type" => "text/html" }, ["Hello World"]] }]
+ def builders_dir
+ "app_builders"
end
- def test_builder_option_with_http
- path = "http://gist.github.com/103208.txt"
- template = "class AppBuilder; end"
- template.instance_eval "def read; self; end" # Make the string respond to read
-
- generator([destination_root], :builder => path).expects(:open).with(path, 'Accept' => 'application/x-thor-template').returns(template)
- capture(:stdout) { generator.invoke_all }
-
- DEFAULT_APP_FILES.each{ |path| assert_no_file path }
+ def builder_class
+ :AppBuilder
end
-protected
-
def action(*args, &block)
silence(:stdout){ generator.send(*args, &block) }
end
diff --git a/railties/test/generators/migration_generator_test.rb b/railties/test/generators/migration_generator_test.rb
index f9d1e42d24..288ec30460 100644
--- a/railties/test/generators/migration_generator_test.rb
+++ b/railties/test/generators/migration_generator_test.rb
@@ -34,12 +34,12 @@ class MigrationGeneratorTest < Rails::Generators::TestCase
run_generator [migration, "title:string", "body:text"]
assert_migration "db/migrate/#{migration}.rb" do |content|
- assert_class_method :up, content do |up|
+ assert_method :up, content do |up|
assert_match /add_column :posts, :title, :string/, up
assert_match /add_column :posts, :body, :text/, up
end
- assert_class_method :down, content do |down|
+ assert_method :down, content do |down|
assert_match /remove_column :posts, :title/, down
assert_match /remove_column :posts, :body/, down
end
@@ -51,12 +51,12 @@ class MigrationGeneratorTest < Rails::Generators::TestCase
run_generator [migration, "title:string", "body:text"]
assert_migration "db/migrate/#{migration}.rb" do |content|
- assert_class_method :up, content do |up|
+ assert_method :up, content do |up|
assert_match /remove_column :posts, :title/, up
assert_match /remove_column :posts, :body/, up
end
- assert_class_method :down, content do |down|
+ assert_method :down, content do |down|
assert_match /add_column :posts, :title, :string/, down
assert_match /add_column :posts, :body, :text/, down
end
@@ -68,11 +68,11 @@ class MigrationGeneratorTest < Rails::Generators::TestCase
run_generator [migration, "title:string", "content:text"]
assert_migration "db/migrate/#{migration}.rb" do |content|
- assert_class_method :up, content do |up|
+ assert_method :up, content do |up|
assert_match /^\s*$/, up
end
- assert_class_method :down, content do |down|
+ assert_method :down, content do |down|
assert_match /^\s*$/, down
end
end
diff --git a/railties/test/generators/model_generator_test.rb b/railties/test/generators/model_generator_test.rb
index 52e08cf2dd..8a0f560bc8 100644
--- a/railties/test/generators/model_generator_test.rb
+++ b/railties/test/generators/model_generator_test.rb
@@ -99,13 +99,13 @@ class ModelGeneratorTest < Rails::Generators::TestCase
run_generator ["product", "name:string", "supplier_id:integer"]
assert_migration "db/migrate/create_products.rb" do |m|
- assert_class_method :up, m do |up|
+ assert_method :up, m do |up|
assert_match /create_table :products/, up
assert_match /t\.string :name/, up
assert_match /t\.integer :supplier_id/, up
end
- assert_class_method :down, m do |down|
+ assert_method :down, m do |down|
assert_match /drop_table :products/, down
end
end
@@ -141,7 +141,7 @@ class ModelGeneratorTest < Rails::Generators::TestCase
run_generator ["account", "--no-timestamps"]
assert_migration "db/migrate/create_accounts.rb" do |m|
- assert_class_method :up, m do |up|
+ assert_method :up, m do |up|
assert_no_match /t.timestamps/, up
end
end
diff --git a/railties/test/generators/namespaced_generators_test.rb b/railties/test/generators/namespaced_generators_test.rb
index d1190fd17d..d61a02d32f 100644
--- a/railties/test/generators/namespaced_generators_test.rb
+++ b/railties/test/generators/namespaced_generators_test.rb
@@ -3,6 +3,7 @@ require 'rails/generators/rails/controller/controller_generator'
require 'rails/generators/rails/model/model_generator'
require 'rails/generators/rails/observer/observer_generator'
require 'rails/generators/mailer/mailer_generator'
+require 'rails/generators/rails/scaffold/scaffold_generator'
class NamespacedGeneratorTestCase < Rails::Generators::TestCase
def setup
@@ -202,3 +203,155 @@ class NamespacedMailerGeneratorTest < NamespacedGeneratorTestCase
assert_file "app/views/test_app/notifier"
end
end
+
+class NamespacedScaffoldGeneratorTest < NamespacedGeneratorTestCase
+ include GeneratorsTestHelper
+ arguments %w(product_line title:string price:integer)
+ tests Rails::Generators::ScaffoldGenerator
+
+ setup :copy_routes
+
+ def test_scaffold_on_invoke
+ run_generator
+
+ # Model
+ assert_file "app/models/test_app/product_line.rb", /module TestApp\n class ProductLine < ActiveRecord::Base/
+ assert_file "test/unit/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"
+
+ # Route
+ assert_file "config/routes.rb" do |route|
+ assert_match(/resources :product_lines$/, route)
+ end
+
+ # Controller
+ assert_file "app/controllers/test_app/product_lines_controller.rb" do |content|
+ assert_match(/module TestApp\n class ProductLinesController < ApplicationController/, content)
+ end
+
+ assert_file "test/functional/test_app/product_lines_controller_test.rb",
+ /module TestApp\n class ProductLinesControllerTest < ActionController::TestCase/
+
+ # Views
+ %w(
+ index
+ edit
+ new
+ show
+ _form
+ ).each { |view| assert_file "app/views/test_app/product_lines/#{view}.html.erb" }
+ assert_no_file "app/views/layouts/test_app/product_lines.html.erb"
+
+ # Helpers
+ assert_file "app/helpers/test_app/product_lines_helper.rb"
+ assert_file "test/unit/helpers/test_app/product_lines_helper_test.rb"
+
+ # Stylesheets
+ assert_file "public/stylesheets/scaffold.css"
+ end
+
+ def test_scaffold_on_revoke
+ run_generator
+ run_generator ["product_line"], :behavior => :revoke
+
+ # Model
+ assert_no_file "app/models/test_app/product_line.rb"
+ assert_no_file "test/unit/test_app/product_line_test.rb"
+ assert_no_file "test/fixtures/test_app/product_lines.yml"
+ assert_no_migration "db/migrate/create_test_app_product_lines.rb"
+
+ # Route
+ assert_file "config/routes.rb" do |route|
+ assert_no_match(/resources :product_lines$/, route)
+ end
+
+ # Controller
+ assert_no_file "app/controllers/test_app/product_lines_controller.rb"
+ assert_no_file "test/functional/test_app/product_lines_controller_test.rb"
+
+ # Views
+ assert_no_file "app/views/test_app/product_lines"
+ assert_no_file "app/views/test_app/layouts/product_lines.html.erb"
+
+ # Helpers
+ assert_no_file "app/helpers/test_app/product_lines_helper.rb"
+ assert_no_file "test/unit/helpers/test_app/product_lines_helper_test.rb"
+
+ # Stylesheets (should not be removed)
+ assert_file "public/stylesheets/scaffold.css"
+ end
+
+ def test_scaffold_with_namespace_on_invoke
+ run_generator [ "admin/role", "name:string", "description:string" ]
+
+ # 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 "test/unit/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"
+
+ # Route
+ assert_file "config/routes.rb" do |route|
+ assert_match(/namespace :admin do resources :roles end$/, route)
+ end
+
+ # Controller
+ assert_file "app/controllers/test_app/admin/roles_controller.rb" do |content|
+ assert_match(/module TestApp\n class Admin::RolesController < ApplicationController/, content)
+ end
+
+ assert_file "test/functional/test_app/admin/roles_controller_test.rb",
+ /module TestApp\n class Admin::RolesControllerTest < ActionController::TestCase/
+
+ # Views
+ %w(
+ index
+ edit
+ new
+ show
+ _form
+ ).each { |view| assert_file "app/views/test_app/admin/roles/#{view}.html.erb" }
+ assert_no_file "app/views/layouts/admin/roles.html.erb"
+
+ # Helpers
+ assert_file "app/helpers/test_app/admin/roles_helper.rb"
+ assert_file "test/unit/helpers/test_app/admin/roles_helper_test.rb"
+
+ # Stylesheets
+ assert_file "public/stylesheets/scaffold.css"
+ end
+
+ def test_scaffold_with_namespace_on_revoke
+ run_generator [ "admin/role", "name:string", "description:string" ]
+ run_generator [ "admin/role" ], :behavior => :revoke
+
+ # Model
+ assert_file "app/models/test_app/admin.rb" # ( should not be remove )
+ assert_no_file "app/models/test_app/admin/role.rb"
+ assert_no_file "test/unit/test_app/admin/role_test.rb"
+ assert_no_file "test/fixtures/test_app/admin/roles.yml"
+ assert_no_migration "db/migrate/create_test_app_admin_roles.rb"
+
+ # Route
+ assert_file "config/routes.rb" do |route|
+ assert_no_match(/namespace :admin do resources :roles end$/, route)
+ end
+
+ # Controller
+ assert_no_file "app/controllers/test_app/admin/roles_controller.rb"
+ assert_no_file "test/functional/test_app/admin/roles_controller_test.rb"
+
+ # Views
+ assert_no_file "app/views/test_app/admin/roles"
+ assert_no_file "app/views/layouts/test_app/admin/roles.html.erb"
+
+ # Helpers
+ assert_no_file "app/helpers/test_app/admin/roles_helper.rb"
+ assert_no_file "test/unit/helpers/test_app/admin/roles_helper_test.rb"
+
+ # Stylesheets (should not be removed)
+ assert_file "public/stylesheets/scaffold.css"
+ end
+end
diff --git a/railties/test/generators/plugin_generator_test.rb b/railties/test/generators/plugin_generator_test.rb
index c1f646f7c1..e6686a6af4 100644
--- a/railties/test/generators/plugin_generator_test.rb
+++ b/railties/test/generators/plugin_generator_test.rb
@@ -6,7 +6,7 @@ class PluginGeneratorTest < Rails::Generators::TestCase
arguments %w(plugin_fu)
def test_plugin_skeleton_is_created
- run_generator
+ silence(:stderr) { run_generator }
year = Date.today.year
%w(
@@ -36,30 +36,36 @@ class PluginGeneratorTest < Rails::Generators::TestCase
end
def test_invokes_default_test_framework
- run_generator
+ silence(:stderr) { run_generator }
assert_file "vendor/plugins/plugin_fu/test/plugin_fu_test.rb", /class PluginFuTest < ActiveSupport::TestCase/
assert_file "vendor/plugins/plugin_fu/test/test_helper.rb"
end
def test_logs_if_the_test_framework_cannot_be_found
- content = run_generator ["plugin_fu", "--test-framework=rspec"]
+ content = nil
+ silence(:stderr) { content = run_generator ["plugin_fu", "--test-framework=rspec"] }
assert_match /rspec \[not found\]/, content
end
def test_creates_tasks_if_required
- run_generator ["plugin_fu", "--tasks"]
+ silence(:stderr) { run_generator ["plugin_fu", "--tasks"] }
assert_file "vendor/plugins/plugin_fu/lib/tasks/plugin_fu_tasks.rake"
end
def test_creates_generator_if_required
- run_generator ["plugin_fu", "--generator"]
+ silence(:stderr) { run_generator ["plugin_fu", "--generator"] }
assert_file "vendor/plugins/plugin_fu/lib/generators/templates"
assert_file "vendor/plugins/plugin_fu/lib/generators/plugin_fu_generator.rb",
/class PluginFuGenerator < Rails::Generators::NamedBase/
end
def test_plugin_generator_on_revoke
- run_generator
+ silence(:stderr) { run_generator }
run_generator ["plugin_fu"], :behavior => :revoke
end
+
+ def test_deprecation
+ output = capture(:stderr) { run_generator }
+ assert_match /Plugin generator is deprecated, please use 'rails plugin new' command to generate plugin structure./, output
+ end
end
diff --git a/railties/test/generators/plugin_new_generator_test.rb b/railties/test/generators/plugin_new_generator_test.rb
new file mode 100644
index 0000000000..2105585272
--- /dev/null
+++ b/railties/test/generators/plugin_new_generator_test.rb
@@ -0,0 +1,196 @@
+require 'abstract_unit'
+require 'generators/generators_test_helper'
+require 'rails/generators/rails/plugin_new/plugin_new_generator'
+require 'generators/shared_generator_tests.rb'
+
+DEFAULT_PLUGIN_FILES = %w(
+ .gitignore
+ Gemfile
+ Rakefile
+ bukkits.gemspec
+ MIT-LICENSE
+ lib
+ lib/bukkits.rb
+ lib/tasks/bukkits_tasks.rake
+ script/rails
+ test/bukkits_test.rb
+ test/test_helper.rb
+ test/dummy
+)
+
+class PluginNewGeneratorTest < Rails::Generators::TestCase
+ include GeneratorsTestHelper
+ destination File.join(Rails.root, "tmp/bukkits")
+ arguments [destination_root]
+ include SharedGeneratorTests
+
+ def default_files
+ ::DEFAULT_PLUGIN_FILES
+ end
+
+ def test_invalid_plugin_name_raises_an_error
+ content = capture(:stderr){ run_generator [File.join(destination_root, "43-things")] }
+ assert_equal "Invalid plugin name 43-things. Please give a name which does not start with numbers.\n", content
+ end
+
+ def test_invalid_plugin_name_is_fixed
+ run_generator [File.join(destination_root, "things-43")]
+ assert_file "things-43/lib/things-43.rb", /module Things43/
+ end
+
+ def test_generating_test_files
+ run_generator
+ assert_file "test/test_helper.rb"
+ assert_file "test/bukkits_test.rb", /assert_kind_of Module, Bukkits/
+ end
+
+ def test_generating_test_files_in_full_mode
+ run_generator [destination_root, "--full"]
+ assert_directory "test/integration/"
+
+ assert_file "test/integration/navigation_test.rb", /ActionDispatch::IntegrationTest/
+ end
+
+ def test_ensure_that_plugin_options_are_not_passed_to_app_generator
+ FileUtils.cd(Rails.root)
+ assert_no_match /It works from file!.*It works_from_file/, run_generator([destination_root, "-m", "lib/template.rb"])
+ end
+
+ def test_ensure_that_test_dummy_can_be_generated_from_a_template
+ FileUtils.cd(Rails.root)
+ run_generator([destination_root, "-m", "lib/create_test_dummy_template.rb", "--skip-test-unit"])
+ assert_file "spec/dummy"
+ assert_no_file "test"
+ end
+
+ def test_database_entry_is_assed_by_default_in_full_mode
+ run_generator([destination_root, "--full"])
+ assert_file "test/dummy/config/database.yml", /sqlite/
+ assert_file "Gemfile", /^gem\s+["']sqlite3-ruby["'],\s+:require\s+=>\s+["']sqlite3["']$/
+ end
+
+ def test_config_another_database
+ run_generator([destination_root, "-d", "mysql", "--full"])
+ assert_file "test/dummy/config/database.yml", /mysql/
+ assert_file "Gemfile", /^gem\s+["']mysql2["']$/
+ end
+
+ def test_active_record_is_removed_from_frameworks_if_skip_active_record_is_given
+ run_generator [destination_root, "--skip-active-record"]
+ assert_file "test/dummy/config/application.rb", /#\s+require\s+["']active_record\/railtie["']/
+ end
+
+ def test_ensure_that_skip_active_record_option_is_passed_to_app_generator
+ run_generator [destination_root, "--skip_active_record"]
+ assert_no_file "test/dummy/config/database.yml"
+ assert_no_match /ActiveRecord/, File.read(File.join(destination_root, "test/test_helper.rb"))
+ end
+
+ def test_ensure_that_database_option_is_passed_to_app_generator
+ run_generator [destination_root, "--database", "postgresql"]
+ assert_file "test/dummy/config/database.yml", /postgres/
+ end
+
+ def test_ensure_that_javascript_option_is_passed_to_app_generator
+ run_generator [destination_root, "--javascript", "jquery"]
+ assert_file "test/dummy/public/javascripts/jquery.js"
+ end
+
+ def test_ensure_that_skip_javascript_option_is_passed_to_app_generator
+ run_generator [destination_root, "--skip_javascript"]
+ assert_no_file "test/dummy/public/javascripts/prototype.js"
+ end
+
+ def test_template_from_dir_pwd
+ FileUtils.cd(Rails.root)
+ assert_match /It works from file!/, run_generator([destination_root, "-m", "lib/template.rb"])
+ end
+
+ def test_ensure_that_tests_works
+ run_generator
+ FileUtils.cd destination_root
+ `bundle install`
+ assert_match /1 tests, 1 assertions, 0 failures, 0 errors/, `bundle exec rake test`
+ end
+
+ def test_ensure_that_tests_works_in_full_mode
+ run_generator [destination_root, "--full"]
+ FileUtils.cd destination_root
+ `bundle install`
+ assert_match /2 tests, 2 assertions, 0 failures, 0 errors/, `bundle exec rake test`
+ end
+
+ def test_creating_engine_in_full_mode
+ run_generator [destination_root, "--full"]
+ assert_file "lib/bukkits/engine.rb", /module Bukkits\n class Engine < Rails::Engine\n end\nend/
+ assert_file "lib/bukkits.rb", /require "bukkits\/engine"/
+ end
+
+ def test_being_quiet_while_creating_dummy_application
+ assert_no_match /create\s+config\/application.rb/, run_generator
+ end
+
+ def test_create_mountable_application_with_mountable_option
+ run_generator [destination_root, "--mountable"]
+ assert_file "config/routes.rb", /Bukkits::Engine.routes.draw do/
+ assert_file "lib/bukkits/engine.rb", /isolate_namespace Bukkits/
+ assert_file "test/dummy/config/routes.rb", /mount Bukkits::Engine => "\/bukkits"/
+ assert_file "app/controllers/bukkits/application_controller.rb", /module Bukkits\n class ApplicationController < ActionController::Base/
+ assert_file "app/helpers/bukkits/application_helper.rb", /module Bukkits\n module ApplicationHelper/
+ end
+
+ def test_passing_dummy_path_as_a_parameter
+ run_generator [destination_root, "--dummy_path", "spec/dummy"]
+ assert_file "spec/dummy"
+ assert_file "spec/dummy/config/application.rb"
+ assert_no_file "test/dummy"
+ end
+
+ def test_skipping_gemspec
+ run_generator [destination_root, "--skip-gemspec"]
+ assert_no_file "bukkits.gemspec"
+ end
+
+protected
+
+ def action(*args, &block)
+ silence(:stdout){ generator.send(*args, &block) }
+ end
+
+end
+
+class CustomPluginGeneratorTest < Rails::Generators::TestCase
+ include GeneratorsTestHelper
+ tests Rails::Generators::PluginNewGenerator
+
+ destination File.join(Rails.root, "tmp/bukkits")
+ arguments [destination_root]
+ include SharedCustomGeneratorTests
+
+ def test_overriding_test_framework
+ FileUtils.cd(destination_root)
+ run_generator([destination_root, "-b", "#{Rails.root}/lib/plugin_builders/spec_builder.rb"])
+ assert_file 'spec/spec_helper.rb'
+ assert_file 'spec/dummy'
+ assert_file 'Rakefile', /task :default => :spec/
+ assert_file 'Rakefile', /# spec tasks in rakefile/
+ assert_file 'script/rails', %r{spec/dummy}
+ end
+
+protected
+ def default_files
+ ::DEFAULT_PLUGIN_FILES
+ end
+
+ def builder_class
+ :PluginBuilder
+ end
+
+ def builders_dir
+ "plugin_builders"
+ end
+
+ def action(*args, &block)
+ silence(:stdout){ generator.send(*args, &block) }
+ end
+end
diff --git a/railties/test/generators/resource_generator_test.rb b/railties/test/generators/resource_generator_test.rb
index 55d5bd6f83..71b3619351 100644
--- a/railties/test/generators/resource_generator_test.rb
+++ b/railties/test/generators/resource_generator_test.rb
@@ -73,6 +73,11 @@ class ResourceGeneratorTest < Rails::Generators::TestCase
assert_no_match /Plural version of the model detected/, content
end
+ def test_mass_nouns_do_not_throw_warnings
+ content = run_generator ["sheep".freeze]
+ assert_no_match /Plural version of the model detected/, content
+ end
+
def test_route_is_removed_on_revoke
run_generator
run_generator ["account"], :behavior => :revoke
diff --git a/railties/test/generators/shared_generator_tests.rb b/railties/test/generators/shared_generator_tests.rb
new file mode 100644
index 0000000000..d117656fbd
--- /dev/null
+++ b/railties/test/generators/shared_generator_tests.rb
@@ -0,0 +1,187 @@
+module SharedGeneratorTests
+ def setup
+ Rails.application = TestApp::Application
+ super
+ Rails::Generators::AppGenerator.instance_variable_set('@desc', nil)
+ @bundle_command = File.basename(Thor::Util.ruby_command).sub(/ruby/, 'bundle')
+
+ Kernel::silence_warnings do
+ Thor::Base.shell.send(:attr_accessor, :always_force)
+ @shell = Thor::Base.shell.new
+ @shell.send(:always_force=, true)
+ end
+ end
+
+ def teardown
+ super
+ Rails::Generators::AppGenerator.instance_variable_set('@desc', nil)
+ Rails.application = TestApp::Application.instance
+ end
+
+ def test_skeleton_is_created
+ run_generator
+
+ default_files.each{ |path| assert_file path }
+ end
+
+ def test_plugin_new_generate_pretend
+ run_generator ["testapp", "--pretend"]
+
+ default_files.each{ |path| assert_no_file path }
+ end
+
+ def test_invalid_database_option_raises_an_error
+ content = capture(:stderr){ run_generator([destination_root, "-d", "unknown"]) }
+ assert_match /Invalid value for \-\-database option/, content
+ end
+
+ def test_test_unit_is_skipped_if_required
+ run_generator [destination_root, "--skip-test-unit"]
+ assert_no_file "test"
+ end
+
+ def test_options_before_application_name_raises_an_error
+ content = capture(:stderr){ run_generator(["--pretend", destination_root]) }
+ assert_match /Options should be given after the \w+ name. For details run: rails( plugin)? --help\n/, content
+ end
+
+ def test_name_collision_raises_an_error
+ reserved_words = %w[application destroy plugin runner test]
+ reserved_words.each do |reserved|
+ content = capture(:stderr){ run_generator [File.join(destination_root, reserved)] }
+ assert_match /Invalid \w+ name #{reserved}. Please give a name which does not match one of the reserved rails words.\n/, content
+ end
+ end
+
+ def test_name_raises_an_error_if_name_already_used_constant
+ %w{ String Hash Class Module Set Symbol }.each do |ruby_class|
+ content = capture(:stderr){ run_generator [File.join(destination_root, ruby_class)] }
+ assert_match /Invalid \w+ name #{ruby_class}, constant #{ruby_class} is already in use. Please choose another \w+ name.\n/, content
+ end
+ end
+
+ def test_shebang_is_added_to_rails_file
+ run_generator [destination_root, "--ruby", "foo/bar/baz"]
+ assert_file "script/rails", /#!foo\/bar\/baz/
+ end
+
+ def test_shebang_when_is_the_same_as_default_use_env
+ run_generator [destination_root, "--ruby", Thor::Util.ruby_command]
+ assert_file "script/rails", /#!\/usr\/bin\/env/
+ end
+
+ def test_template_raises_an_error_with_invalid_path
+ content = capture(:stderr){ run_generator([destination_root, "-m", "non/existant/path"]) }
+ assert_match /The template \[.*\] could not be loaded/, content
+ assert_match /non\/existant\/path/, content
+ end
+
+ def test_template_is_executed_when_supplied
+ path = "http://gist.github.com/103208.txt"
+ template = %{ say "It works!" }
+ template.instance_eval "def read; self; end" # Make the string respond to read
+
+ generator([destination_root], :template => path).expects(:open).with(path, 'Accept' => 'application/x-thor-template').returns(template)
+ assert_match /It works!/, silence(:stdout){ generator.invoke_all }
+ end
+
+ def test_dev_option
+ generator([destination_root], :dev => true).expects(:run).with("#{@bundle_command} install")
+ silence(:stdout){ generator.invoke_all }
+ rails_path = File.expand_path('../../..', Rails.root)
+ assert_file 'Gemfile', /^gem\s+["']rails["'],\s+:path\s+=>\s+["']#{Regexp.escape(rails_path)}["']$/
+ end
+
+ def test_edge_option
+ generator([destination_root], :edge => true).expects(:run).with("#{@bundle_command} install")
+ silence(:stdout){ generator.invoke_all }
+ assert_file 'Gemfile', %r{^gem\s+["']rails["'],\s+:git\s+=>\s+["']#{Regexp.escape("git://github.com/rails/rails.git")}["']$}
+ end
+
+ def test_template_raises_an_error_with_invalid_path
+ content = capture(:stderr){ run_generator([destination_root, "-m", "non/existant/path"]) }
+ assert_match /The template \[.*\] could not be loaded/, content
+ assert_match /non\/existant\/path/, content
+ end
+
+ def test_template_is_executed_when_supplied
+ path = "http://gist.github.com/103208.txt"
+ template = %{ say "It works!" }
+ template.instance_eval "def read; self; end" # Make the string respond to read
+
+ generator([destination_root], :template => path).expects(:open).with(path, 'Accept' => 'application/x-thor-template').returns(template)
+ assert_match /It works!/, silence(:stdout){ generator.invoke_all }
+ end
+
+ def test_dev_option
+ generator([destination_root], :dev => true).expects(:run).with("#{@bundle_command} install")
+ silence(:stdout){ generator.invoke_all }
+ rails_path = File.expand_path('../../..', Rails.root)
+ assert_file 'Gemfile', /^gem\s+["']rails["'],\s+:path\s+=>\s+["']#{Regexp.escape(rails_path)}["']$/
+ end
+
+ def test_edge_option
+ generator([destination_root], :edge => true).expects(:run).with("#{@bundle_command} install")
+ silence(:stdout){ generator.invoke_all }
+ assert_file 'Gemfile', %r{^gem\s+["']rails["'],\s+:git\s+=>\s+["']#{Regexp.escape("git://github.com/rails/rails.git")}["']$}
+ end
+end
+
+module SharedCustomGeneratorTests
+ def setup
+ Rails.application = TestApp::Application
+ super
+ Rails::Generators::AppGenerator.instance_variable_set('@desc', nil)
+ @bundle_command = File.basename(Thor::Util.ruby_command).sub(/ruby/, 'bundle')
+ end
+
+ def teardown
+ super
+ Rails::Generators::AppGenerator.instance_variable_set('@desc', nil)
+ Object.class_eval do
+ remove_const :AppBuilder if const_defined?(:AppBuilder)
+ remove_const :PluginBuilder if const_defined?(:PluginBuilder)
+ end
+ Rails.application = TestApp::Application.instance
+ end
+
+ def test_builder_option_with_empty_app_builder
+ FileUtils.cd(destination_root)
+ run_generator([destination_root, "-b", "#{Rails.root}/lib/#{builders_dir}/empty_builder.rb"])
+ default_files.each{ |path| assert_no_file path }
+ end
+
+ def test_builder_option_with_simple_plugin_builder
+ FileUtils.cd(destination_root)
+ run_generator([destination_root, "-b", "#{Rails.root}/lib/#{builders_dir}/simple_builder.rb"])
+ (default_files - ['.gitignore']).each{ |path| assert_no_file path }
+ assert_file ".gitignore", "foobar"
+ end
+
+ def test_builder_option_with_relative_path
+ here = File.expand_path(File.dirname(__FILE__))
+ FileUtils.cd(here)
+ run_generator([destination_root, "-b", "../fixtures/lib/#{builders_dir}/simple_builder.rb"])
+ FileUtils.cd(destination_root)
+ (default_files - ['.gitignore']).each{ |path| assert_no_file path }
+ assert_file ".gitignore", "foobar"
+ end
+
+ def test_builder_option_with_tweak_plugin_builder
+ FileUtils.cd(destination_root)
+ run_generator([destination_root, "-b", "#{Rails.root}/lib/#{builders_dir}/tweak_builder.rb"])
+ default_files.each{ |path| assert_file path }
+ assert_file ".gitignore", "foobar"
+ end
+
+ def test_builder_option_with_http
+ path = "http://gist.github.com/103208.txt"
+ template = "class #{builder_class}; end"
+ template.instance_eval "def read; self; end" # Make the string respond to read
+
+ generator([destination_root], :builder => path).expects(:open).with(path, 'Accept' => 'application/x-thor-template').returns(template)
+ capture(:stdout) { generator.invoke_all }
+
+ default_files.each{ |path| assert_no_file path }
+ end
+end
diff --git a/railties/test/generators_test.rb b/railties/test/generators_test.rb
index f93800a5ae..346c9ceb9d 100644
--- a/railties/test/generators_test.rb
+++ b/railties/test/generators_test.rb
@@ -102,6 +102,12 @@ class GeneratorsTest < Rails::Generators::TestCase
assert_no_match /^ app$/, output
end
+ def test_rails_generators_help_does_not_include_app_nor_plugin_new
+ output = capture(:stdout){ Rails::Generators.help }
+ assert_no_match /app/, output
+ assert_no_match /plugin_new/, output
+ end
+
def test_rails_generators_with_others_information
output = capture(:stdout){ Rails::Generators.help }
assert_match /Fixjour:/, output
diff --git a/railties/test/railties/engine_test.rb b/railties/test/railties/engine_test.rb
index db74e41472..7548c6318e 100644
--- a/railties/test/railties/engine_test.rb
+++ b/railties/test/railties/engine_test.rb
@@ -224,32 +224,14 @@ module RailtiesTest
end
RUBY
- @plugin.write "app/views/foo/index.html.erb", <<-RUBY
- <%= compute_public_path("/foo", "") %>
+ @plugin.write "app/views/foo/index.html.erb", <<-ERB
<%= image_path("foo.png") %>
<%= javascript_include_tag("foo") %>
<%= stylesheet_link_tag("foo") %>
- RUBY
-
-
- app_file "app/controllers/bar_controller.rb", <<-RUBY
- class BarController < ActionController::Base
- def index
- render :index
- end
- end
- RUBY
-
- app_file "app/views/bar/index.html.erb", <<-RUBY
- <%= compute_public_path("/foo", "") %>
- RUBY
+ ERB
add_to_config 'config.asset_path = "/omg%s"'
- @plugin.write 'public/touch.txt', <<-RUBY
- touch
- RUBY
-
boot_rails
# should set asset_path with engine name by default
@@ -259,11 +241,10 @@ module RailtiesTest
env = Rack::MockRequest.env_for("/foo")
response = Bukkits::Engine.call(env)
- stripped_body = response[2].body.split("\n").map(&:strip).join("\n")
+ stripped_body = response[2].body.split("\n").map(&:strip).join
- expected = "/omg/bukkits/foo\n" +
- "/omg/bukkits/images/foo.png\n" +
- "<script src=\"/omg/bukkits/javascripts/foo.js\" type=\"text/javascript\"></script>\n" +
+ expected = "/omg/bukkits/images/foo.png" +
+ "<script src=\"/omg/bukkits/javascripts/foo.js\" type=\"text/javascript\"></script>" +
"<link href=\"/omg/bukkits/stylesheets/foo.css\" media=\"screen\" rel=\"stylesheet\" type=\"text/css\" />"
assert_equal expected, stripped_body
end
@@ -278,21 +259,18 @@ module RailtiesTest
@plugin.write "app/controllers/foo_controller.rb", <<-RUBY
class FooController < ActionController::Base
def index
+ render :inline => '<%= image_path("foo.png") %>'
end
end
RUBY
- @plugin.write "app/views/foo/index.html.erb", <<-RUBY
- <%= compute_public_path("/foo", "") %>
- RUBY
-
boot_rails
env = Rack::MockRequest.env_for("/foo")
response = Bukkits::Engine.call(env)
stripped_body = response[2].body.strip
- expected = "/bukkits/foo"
+ expected = "/bukkits/images/foo.png"
assert_equal expected, stripped_body
end
@@ -568,63 +546,6 @@ module RailtiesTest
assert rack_body(response[2]) =~ /name="post\[title\]"/
end
- test "creating symlinks" do
- @plugin.write "lib/bukkits.rb", <<-RUBY
- module Bukkits
- class Engine < ::Rails::Engine
- isolate_namespace(Bukkits)
- end
- end
- RUBY
-
- @plugin.write "public/hello.txt", "foo"
- @plugin.write "alternate_public/hello.txt", "bar"
-
- Dir.chdir(app_path) do
- output = `rake railties:create_symlinks`
-
- assert_match /Created symlink/, output
- assert_match /#{app_path}\/public\/bukkits/, output
- assert_match /#{@plugin.path}\/public/, output
-
- assert File.symlink?(File.join(app_path, 'public/bukkits'))
- assert_equal "foo\n", File.read(File.join(app_path, 'public/bukkits/hello.txt'))
-
- @plugin.write "lib/bukkits.rb", <<-RUBY
- module Bukkits
- class Engine < ::Rails::Engine
- isolate_namespace(Bukkits)
- paths["public"] = "#{File.join(@plugin.path, "alternate_public")}"
- end
- end
- RUBY
-
- output = `rake railties:create_symlinks`
-
- assert_match /Created symlink/, output
- assert_match /#{app_path}\/public\/bukkits/, output
- assert_match /#{@plugin.path}\/alternate_public/, output
-
- assert File.symlink?(File.join(app_path, 'public/bukkits'))
- assert_equal "bar\n", File.read(File.join(app_path, 'public/bukkits/hello.txt'))
-
- @plugin.write "lib/bukkits.rb", <<-RUBY
- module Bukkits
- class Engine < ::Rails::Engine
- isolate_namespace(Bukkits)
- paths["public"] = "#{File.join(@plugin.path, "not_existing")}"
- end
- end
- RUBY
-
- FileUtils.rm File.join(app_path, 'public/bukkits')
-
- output = `rake railties:create_symlinks`
- assert_no_match /Created symlink/, output
- assert !File.exist?(File.join(app_path, 'public/bukkits'))
- end
- end
-
test "loading seed data" do
@plugin.write "db/seeds.rb", <<-RUBY
Bukkits::Engine.config.bukkits_seeds_loaded = true
@@ -742,5 +663,44 @@ module RailtiesTest
assert_equal :haml , generators[:template_engine]
assert_equal :rspec , generators[:test_framework]
end
+
+ test "engine should get default generators with ability to overwrite them" do
+ @plugin.write "lib/bukkits.rb", <<-RUBY
+ module Bukkits
+ class Engine < ::Rails::Engine
+ config.generators.test_framework :rspec
+ end
+ end
+ RUBY
+
+ boot_rails
+ require "#{rails_root}/config/environment"
+
+ generators = Bukkits::Engine.config.generators.options[:rails]
+ assert_equal :active_record, generators[:orm]
+ assert_equal :rspec , generators[:test_framework]
+
+ app_generators = Rails.application.config.generators.options[:rails]
+ assert_equal :test_unit , app_generators[:test_framework]
+ end
+
+ test "do not create table_name_prefix method if it already exists" do
+ @plugin.write "lib/bukkits.rb", <<-RUBY
+ module Bukkits
+ def self.table_name_prefix
+ "foo"
+ end
+
+ class Engine < ::Rails::Engine
+ isolate_namespace(Bukkits)
+ end
+ end
+ RUBY
+
+ boot_rails
+ require "#{rails_root}/config/environment"
+
+ assert_equal "foo", Bukkits.table_name_prefix
+ end
end
end
diff --git a/railties/test/railties/shared_tests.rb b/railties/test/railties/shared_tests.rb
index b1d7580dff..31ba2eaca2 100644
--- a/railties/test/railties/shared_tests.rb
+++ b/railties/test/railties/shared_tests.rb
@@ -10,6 +10,44 @@ module RailtiesTest
@app ||= Rails.application
end
+ def test_install_migrations_and_assets
+ @plugin.write "public/javascripts/foo.js", "doSomething()"
+
+ @plugin.write "db/migrate/1_create_users.rb", <<-RUBY
+ class CreateUsers < ActiveRecord::Migration
+ end
+ RUBY
+
+ app_file "db/migrate/1_create_sessions.rb", <<-RUBY
+ class CreateSessions < ActiveRecord::Migration
+ end
+ RUBY
+
+ add_to_config "ActiveRecord::Base.timestamped_migrations = false"
+
+ Dir.chdir(app_path) do
+ `rake bukkits:install`
+ assert File.exists?("#{app_path}/db/migrate/2_create_users.rb")
+ assert File.exists?(app_path("public/bukkits/javascripts/foo.js"))
+ end
+ end
+
+ def test_copying_assets
+ @plugin.write "public/javascripts/foo.js", "doSomething()"
+ @plugin.write "public/stylesheets/foo.css", "h1 { font-size: 10000px }"
+ @plugin.write "public/images/img.png", ""
+
+ Dir.chdir(app_path) do
+ `rake bukkits:install:assets --trace`
+
+ assert File.exists?(app_path("public/bukkits/javascripts/foo.js"))
+ assert_equal "doSomething()\n", File.read(app_path("public/bukkits/javascripts/foo.js"))
+ assert File.exists?(app_path("public/bukkits/stylesheets/foo.css"))
+ assert_equal "h1 { font-size: 10000px }\n", File.read(app_path("public/bukkits/stylesheets/foo.css"))
+ assert File.exists?(app_path("public/bukkits/images/img.png"))
+ end
+ end
+
def test_copying_migrations
@plugin.write "db/migrate/1_create_users.rb", <<-RUBY
class CreateUsers < ActiveRecord::Migration
@@ -43,24 +81,24 @@ module RailtiesTest
add_to_config "ActiveRecord::Base.timestamped_migrations = false"
Dir.chdir(app_path) do
- output = `rake bukkits:install:migrations 2>&1`
+ output = `rake bukkits:install:migrations`
assert File.exists?("#{app_path}/db/migrate/2_create_users.rb")
assert File.exists?("#{app_path}/db/migrate/3_add_last_name_to_users.rb")
assert_match /Copied migration 2_create_users.rb from bukkits/, output
assert_match /Copied migration 3_add_last_name_to_users.rb from bukkits/, output
- assert_match /WARNING: Migration 3_create_sessions.rb from bukkits has been skipped/, output
+ assert_match /NOTE: Migration 3_create_sessions.rb from bukkits has been skipped/, output
assert_equal 3, Dir["#{app_path}/db/migrate/*.rb"].length
- output = `rake railties:install:migrations 2>&1`
+ output = `rake railties:install:migrations`
assert File.exists?("#{app_path}/db/migrate/4_create_yaffles.rb")
- assert_match /WARNING: Migration 3_create_sessions.rb from bukkits has been skipped/, output
+ assert_match /NOTE: Migration 3_create_sessions.rb from bukkits has been skipped/, output
assert_match /Copied migration 4_create_yaffles.rb from acts_as_yaffle/, output
assert_no_match /2_create_users/, output
migrations_count = Dir["#{app_path}/db/migrate/*.rb"].length
- output = `rake railties:install:migrations 2>&1`
+ output = `rake railties:install:migrations`
assert_equal migrations_count, Dir["#{app_path}/db/migrate/*.rb"].length
end