diff options
Diffstat (limited to 'actionpack/lib/action_dispatch/middleware')
5 files changed, 83 insertions, 70 deletions
diff --git a/actionpack/lib/action_dispatch/middleware/session/cache_store.rb b/actionpack/lib/action_dispatch/middleware/session/cache_store.rb index 625050dc4b..857e49a682 100644 --- a/actionpack/lib/action_dispatch/middleware/session/cache_store.rb +++ b/actionpack/lib/action_dispatch/middleware/session/cache_store.rb @@ -2,12 +2,15 @@ require 'action_dispatch/middleware/session/abstract_store' module ActionDispatch module Session - # Session store that uses an ActiveSupport::Cache::Store to store the sessions. This store is most useful + # A session store that uses an ActiveSupport::Cache::Store to store the sessions. This store is most useful # if you don't store critical data in your sessions and you don't need them to live for extended periods # of time. + # + # ==== Options + # * <tt>cache</tt> - The cache to use. If it is not specified, <tt>Rails.cache</tt> will be used. + # * <tt>expire_after</tt> - The length of time a session will be stored before automatically expiring. + # By default, the <tt>:expires_in</tt> option of the cache is used. class CacheStore < AbstractStore - # Create a new store. The cache to use can be passed in the <tt>:cache</tt> option. If it is - # not specified, <tt>Rails.cache</tt> will be used. def initialize(app, options = {}) @cache = options[:cache] || Rails.cache options[:expire_after] ||= @cache.options[:expires_in] diff --git a/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb b/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb index ed25c67ae5..d8f9614904 100644 --- a/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb +++ b/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb @@ -52,6 +52,16 @@ module ActionDispatch # JavaScript before upgrading. # # Note that changing the secret key will invalidate all existing sessions! + # + # Because CookieStore extends Rack::Session::Abstract::ID, many of the + # options described there can be used to customize the session cookie that + # is generated. For example: + # + # Rails.application.config.session_store :cookie_store, expire_after: 14.days + # + # would set the session cookie to expire automatically 14 days after creation. + # Other useful options include <tt>:key</tt>, <tt>:secure</tt> and + # <tt>:httponly</tt>. class CookieStore < Rack::Session::Abstract::ID include Compatibility include StaleSessionCheck diff --git a/actionpack/lib/action_dispatch/middleware/session/mem_cache_store.rb b/actionpack/lib/action_dispatch/middleware/session/mem_cache_store.rb index b4d6629c35..cb19786f0b 100644 --- a/actionpack/lib/action_dispatch/middleware/session/mem_cache_store.rb +++ b/actionpack/lib/action_dispatch/middleware/session/mem_cache_store.rb @@ -8,6 +8,10 @@ end module ActionDispatch module Session + # A session store that uses MemCache to implement storage. + # + # ==== Options + # * <tt>expire_after</tt> - The length of time a session will be stored before automatically expiring. class MemCacheStore < Rack::Session::Dalli include Compatibility include StaleSessionCheck diff --git a/actionpack/lib/action_dispatch/middleware/templates/routes/_route.html.erb b/actionpack/lib/action_dispatch/middleware/templates/routes/_route.html.erb index 24e44f31ac..6e995c85c1 100644 --- a/actionpack/lib/action_dispatch/middleware/templates/routes/_route.html.erb +++ b/actionpack/lib/action_dispatch/middleware/templates/routes/_route.html.erb @@ -4,13 +4,13 @@ <%= route[:name] %><span class='helper'>_path</span> <% end %> </td> - <td data-route-verb='<%= route[:verb] %>'> + <td> <%= route[:verb] %> </td> - <td data-route-path='<%= route[:path] %>' data-regexp='<%= route[:regexp] %>'> + <td data-route-path='<%= route[:path] %>'> <%= route[:path] %> </td> - <td data-route-reqs='<%= route[:reqs] %>'> - <%= route[:reqs] %> + <td> + <%=simple_format route[:reqs] %> </td> </tr> diff --git a/actionpack/lib/action_dispatch/middleware/templates/routes/_table.html.erb b/actionpack/lib/action_dispatch/middleware/templates/routes/_table.html.erb index 5cee0b5932..429ea7057c 100644 --- a/actionpack/lib/action_dispatch/middleware/templates/routes/_table.html.erb +++ b/actionpack/lib/action_dispatch/middleware/templates/routes/_table.html.erb @@ -81,92 +81,87 @@ </table> <script type='text/javascript'> - // Iterates each element through a function - function each(elems, func) { - if (!elems instanceof Array) { elems = [elems]; } - for (var i = 0, len = elems.length; i < len; i++) { - func(elems[i]); - } - } - - // Sets innerHTML for an element - function setContent(elem, text) { - elem.innerHTML = text; - } + // support forEarch iterator on NodeList + NodeList.prototype.forEach = Array.prototype.forEach; // Enables path search functionality function setupMatchPaths() { - // Check if the user input (sanitized as a path) matches the regexp data attribute - function checkExactMatch(section, elem, value) { - var string = sanitizePath(value), - regexp = elem.getAttribute("data-regexp"); - - showMatch(string, regexp, section, elem); + // Check if there are any matched results in a section + function checkNoMatch(section, noMatchText) { + if (section.children.length <= 1) { + section.innerHTML += noMatchText; + } } - // Check if the route path data attribute contains the user input - function checkFuzzyMatch(section, elem, value) { - var string = elem.getAttribute("data-route-path"), - regexp = value; - - showMatch(string, regexp, section, elem); + // get JSON from url and invoke callback with result + function getJSON(url, success) { + var xhr = new XMLHttpRequest(); + xhr.open('GET', url); + xhr.onload = function() { + if (this.status == 200) + success(JSON.parse(this.response)); + }; + xhr.send(); } - // Display the parent <tr> element in the appropriate section when there's a match - function showMatch(string, regexp, section, elem) { - if(string.match(RegExp(regexp))) { - section.appendChild(elem.parentNode.cloneNode(true)); + function delayedKeyup(input, callback) { + var timeout; + input.onkeyup = function(){ + if (timeout) clearTimeout(timeout); + timeout = setTimeout(callback, 300); } } - // Check if there are any matched results in a section - function checkNoMatch(section, defaultText, noMatchText) { - if (section.innerHTML === defaultText) { - setContent(section, defaultText + noMatchText); - } - } - - // Ensure path always starts with a slash "/" and remove params or fragments + // remove params or fragments function sanitizePath(path) { - var path = path.charAt(0) == '/' ? path : "/" + path; - return path.replace(/\#.*|\?.*/, ''); + return path.replace(/[#?].*/, ''); } - var regexpElems = document.querySelectorAll('#route_table [data-regexp]'), - searchElem = document.querySelector('#search'), - exactMatches = document.querySelector('#exact_matches'), - fuzzyMatches = document.querySelector('#fuzzy_matches'); + var pathElements = document.querySelectorAll('#route_table [data-route-path]'), + searchElem = document.querySelector('#search'), + exactSection = document.querySelector('#exact_matches'), + fuzzySection = document.querySelector('#fuzzy_matches'); // Remove matches when no search value is present searchElem.onblur = function(e) { if (searchElem.value === "") { - setContent(exactMatches, ""); - setContent(fuzzyMatches, ""); + exactSection.innerHTML = ""; + fuzzySection.innerHTML = ""; } } // On key press perform a search for matching paths - searchElem.onkeyup = function(e){ - var userInput = searchElem.value, - defaultExactMatch = '<tr><th colspan="4">Paths Matching (' + escape(sanitizePath(userInput)) +'):</th></tr>', - defaultFuzzyMatch = '<tr><th colspan="4">Paths Containing (' + escape(userInput) +'):</th></tr>', + delayedKeyup(searchElem, function() { + var path = sanitizePath(searchElem.value), + defaultExactMatch = '<tr><th colspan="4">Paths Matching (' + path +'):</th></tr>', + defaultFuzzyMatch = '<tr><th colspan="4">Paths Containing (' + path +'):</th></tr>', noExactMatch = '<tr><th colspan="4">No Exact Matches Found</th></tr>', noFuzzyMatch = '<tr><th colspan="4">No Fuzzy Matches Found</th></tr>'; - // Clear out results section - setContent(exactMatches, defaultExactMatch); - setContent(fuzzyMatches, defaultFuzzyMatch); + if (!path) + return searchElem.onblur(); - // Display exact matches and fuzzy matches - each(regexpElems, function(elem) { - checkExactMatch(exactMatches, elem, userInput); - checkFuzzyMatch(fuzzyMatches, elem, userInput); - }) + getJSON('/rails/info/routes?path=' + path, function(matches){ + // Clear out results section + exactSection.innerHTML = defaultExactMatch; + fuzzySection.innerHTML = defaultFuzzyMatch; - // Display 'No Matches' message when no matches are found - checkNoMatch(exactMatches, defaultExactMatch, noExactMatch); - checkNoMatch(fuzzyMatches, defaultFuzzyMatch, noFuzzyMatch); - } + // Display exact matches and fuzzy matches + pathElements.forEach(function(elem) { + var elemPath = elem.getAttribute('data-route-path'); + + if (matches['exact'].indexOf(elemPath) != -1) + exactSection.appendChild(elem.parentNode.cloneNode(true)); + + if (matches['fuzzy'].indexOf(elemPath) != -1) + fuzzySection.appendChild(elem.parentNode.cloneNode(true)); + }) + + // Display 'No Matches' message when no matches are found + checkNoMatch(exactSection, noExactMatch); + checkNoMatch(fuzzySection, noFuzzyMatch); + }) + }) } // Enables functionality to toggle between `_path` and `_url` helper suffixes @@ -174,19 +169,20 @@ // Sets content for each element function setValOn(elems, val) { - each(elems, function(elem) { - setContent(elem, val); + elems.forEach(function(elem) { + elem.innerHTML = val; }); } // Sets onClick event for each element function onClick(elems, func) { - each(elems, function(elem) { + elems.forEach(function(elem) { elem.onclick = func; }); } var toggleLinks = document.querySelectorAll('#route_table [data-route-helper]'); + onClick(toggleLinks, function(){ var helperTxt = this.getAttribute("data-route-helper"), helperElems = document.querySelectorAll('[data-route-name] span.helper'); |