A plugin based on the css_browser_selector to add the browser type and os to either the body
and/or html
elements within a document. The full usage on how to use these css selectors can be understood at:
http://rafael.adm.br/css_browser_selector/
Major Props to Rafael Lima (from above link) who implemented this JS and has helped me with the plugin.
The initial implementation relies on javascript to place these selectors on the html
element. This plugin will add these selectors to a page regardless of whether or not javascript is enabled.
CssBrowserSelector plugin provides an implementation for body
and html
content_tags, supplying the css_browser_selectors by default. The original javascript is also supplied and can be rendered inline if this is your preference, along with some other helper javascripts.
CssBrowswerSelector is aware of Page Caching and tracks each controller’s caches_page
actions. If the page is cached, CssBrowserSelector will revert to the original javascript only version of css_browser_selector the browser and platform _will not_ be cached into the rendered html. See more in Caching, below.
To add css_browser_selectors to your body tag in your layout (make sure you don’t output the content with +<%= %>+ or you may end up with double content). Do the following:
<% body do %> <%= yield %> <% end %> This will render, depending on your user agent string: <body class="gecko mac"> <div>This is a test</div> </body>
You may pass any html_options as you would expect:
<% body :onload => "alert('yo')" do %> <%= yield %> <% end %>
Renders:
<body class="gecko mac" onload="alert('yo')"> <div>This is a test</div> </body>
Or, if you prefer, you can add the css_browser_selectors to your html tag as first realized in the original javascript.
<% html do %> <head> <title>Example</title> </head> <body> <%= yield %> </body> <% end %>
Renders, by default, with the following attributes (which may be overriden by passing options):
<html class="gecko mac" xmlns="http://www.w3.org/1999/xhtml" xml:lang=>"en" lang=>"en"> <head> <title>Example</title> </head> <body> <div>This is a test</div> </body> </html>
You can use the plugin just to include the original css_browser_selector javascript inline:
<%= javascript_tag css_browser_selector %>
Renders, as you would expect:
<script type="text/javascript"> //<![CDATA[ var css_browser_selector = function() { var ua=navigator.userAgent.toLowerCase(), is=function(t){ return ua.indexOf(t) != -1; }, h=document.getElementsByTagName('html')[0], b=(!(/opera|webtv/i.test(ua))&&/msie (d)/.test(ua))?('ie ie'+RegExp.$1):is('gecko/')? 'gecko':is('opera/9')?'opera opera9':/opera (d)/.test(ua)?'opera opera'+RegExp.$1:is('konqueror')?'konqueror':is('applewebkit/')?'webkit safari':is('mozilla/')?'gecko':'', os=(is('x11')||is('linux'))?' linux':is('mac')?' mac':is('win')?' win':''; var c=b+os+' js'; h.className += h.className?' '+c:c; }(); //]]> </script>
You can pass the css_browser_selector a string or symbol of the tag in which to place the selectors (‘html’ is the default):
<%= javascript_tag css_browser_selector(:body) %>
Changes this line in the script:
h=document.getElementsByTagName('body')[0],
To add the ‘js’ selector to your element, a Page Cache aware helper to include inline javascript is available:
<%= javascript_to_add_js_to :body %>
This will put the following javascript inline:
<script type="text/javascript"> //<![CDATA[ Window.addLoadEvent = function(f){var oldf=window.onload; window.onload=(typeof window.onload!='function')?f:function(){oldf();f();}} Window.addLoadEvent(function(){e=document.getElementsByTagName('body')[0];e.className+=e.className?' js':'js'}) //]]> </script>
This script is included only if the action is not page cached. If the page is cached, the javascript version of css_browser_selector will add the ‘js’ selector to your element. If you want to by-pass this Page Caching awareness you can:
<%= javascript_tag window_on_load_add_js_to_tag(:body) %>
If you enjoy the Window.addLoadEvent
function and wish to use it alone, as a convenience you can:
<%= javascript_tag window_add_load_event %>
For those who wish to use the html
and body
content tags but wish to turn off the css_browser_selectors you can turn them off. For example, if you are using both helpers:
<% html :exclude_browser_and_os => true do %> <head> <title>Example</title> </head> <% body do %> <%= yield %> <% end %> <% end %>
Renders:
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang=>"en" lang=>"en"> <head> <title>Example</title> </head> <body class="gecko mac"> <div>This is a test</div> </body> </html>
CssBrowserSelector keeps track of all the actions that each controller lists in caches_page
in a class attribute called page_cached_actions
. Each controller instance will have a method called page_cached? to determine if the action was listed in caches_page
and honors the perform_caching
configuration.
Currently, it does not keep track of actions cached directly through cache_page
, but could be extended in the future to handle this need. Additionally, it does not track action_caching which could also be added at a later time.
Both the page_cached_action
class variable and page_cached?
instance method are added by the ActionController::CachingTracker
module and can be accessed from anywhere you can get a reference to a controller:
CustomController.page_cached_actions #=> ["new", "show"] controller.page_cached_actions #=> ["new", "show"] controller.page_cached? #=> true if perform_caching is true and is action_name in page_cached_actions
Copyright © 2008 Los Angeles Times (www.latimes.com) released under the MIT license