| 1 | efrain | 1 | YUI.add('yui2-stylesheet', function(Y) {
 | 
        
           |  |  | 2 |     var YAHOO    = Y.YUI2;
 | 
        
           |  |  | 3 |     /*
 | 
        
           |  |  | 4 | Copyright (c) 2011, Yahoo! Inc. All rights reserved.
 | 
        
           |  |  | 5 | Code licensed under the BSD License:
 | 
        
           |  |  | 6 | http://developer.yahoo.com/yui/license.html
 | 
        
           |  |  | 7 | version: 2.9.0
 | 
        
           |  |  | 8 | */
 | 
        
           |  |  | 9 | /**
 | 
        
           |  |  | 10 |  * The StyleSheet component is a utility for managing css rules at the
 | 
        
           |  |  | 11 |  * stylesheet level
 | 
        
           |  |  | 12 |  *
 | 
        
           |  |  | 13 |  * @module stylesheet
 | 
        
           |  |  | 14 |  * @namespace YAHOO.util
 | 
        
           |  |  | 15 |  * @requires yahoo
 | 
        
           |  |  | 16 |  */
 | 
        
           |  |  | 17 | (function () {
 | 
        
           |  |  | 18 |   | 
        
           |  |  | 19 | var d      = document,
 | 
        
           |  |  | 20 |     p      = d.createElement('p'), // Have to hold the node (see notes)
 | 
        
           |  |  | 21 |     workerStyle = p.style, // worker style collection
 | 
        
           |  |  | 22 |     lang   = YAHOO.lang,
 | 
        
           |  |  | 23 |     selectors = {},
 | 
        
           |  |  | 24 |     sheets = {},
 | 
        
           |  |  | 25 |     ssId   = 0,
 | 
        
           |  |  | 26 |     floatAttr = ('cssFloat' in workerStyle) ? 'cssFloat' : 'styleFloat',
 | 
        
           |  |  | 27 |     _toCssText,
 | 
        
           |  |  | 28 |     _unsetOpacity,
 | 
        
           |  |  | 29 |     _unsetProperty;
 | 
        
           |  |  | 30 |   | 
        
           |  |  | 31 | /*
 | 
        
           |  |  | 32 |  * Normalizes the removal of an assigned style for opacity.  IE uses the filter property.
 | 
        
           |  |  | 33 |  */
 | 
        
           |  |  | 34 | _unsetOpacity = ('opacity' in workerStyle) ?
 | 
        
           |  |  | 35 |     function (style) { style.opacity = ''; } :
 | 
        
           |  |  | 36 |     function (style) { style.filter = ''; };
 | 
        
           |  |  | 37 |   | 
        
           |  |  | 38 | /*
 | 
        
           |  |  | 39 |  * Normalizes the removal of an assigned style for a given property.  Expands
 | 
        
           |  |  | 40 |  * shortcut properties if necessary and handles the various names for the float property.
 | 
        
           |  |  | 41 |  */
 | 
        
           |  |  | 42 | workerStyle.border = "1px solid red";
 | 
        
           |  |  | 43 | workerStyle.border = ''; // IE doesn't unset child properties
 | 
        
           |  |  | 44 | _unsetProperty = workerStyle.borderLeft ?
 | 
        
           |  |  | 45 |     function (style,prop) {
 | 
        
           |  |  | 46 |         var p;
 | 
        
           |  |  | 47 |         if (prop !== floatAttr && prop.toLowerCase().indexOf('float') != -1) {
 | 
        
           |  |  | 48 |             prop = floatAttr;
 | 
        
           |  |  | 49 |         }
 | 
        
           |  |  | 50 |         if (typeof style[prop] === 'string') {
 | 
        
           |  |  | 51 |             switch (prop) {
 | 
        
           |  |  | 52 |                 case 'opacity':
 | 
        
           |  |  | 53 |                 case 'filter' : _unsetOpacity(style); break;
 | 
        
           |  |  | 54 |                 case 'font'   :
 | 
        
           |  |  | 55 |                     style.font       = style.fontStyle = style.fontVariant =
 | 
        
           |  |  | 56 |                     style.fontWeight = style.fontSize  = style.lineHeight  =
 | 
        
           |  |  | 57 |                     style.fontFamily = '';
 | 
        
           |  |  | 58 |                     break;
 | 
        
           |  |  | 59 |                 default       :
 | 
        
           |  |  | 60 |                     for (p in style) {
 | 
        
           |  |  | 61 |                         if (p.indexOf(prop) === 0) {
 | 
        
           |  |  | 62 |                             style[p] = '';
 | 
        
           |  |  | 63 |                         }
 | 
        
           |  |  | 64 |                     }
 | 
        
           |  |  | 65 |             }
 | 
        
           |  |  | 66 |         }
 | 
        
           |  |  | 67 |     } :
 | 
        
           |  |  | 68 |     function (style,prop) {
 | 
        
           |  |  | 69 |         if (prop !== floatAttr && prop.toLowerCase().indexOf('float') != -1) {
 | 
        
           |  |  | 70 |             prop = floatAttr;
 | 
        
           |  |  | 71 |         }
 | 
        
           |  |  | 72 |         if (lang.isString(style[prop])) {
 | 
        
           |  |  | 73 |             if (prop === 'opacity') {
 | 
        
           |  |  | 74 |                 _unsetOpacity(style);
 | 
        
           |  |  | 75 |             } else {
 | 
        
           |  |  | 76 |                 style[prop] = '';
 | 
        
           |  |  | 77 |             }
 | 
        
           |  |  | 78 |         }
 | 
        
           |  |  | 79 |     };
 | 
        
           |  |  | 80 |   | 
        
           |  |  | 81 | /**
 | 
        
           |  |  | 82 |  * Create an instance of YAHOO.util.StyleSheet to encapsulate a css stylesheet.
 | 
        
           |  |  | 83 |  * The constructor can be called using function or constructor syntax.
 | 
        
           |  |  | 84 |  * <pre><code>var sheet = YAHOO.util.StyleSheet(..);</pre></code>
 | 
        
           |  |  | 85 |  * or
 | 
        
           |  |  | 86 |  * <pre><code>var sheet = new YAHOO.util.StyleSheet(..);</pre></code>
 | 
        
           |  |  | 87 |  *
 | 
        
           |  |  | 88 |  * The first parameter passed can be any of the following things:
 | 
        
           |  |  | 89 |  * <ul>
 | 
        
           |  |  | 90 |  *   <li>The desired string name to register a new empty sheet</li>
 | 
        
           |  |  | 91 |  *   <li>The string name of an existing YAHOO.util.StyleSheet instance</li>
 | 
        
           |  |  | 92 |  *   <li>The unique yuiSSID generated for an existing YAHOO.util.StyleSheet instance</li>
 | 
        
           |  |  | 93 |  *   <li>The id of an existing <code><link></code> or <code><style></code> node</li>
 | 
        
           |  |  | 94 |  *   <li>The node reference for an existing <code><link></code> or <code><style></code> node</li>
 | 
        
           |  |  | 95 |  *   <li>A chunk of css text to create a new stylesheet from</li>
 | 
        
           |  |  | 96 |  * </ul>
 | 
        
           |  |  | 97 |  *
 | 
        
           |  |  | 98 |  * <p>If a string is passed, StyleSheet will first look in its static name
 | 
        
           |  |  | 99 |  * registry for an existing sheet, then in the DOM for an element with that id.
 | 
        
           |  |  | 100 |  * If neither are found and the string contains the { character, it will be
 | 
        
           |  |  | 101 |  * used as a the initial cssText for a new StyleSheet.  Otherwise, a new empty
 | 
        
           |  |  | 102 |  * StyleSheet is created, assigned the string value as a name, and registered
 | 
        
           |  |  | 103 |  * statically by that name.</p>
 | 
        
           |  |  | 104 |  *
 | 
        
           |  |  | 105 |  * <p>The optional second parameter is a string name to register the sheet as.
 | 
        
           |  |  | 106 |  * This param is largely useful when providing a node id/ref or chunk of css
 | 
        
           |  |  | 107 |  * text to create a populated instance.</p>
 | 
        
           |  |  | 108 |  *
 | 
        
           |  |  | 109 |  * @class StyleSheet
 | 
        
           |  |  | 110 |  * @constructor
 | 
        
           |  |  | 111 |  * @param seed {String|<style> element} a style or link node, its id, or a name or
 | 
        
           |  |  | 112 |  *              yuiSSID of a StyleSheet, or a string of css text (see above)
 | 
        
           |  |  | 113 |  * @param name {String} OPTIONAL name to register instance for future static
 | 
        
           |  |  | 114 |  *              access
 | 
        
           |  |  | 115 |  */
 | 
        
           |  |  | 116 | function StyleSheet(seed, name) {
 | 
        
           |  |  | 117 |     var head,
 | 
        
           |  |  | 118 |         node,
 | 
        
           |  |  | 119 |         sheet,
 | 
        
           |  |  | 120 |         cssRules = {},
 | 
        
           |  |  | 121 |         _rules,
 | 
        
           |  |  | 122 |         _insertRule,
 | 
        
           |  |  | 123 |         _deleteRule,
 | 
        
           |  |  | 124 |         i,r,sel;
 | 
        
           |  |  | 125 |   | 
        
           |  |  | 126 |     // Factory or constructor
 | 
        
           |  |  | 127 |     if (!(this instanceof StyleSheet)) {
 | 
        
           |  |  | 128 |         return new StyleSheet(seed,name);
 | 
        
           |  |  | 129 |     }
 | 
        
           |  |  | 130 |   | 
        
           |  |  | 131 |     // capture the DOM node if the string is an id
 | 
        
           |  |  | 132 |     node = seed && (seed.nodeName ? seed : d.getElementById(seed));
 | 
        
           |  |  | 133 |   | 
        
           |  |  | 134 |     // Check for the StyleSheet in the static registry
 | 
        
           |  |  | 135 |     if (seed && sheets[seed]) {
 | 
        
           |  |  | 136 |         return sheets[seed];
 | 
        
           |  |  | 137 |     } else if (node && node.yuiSSID && sheets[node.yuiSSID]) {
 | 
        
           |  |  | 138 |         return sheets[node.yuiSSID];
 | 
        
           |  |  | 139 |     }
 | 
        
           |  |  | 140 |   | 
        
           |  |  | 141 |     // Create a style node if necessary
 | 
        
           |  |  | 142 |     if (!node || !/^(?:style|link)$/i.test(node.nodeName)) {
 | 
        
           |  |  | 143 |         node = d.createElement('style');
 | 
        
           |  |  | 144 |         node.type = 'text/css';
 | 
        
           |  |  | 145 |     }
 | 
        
           |  |  | 146 |   | 
        
           |  |  | 147 |     if (lang.isString(seed)) {
 | 
        
           |  |  | 148 |         // Create entire sheet from seed cssText
 | 
        
           |  |  | 149 |         if (seed.indexOf('{') != -1) {
 | 
        
           |  |  | 150 |             // Not a load-time fork because low run-time impact and IE fails
 | 
        
           |  |  | 151 |             // test for s.styleSheet at page load time (oddly)
 | 
        
           |  |  | 152 |             if (node.styleSheet) {
 | 
        
           |  |  | 153 |                 node.styleSheet.cssText = seed;
 | 
        
           |  |  | 154 |             } else {
 | 
        
           |  |  | 155 |                 node.appendChild(d.createTextNode(seed));
 | 
        
           |  |  | 156 |             }
 | 
        
           |  |  | 157 |         } else if (!name) {
 | 
        
           |  |  | 158 |             name = seed;
 | 
        
           |  |  | 159 |         }
 | 
        
           |  |  | 160 |     }
 | 
        
           |  |  | 161 |   | 
        
           |  |  | 162 |     if (!node.parentNode || node.parentNode.nodeName.toLowerCase() !== 'head') {
 | 
        
           |  |  | 163 |         head = (node.ownerDocument || d).getElementsByTagName('head')[0];
 | 
        
           |  |  | 164 |         // styleSheet isn't available on the style node in FF2 until appended
 | 
        
           |  |  | 165 |         // to the head element.  style nodes appended to body do not affect
 | 
        
           |  |  | 166 |         // change in Safari.
 | 
        
           |  |  | 167 |         head.appendChild(node);
 | 
        
           |  |  | 168 |     }
 | 
        
           |  |  | 169 |   | 
        
           |  |  | 170 |     // Begin setting up private aliases to the important moving parts
 | 
        
           |  |  | 171 |     // 1. The stylesheet object
 | 
        
           |  |  | 172 |     // IE stores StyleSheet under the "styleSheet" property
 | 
        
           |  |  | 173 |     // Safari doesn't populate sheet for xdomain link elements
 | 
        
           |  |  | 174 |     sheet = node.sheet || node.styleSheet;
 | 
        
           |  |  | 175 |   | 
        
           |  |  | 176 |     // 2. The style rules collection
 | 
        
           |  |  | 177 |     // IE stores the rules collection under the "rules" property
 | 
        
           |  |  | 178 |     _rules = sheet && ('cssRules' in sheet) ? 'cssRules' : 'rules';
 | 
        
           |  |  | 179 |   | 
        
           |  |  | 180 |     // 3. The method to remove a rule from the stylesheet
 | 
        
           |  |  | 181 |     // IE supports removeRule
 | 
        
           |  |  | 182 |     _deleteRule = ('deleteRule' in sheet) ?
 | 
        
           |  |  | 183 |         function (i) { sheet.deleteRule(i); } :
 | 
        
           |  |  | 184 |         function (i) { sheet.removeRule(i); };
 | 
        
           |  |  | 185 |   | 
        
           |  |  | 186 |     // 4. The method to add a new rule to the stylesheet
 | 
        
           |  |  | 187 |     // IE supports addRule with different signature
 | 
        
           |  |  | 188 |     _insertRule = ('insertRule' in sheet) ?
 | 
        
           |  |  | 189 |         function (sel,css,i) { sheet.insertRule(sel+' {'+css+'}',i); } :
 | 
        
           |  |  | 190 |         function (sel,css,i) { sheet.addRule(sel,css,i); };
 | 
        
           |  |  | 191 |   | 
        
           |  |  | 192 |     // 5. Initialize the cssRules map from the node
 | 
        
           |  |  | 193 |     // xdomain link nodes forbid access to the cssRules collection, so this
 | 
        
           |  |  | 194 |     // will throw an error.
 | 
        
           |  |  | 195 |     // TODO: research alternate stylesheet, @media
 | 
        
           |  |  | 196 |     for (i = sheet[_rules].length - 1; i >= 0; --i) {
 | 
        
           |  |  | 197 |         r   = sheet[_rules][i];
 | 
        
           |  |  | 198 |         sel = r.selectorText;
 | 
        
           |  |  | 199 |   | 
        
           |  |  | 200 |         if (cssRules[sel]) {
 | 
        
           |  |  | 201 |             cssRules[sel].style.cssText += ';' + r.style.cssText;
 | 
        
           |  |  | 202 |             _deleteRule(i);
 | 
        
           |  |  | 203 |         } else {
 | 
        
           |  |  | 204 |             cssRules[sel] = r;
 | 
        
           |  |  | 205 |         }
 | 
        
           |  |  | 206 |     }
 | 
        
           |  |  | 207 |   | 
        
           |  |  | 208 |     // Cache the instance by the generated Id
 | 
        
           |  |  | 209 |     node.yuiSSID = 'yui-stylesheet-' + (ssId++);
 | 
        
           |  |  | 210 |     StyleSheet.register(node.yuiSSID,this);
 | 
        
           |  |  | 211 |   | 
        
           |  |  | 212 |     // Register the instance by name if provided or defaulted from seed
 | 
        
           |  |  | 213 |     if (name) {
 | 
        
           |  |  | 214 |         StyleSheet.register(name,this);
 | 
        
           |  |  | 215 |     }
 | 
        
           |  |  | 216 |   | 
        
           |  |  | 217 |     // Public API
 | 
        
           |  |  | 218 |     lang.augmentObject(this,{
 | 
        
           |  |  | 219 |         /**
 | 
        
           |  |  | 220 |          * Get the unique yuiSSID for this StyleSheet instance
 | 
        
           |  |  | 221 |          *
 | 
        
           |  |  | 222 |          * @method getId
 | 
        
           |  |  | 223 |          * @return {Number} the static id
 | 
        
           |  |  | 224 |          */
 | 
        
           |  |  | 225 |         getId : function () { return node.yuiSSID; },
 | 
        
           |  |  | 226 |   | 
        
           |  |  | 227 |         /**
 | 
        
           |  |  | 228 |          * The <style> element that this instance encapsulates
 | 
        
           |  |  | 229 |          *
 | 
        
           |  |  | 230 |          * @property node
 | 
        
           |  |  | 231 |          * @type HTMLElement
 | 
        
           |  |  | 232 |          */
 | 
        
           |  |  | 233 |         node : node,
 | 
        
           |  |  | 234 |   | 
        
           |  |  | 235 |         /**
 | 
        
           |  |  | 236 |          * Enable all the rules in the sheet
 | 
        
           |  |  | 237 |          *
 | 
        
           |  |  | 238 |          * @method enable
 | 
        
           |  |  | 239 |          * @return {StyleSheet} the instance
 | 
        
           |  |  | 240 |          * @chainable
 | 
        
           |  |  | 241 |          */
 | 
        
           |  |  | 242 |         // Enabling/disabling the stylesheet.  Changes may be made to rules
 | 
        
           |  |  | 243 |         // while disabled.
 | 
        
           |  |  | 244 |         enable : function () { sheet.disabled = false; return this; },
 | 
        
           |  |  | 245 |   | 
        
           |  |  | 246 |         /**
 | 
        
           |  |  | 247 |          * Disable all the rules in the sheet.  Rules may be changed while the
 | 
        
           |  |  | 248 |          * StyleSheet is disabled.
 | 
        
           |  |  | 249 |          *
 | 
        
           |  |  | 250 |          * @method disable
 | 
        
           |  |  | 251 |          * @return {StyleSheet} the instance
 | 
        
           |  |  | 252 |          * @chainable
 | 
        
           |  |  | 253 |          */
 | 
        
           |  |  | 254 |         disable : function () { sheet.disabled = true; return this; },
 | 
        
           |  |  | 255 |   | 
        
           |  |  | 256 |         /**
 | 
        
           |  |  | 257 |          * Returns boolean indicating whether the StyleSheet is enabled
 | 
        
           |  |  | 258 |          *
 | 
        
           |  |  | 259 |          * @method isEnabled
 | 
        
           |  |  | 260 |          * @return {Boolean} is it enabled?
 | 
        
           |  |  | 261 |          */
 | 
        
           |  |  | 262 |         isEnabled : function () { return !sheet.disabled; },
 | 
        
           |  |  | 263 |   | 
        
           |  |  | 264 |         /**
 | 
        
           |  |  | 265 |          * <p>Set style properties for a provided selector string.
 | 
        
           |  |  | 266 |          * If the selector includes commas, it will be split into individual
 | 
        
           |  |  | 267 |          * selectors and applied accordingly.  If the selector string does not
 | 
        
           |  |  | 268 |          * have a corresponding rule in the sheet, it will be added.</p>
 | 
        
           |  |  | 269 |          *
 | 
        
           |  |  | 270 |          * <p>The second parameter can be either a string of CSS text,
 | 
        
           |  |  | 271 |          * formatted as CSS ("font-size: 10px;"), or an object collection of
 | 
        
           |  |  | 272 |          * properties and their new values.  Object properties must be in
 | 
        
           |  |  | 273 |          * JavaScript format ({ fontSize: "10px" }).</p>
 | 
        
           |  |  | 274 |          *
 | 
        
           |  |  | 275 |          * <p>The float style property will be set by any of "float",
 | 
        
           |  |  | 276 |          * "styleFloat", or "cssFloat" if passed in the
 | 
        
           |  |  | 277 |          * object map.  Use "float: left;" format when passing a CSS text
 | 
        
           |  |  | 278 |          * string.</p>
 | 
        
           |  |  | 279 |          *
 | 
        
           |  |  | 280 |          * @method set
 | 
        
           |  |  | 281 |          * @param sel {String} the selector string to apply the changes to
 | 
        
           |  |  | 282 |          * @param css {Object|String} Object literal of style properties and
 | 
        
           |  |  | 283 |          *                      new values, or a string of cssText
 | 
        
           |  |  | 284 |          * @return {StyleSheet} the StyleSheet instance
 | 
        
           |  |  | 285 |          * @chainable
 | 
        
           |  |  | 286 |          */
 | 
        
           |  |  | 287 |         set : function (sel,css) {
 | 
        
           |  |  | 288 |             var rule = cssRules[sel],
 | 
        
           |  |  | 289 |                 multi = sel.split(/\s*,\s*/),i,
 | 
        
           |  |  | 290 |                 idx;
 | 
        
           |  |  | 291 |   | 
        
           |  |  | 292 |             // IE's addRule doesn't support multiple comma delimited selectors
 | 
        
           |  |  | 293 |             if (multi.length > 1) {
 | 
        
           |  |  | 294 |                 for (i = multi.length - 1; i >= 0; --i) {
 | 
        
           |  |  | 295 |                     this.set(multi[i], css);
 | 
        
           |  |  | 296 |                 }
 | 
        
           |  |  | 297 |                 return this;
 | 
        
           |  |  | 298 |             }
 | 
        
           |  |  | 299 |   | 
        
           |  |  | 300 |             // Some selector values can cause IE to hang
 | 
        
           |  |  | 301 |             if (!StyleSheet.isValidSelector(sel)) {
 | 
        
           |  |  | 302 |                 YAHOO.log("Invalid selector '"+sel+"' passed to set (ignoring).",'warn','StyleSheet');
 | 
        
           |  |  | 303 |                 return this;
 | 
        
           |  |  | 304 |             }
 | 
        
           |  |  | 305 |   | 
        
           |  |  | 306 |             // Opera throws an error if there's a syntax error in assigned
 | 
        
           |  |  | 307 |             // cssText. Avoid this using a worker style collection, then
 | 
        
           |  |  | 308 |             // assigning the resulting cssText.
 | 
        
           |  |  | 309 |             if (rule) {
 | 
        
           |  |  | 310 |                 rule.style.cssText = StyleSheet.toCssText(css,rule.style.cssText);
 | 
        
           |  |  | 311 |             } else {
 | 
        
           |  |  | 312 |                 idx = sheet[_rules].length;
 | 
        
           |  |  | 313 |                 css = StyleSheet.toCssText(css);
 | 
        
           |  |  | 314 |   | 
        
           |  |  | 315 |                 // IE throws an error when attempting to addRule(sel,'',n)
 | 
        
           |  |  | 316 |                 // which would crop up if no, or only invalid values are used
 | 
        
           |  |  | 317 |                 if (css) {
 | 
        
           |  |  | 318 |                     _insertRule(sel, css, idx);
 | 
        
           |  |  | 319 |   | 
        
           |  |  | 320 |                     // Safari replaces the rules collection, but maintains the
 | 
        
           |  |  | 321 |                     // rule instances in the new collection when rules are
 | 
        
           |  |  | 322 |                     // added/removed
 | 
        
           |  |  | 323 |                     cssRules[sel] = sheet[_rules][idx];
 | 
        
           |  |  | 324 |                 }
 | 
        
           |  |  | 325 |             }
 | 
        
           |  |  | 326 |             return this;
 | 
        
           |  |  | 327 |         },
 | 
        
           |  |  | 328 |   | 
        
           |  |  | 329 |         /**
 | 
        
           |  |  | 330 |          * <p>Unset style properties for a provided selector string, removing
 | 
        
           |  |  | 331 |          * their effect from the style cascade.</p>
 | 
        
           |  |  | 332 |          *
 | 
        
           |  |  | 333 |          * <p>If the selector includes commas, it will be split into individual
 | 
        
           |  |  | 334 |          * selectors and applied accordingly.  If there are no properties
 | 
        
           |  |  | 335 |          * remaining in the rule after unsetting, the rule is removed.</p>
 | 
        
           |  |  | 336 |          *
 | 
        
           |  |  | 337 |          * <p>The style property or properties in the second parameter must be the
 | 
        
           |  |  | 338 |          * <p>JavaScript style property names. E.g. fontSize rather than font-size.</p>
 | 
        
           |  |  | 339 |          *
 | 
        
           |  |  | 340 |          * <p>The float style property will be unset by any of "float",
 | 
        
           |  |  | 341 |          * "styleFloat", or "cssFloat".</p>
 | 
        
           |  |  | 342 |          *
 | 
        
           |  |  | 343 |          * @method unset
 | 
        
           |  |  | 344 |          * @param sel {String} the selector string to apply the changes to
 | 
        
           |  |  | 345 |          * @param css {String|Array} style property name or Array of names
 | 
        
           |  |  | 346 |          * @return {StyleSheet} the StyleSheet instance
 | 
        
           |  |  | 347 |          * @chainable
 | 
        
           |  |  | 348 |          */
 | 
        
           |  |  | 349 |         unset : function (sel,css) {
 | 
        
           |  |  | 350 |             var rule = cssRules[sel],
 | 
        
           |  |  | 351 |                 multi = sel.split(/\s*,\s*/),
 | 
        
           |  |  | 352 |                 remove = !css,
 | 
        
           |  |  | 353 |                 rules, i;
 | 
        
           |  |  | 354 |   | 
        
           |  |  | 355 |             // IE's addRule doesn't support multiple comma delimited selectors
 | 
        
           |  |  | 356 |             // so rules are mapped internally by atomic selectors
 | 
        
           |  |  | 357 |             if (multi.length > 1) {
 | 
        
           |  |  | 358 |                 for (i = multi.length - 1; i >= 0; --i) {
 | 
        
           |  |  | 359 |                     this.unset(multi[i], css);
 | 
        
           |  |  | 360 |                 }
 | 
        
           |  |  | 361 |                 return this;
 | 
        
           |  |  | 362 |             }
 | 
        
           |  |  | 363 |   | 
        
           |  |  | 364 |             if (rule) {
 | 
        
           |  |  | 365 |                 if (!remove) {
 | 
        
           |  |  | 366 |                     if (!lang.isArray(css)) {
 | 
        
           |  |  | 367 |                         css = [css];
 | 
        
           |  |  | 368 |                     }
 | 
        
           |  |  | 369 |   | 
        
           |  |  | 370 |                     workerStyle.cssText = rule.style.cssText;
 | 
        
           |  |  | 371 |                     for (i = css.length - 1; i >= 0; --i) {
 | 
        
           |  |  | 372 |                         _unsetProperty(workerStyle,css[i]);
 | 
        
           |  |  | 373 |                     }
 | 
        
           |  |  | 374 |   | 
        
           |  |  | 375 |                     if (workerStyle.cssText) {
 | 
        
           |  |  | 376 |                         rule.style.cssText = workerStyle.cssText;
 | 
        
           |  |  | 377 |                     } else {
 | 
        
           |  |  | 378 |                         remove = true;
 | 
        
           |  |  | 379 |                     }
 | 
        
           |  |  | 380 |                 }
 | 
        
           |  |  | 381 |   | 
        
           |  |  | 382 |                 if (remove) { // remove the rule altogether
 | 
        
           |  |  | 383 |                     rules = sheet[_rules];
 | 
        
           |  |  | 384 |                     for (i = rules.length - 1; i >= 0; --i) {
 | 
        
           |  |  | 385 |                         if (rules[i] === rule) {
 | 
        
           |  |  | 386 |                             delete cssRules[sel];
 | 
        
           |  |  | 387 |                             _deleteRule(i);
 | 
        
           |  |  | 388 |                             break;
 | 
        
           |  |  | 389 |                         }
 | 
        
           |  |  | 390 |                     }
 | 
        
           |  |  | 391 |                 }
 | 
        
           |  |  | 392 |             }
 | 
        
           |  |  | 393 |             return this;
 | 
        
           |  |  | 394 |         },
 | 
        
           |  |  | 395 |   | 
        
           |  |  | 396 |         /**
 | 
        
           |  |  | 397 |          * Get the current cssText for a rule or the entire sheet.  If the
 | 
        
           |  |  | 398 |          * selector param is supplied, only the cssText for that rule will be
 | 
        
           |  |  | 399 |          * returned, if found.  If the selector string targets multiple
 | 
        
           |  |  | 400 |          * selectors separated by commas, the cssText of the first rule only
 | 
        
           |  |  | 401 |          * will be returned.  If no selector string, the stylesheet's full
 | 
        
           |  |  | 402 |          * cssText will be returned.
 | 
        
           |  |  | 403 |          *
 | 
        
           |  |  | 404 |          * @method getCssText
 | 
        
           |  |  | 405 |          * @param sel {String} Selector string
 | 
        
           |  |  | 406 |          * @return {String}
 | 
        
           |  |  | 407 |          */
 | 
        
           |  |  | 408 |         getCssText : function (sel) {
 | 
        
           |  |  | 409 |             var rule, css, selector;
 | 
        
           |  |  | 410 |   | 
        
           |  |  | 411 |             if (lang.isString(sel)) {
 | 
        
           |  |  | 412 |                 // IE's addRule doesn't support multiple comma delimited
 | 
        
           |  |  | 413 |                 // selectors so rules are mapped internally by atomic selectors
 | 
        
           |  |  | 414 |                 rule = cssRules[sel.split(/\s*,\s*/)[0]];
 | 
        
           |  |  | 415 |   | 
        
           |  |  | 416 |                 return rule ? rule.style.cssText : null;
 | 
        
           |  |  | 417 |             } else {
 | 
        
           |  |  | 418 |                 css = [];
 | 
        
           |  |  | 419 |                 for (selector in cssRules) {
 | 
        
           |  |  | 420 |                     if (cssRules.hasOwnProperty(selector)) {
 | 
        
           |  |  | 421 |                         rule = cssRules[selector];
 | 
        
           |  |  | 422 |                         css.push(rule.selectorText+" {"+rule.style.cssText+"}");
 | 
        
           |  |  | 423 |                     }
 | 
        
           |  |  | 424 |                 }
 | 
        
           |  |  | 425 |                 return css.join("\n");
 | 
        
           |  |  | 426 |             }
 | 
        
           |  |  | 427 |         }
 | 
        
           |  |  | 428 |     },true);
 | 
        
           |  |  | 429 |   | 
        
           |  |  | 430 | }
 | 
        
           |  |  | 431 |   | 
        
           |  |  | 432 | _toCssText = function (css,base) {
 | 
        
           |  |  | 433 |     var f = css.styleFloat || css.cssFloat || css['float'],
 | 
        
           |  |  | 434 |         prop;
 | 
        
           |  |  | 435 |   | 
        
           |  |  | 436 |     // A very difficult to repro/isolate IE 9 beta (and Platform Preview 7) bug
 | 
        
           |  |  | 437 |     // was reduced to this line throwing the error:
 | 
        
           |  |  | 438 |     // "Invalid this pointer used as target for method call"
 | 
        
           |  |  | 439 |     // It appears that the style collection is corrupted. The error is
 | 
        
           |  |  | 440 |     // catchable, so in a best effort to work around it, replace the
 | 
        
           |  |  | 441 |     // p and workerStyle and try the assignment again.
 | 
        
           |  |  | 442 |     try {
 | 
        
           |  |  | 443 |         workerStyle.cssText = base || '';
 | 
        
           |  |  | 444 |     } catch (ex) {
 | 
        
           |  |  | 445 |         YAHOO.log("Worker style collection corrupted. Replacing.", "warn", "StyleSheet");
 | 
        
           |  |  | 446 |         p = d.createElement('p');
 | 
        
           |  |  | 447 |         workerStyle = p.style;
 | 
        
           |  |  | 448 |         workerStyle.cssText = base || '';
 | 
        
           |  |  | 449 |     }
 | 
        
           |  |  | 450 |   | 
        
           |  |  | 451 |     if (lang.isString(css)) {
 | 
        
           |  |  | 452 |         // There is a danger here of incremental memory consumption in Opera
 | 
        
           |  |  | 453 |         workerStyle.cssText += ';' + css;
 | 
        
           |  |  | 454 |     } else {
 | 
        
           |  |  | 455 |         if (f && !css[floatAttr]) {
 | 
        
           |  |  | 456 |             css = lang.merge(css);
 | 
        
           |  |  | 457 |             delete css.styleFloat; delete css.cssFloat; delete css['float'];
 | 
        
           |  |  | 458 |             css[floatAttr] = f;
 | 
        
           |  |  | 459 |         }
 | 
        
           |  |  | 460 |   | 
        
           |  |  | 461 |         for (prop in css) {
 | 
        
           |  |  | 462 |             if (css.hasOwnProperty(prop)) {
 | 
        
           |  |  | 463 |                 try {
 | 
        
           |  |  | 464 |                     // IE throws Invalid Value errors and doesn't like whitespace
 | 
        
           |  |  | 465 |                     // in values ala ' red' or 'red '
 | 
        
           |  |  | 466 |                     workerStyle[prop] = lang.trim(css[prop]);
 | 
        
           |  |  | 467 |                 }
 | 
        
           |  |  | 468 |                 catch (e) {
 | 
        
           |  |  | 469 |                     YAHOO.log('Error assigning property "'+prop+'" to "'+css[prop]+
 | 
        
           |  |  | 470 |                               "\" (ignored):\n"+e.message,'warn','StyleSheet');
 | 
        
           |  |  | 471 |                 }
 | 
        
           |  |  | 472 |             }
 | 
        
           |  |  | 473 |         }
 | 
        
           |  |  | 474 |     }
 | 
        
           |  |  | 475 |   | 
        
           |  |  | 476 |     return workerStyle.cssText;
 | 
        
           |  |  | 477 | };
 | 
        
           |  |  | 478 |   | 
        
           |  |  | 479 | lang.augmentObject(StyleSheet, {
 | 
        
           |  |  | 480 |     /**
 | 
        
           |  |  | 481 |      * <p>Converts an object literal of style properties and values into a string
 | 
        
           |  |  | 482 |      * of css text.  This can then be assigned to el.style.cssText.</p>
 | 
        
           |  |  | 483 |      *
 | 
        
           |  |  | 484 |      * <p>The optional second parameter is a cssText string representing the
 | 
        
           |  |  | 485 |      * starting state of the style prior to alterations.  This is most often
 | 
        
           |  |  | 486 |      * extracted from the eventual target's current el.style.cssText.</p>
 | 
        
           |  |  | 487 |      *
 | 
        
           |  |  | 488 |      * @method StyleSheet.toCssText
 | 
        
           |  |  | 489 |      * @param css {Object} object literal of style properties and values
 | 
        
           |  |  | 490 |      * @param cssText {String} OPTIONAL starting cssText value
 | 
        
           |  |  | 491 |      * @return {String} the resulting cssText string
 | 
        
           |  |  | 492 |      * @static
 | 
        
           |  |  | 493 |      */
 | 
        
           |  |  | 494 |     toCssText : (('opacity' in workerStyle) ? _toCssText :
 | 
        
           |  |  | 495 |         // Wrap IE's toCssText to catch opacity.  The copy/merge is to preserve
 | 
        
           |  |  | 496 |         // the input object's integrity, but if float and opacity are set, the
 | 
        
           |  |  | 497 |         // input will be copied twice in IE.  Is there a way to avoid this
 | 
        
           |  |  | 498 |         // without increasing the byte count?
 | 
        
           |  |  | 499 |         function (css, cssText) {
 | 
        
           |  |  | 500 |             if (lang.isObject(css) && 'opacity' in css) {
 | 
        
           |  |  | 501 |                 css = lang.merge(css,{
 | 
        
           |  |  | 502 |                         filter: 'alpha(opacity='+(css.opacity*100)+')'
 | 
        
           |  |  | 503 |                       });
 | 
        
           |  |  | 504 |                 delete css.opacity;
 | 
        
           |  |  | 505 |             }
 | 
        
           |  |  | 506 |             return _toCssText(css,cssText);
 | 
        
           |  |  | 507 |         }),
 | 
        
           |  |  | 508 |   | 
        
           |  |  | 509 |     /**
 | 
        
           |  |  | 510 |      * Registers a StyleSheet instance in the static registry by the given name
 | 
        
           |  |  | 511 |      *
 | 
        
           |  |  | 512 |      * @method StyleSheet.register
 | 
        
           |  |  | 513 |      * @param name {String} the name to assign the StyleSheet in the registry
 | 
        
           |  |  | 514 |      * @param sheet {StyleSheet} The StyleSheet instance
 | 
        
           |  |  | 515 |      * @return {Boolean} false if no name or sheet is not a StyleSheet
 | 
        
           |  |  | 516 |      *              instance. true otherwise.
 | 
        
           |  |  | 517 |      * @static
 | 
        
           |  |  | 518 |      */
 | 
        
           |  |  | 519 |     register : function (name,sheet) {
 | 
        
           |  |  | 520 |         return !!(name && sheet instanceof StyleSheet &&
 | 
        
           |  |  | 521 |                   !sheets[name] && (sheets[name] = sheet));
 | 
        
           |  |  | 522 |     },
 | 
        
           |  |  | 523 |   | 
        
           |  |  | 524 |     /**
 | 
        
           |  |  | 525 |      * <p>Determines if a selector string is safe to use.  Used internally
 | 
        
           |  |  | 526 |      * in set to prevent IE from locking up when attempting to add a rule for a
 | 
        
           |  |  | 527 |      * "bad selector".</p>
 | 
        
           |  |  | 528 |      *
 | 
        
           |  |  | 529 |      * <p>Bad selectors are considered to be any string containing unescaped
 | 
        
           |  |  | 530 |      * `~!@$%^&()+=|{}[];'"?< or space. Also forbidden are . or # followed by
 | 
        
           |  |  | 531 |      * anything other than an alphanumeric.  Additionally -abc or .-abc or
 | 
        
           |  |  | 532 |      * #_abc or '# ' all fail.  There are likely more failure cases, so
 | 
        
           |  |  | 533 |      * please file a bug if you encounter one.</p>
 | 
        
           |  |  | 534 |      *
 | 
        
           |  |  | 535 |      * @method StyleSheet.isValidSelector
 | 
        
           |  |  | 536 |      * @param sel {String} the selector string
 | 
        
           |  |  | 537 |      * @return {Boolean}
 | 
        
           |  |  | 538 |      * @static
 | 
        
           |  |  | 539 |      */
 | 
        
           |  |  | 540 |     isValidSelector : function (sel) {
 | 
        
           |  |  | 541 |         var valid = false;
 | 
        
           |  |  | 542 |   | 
        
           |  |  | 543 |         if (sel && lang.isString(sel)) {
 | 
        
           |  |  | 544 |   | 
        
           |  |  | 545 |             if (!selectors.hasOwnProperty(sel)) {
 | 
        
           |  |  | 546 |                 // TEST: there should be nothing but white-space left after
 | 
        
           |  |  | 547 |                 // these destructive regexs
 | 
        
           |  |  | 548 |                 selectors[sel] = !/\S/.test(
 | 
        
           |  |  | 549 |                     // combinators
 | 
        
           |  |  | 550 |                     sel.replace(/\s+|\s*[+~>]\s*/g,' ').
 | 
        
           |  |  | 551 |                     // attribute selectors (contents not validated)
 | 
        
           |  |  | 552 |                     replace(/([^ ])\[.*?\]/g,'$1').
 | 
        
           |  |  | 553 |                     // pseudo-class|element selectors (contents of parens
 | 
        
           |  |  | 554 |                     // such as :nth-of-type(2) or :not(...) not validated)
 | 
        
           |  |  | 555 |                     replace(/([^ ])::?[a-z][a-z\-]+[a-z](?:\(.*?\))?/ig,'$1').
 | 
        
           |  |  | 556 |                     // element tags
 | 
        
           |  |  | 557 |                     replace(/(?:^| )[a-z0-6]+/ig,' ').
 | 
        
           |  |  | 558 |                     // escaped characters
 | 
        
           |  |  | 559 |                     replace(/\\./g,'').
 | 
        
           |  |  | 560 |                     // class and id identifiers
 | 
        
           |  |  | 561 |                     replace(/[.#]\w[\w\-]*/g,''));
 | 
        
           |  |  | 562 |             }
 | 
        
           |  |  | 563 |   | 
        
           |  |  | 564 |             valid = selectors[sel];
 | 
        
           |  |  | 565 |         }
 | 
        
           |  |  | 566 |   | 
        
           |  |  | 567 |         return valid;
 | 
        
           |  |  | 568 |     }
 | 
        
           |  |  | 569 | },true);
 | 
        
           |  |  | 570 |   | 
        
           |  |  | 571 | YAHOO.util.StyleSheet = StyleSheet;
 | 
        
           |  |  | 572 |   | 
        
           |  |  | 573 | })();
 | 
        
           |  |  | 574 |   | 
        
           |  |  | 575 | /*
 | 
        
           |  |  | 576 |   | 
        
           |  |  | 577 | NOTES
 | 
        
           |  |  | 578 |  * Style node must be added to the head element.  Safari does not honor styles
 | 
        
           |  |  | 579 |    applied to StyleSheet objects on style nodes in the body.
 | 
        
           |  |  | 580 |  * StyleSheet object is created on the style node when the style node is added
 | 
        
           |  |  | 581 |    to the head element in Firefox 2 (and maybe 3?)
 | 
        
           |  |  | 582 |  * The cssRules collection is replaced after insertRule/deleteRule calls in
 | 
        
           |  |  | 583 |    Safari 3.1.  Existing Rules are used in the new collection, so the collection
 | 
        
           |  |  | 584 |    cannot be cached, but the rules can be.
 | 
        
           |  |  | 585 |  * Opera requires that the index be passed with insertRule.
 | 
        
           |  |  | 586 |  * Same-domain restrictions prevent modifying StyleSheet objects attached to
 | 
        
           |  |  | 587 |    link elements with remote href (or "about:blank" or "javascript:false")
 | 
        
           |  |  | 588 |  * Same-domain restrictions prevent reading StyleSheet cssRules/rules
 | 
        
           |  |  | 589 |    collection of link elements with remote href (or "about:blank" or
 | 
        
           |  |  | 590 |    "javascript:false")
 | 
        
           |  |  | 591 |  * Same-domain restrictions result in Safari not populating node.sheet property
 | 
        
           |  |  | 592 |    for link elements with remote href (et.al)
 | 
        
           |  |  | 593 |  * IE names StyleSheet related properties and methods differently (see code)
 | 
        
           |  |  | 594 |  * IE converts tag names to upper case in the Rule's selectorText
 | 
        
           |  |  | 595 |  * IE converts empty string assignment to complex properties to value settings
 | 
        
           |  |  | 596 |    for all child properties.  E.g. style.background = '' sets non-'' values on
 | 
        
           |  |  | 597 |    style.backgroundPosition, style.backgroundColor, etc.  All else clear
 | 
        
           |  |  | 598 |    style.background and all child properties.
 | 
        
           |  |  | 599 |  * IE assignment style.filter = '' will result in style.cssText == 'FILTER:'
 | 
        
           |  |  | 600 |  * All browsers support Rule.style.cssText as a read/write property, leaving
 | 
        
           |  |  | 601 |    only opacity needing to be accounted for.
 | 
        
           |  |  | 602 |  * Benchmarks of style.property = value vs style.cssText += 'property: value'
 | 
        
           |  |  | 603 |    indicate cssText is slightly slower for single property assignment.  For
 | 
        
           |  |  | 604 |    multiple property assignment, cssText speed stays relatively the same where
 | 
        
           |  |  | 605 |    style.property speed decreases linearly by the number of properties set.
 | 
        
           |  |  | 606 |    Exception being Opera 9.27, where style.property is always faster than
 | 
        
           |  |  | 607 |    style.cssText.
 | 
        
           |  |  | 608 |  * Opera 9.5b throws a syntax error when assigning cssText with a syntax error.
 | 
        
           |  |  | 609 |  * Opera 9.5 doesn't honor rule.style.cssText = ''.  Previous style persists.
 | 
        
           |  |  | 610 |    You have to remove the rule altogether.
 | 
        
           |  |  | 611 |  * Stylesheet properties set with !important will trump inline style set on an
 | 
        
           |  |  | 612 |    element or in el.style.property.
 | 
        
           |  |  | 613 |  * Creating a worker style collection like document.createElement('p').style;
 | 
        
           |  |  | 614 |    will fail after a time in FF (~5secs of inactivity).  Property assignments
 | 
        
           |  |  | 615 |    will not alter the property or cssText.  It may be the generated node is
 | 
        
           |  |  | 616 |    garbage collected and the style collection becomes inert (speculation).
 | 
        
           |  |  | 617 |  * IE locks up when attempting to add a rule with a selector including at least
 | 
        
           |  |  | 618 |    characters {[]}~`!@%^&*()+=|? (unescaped) and leading _ or -
 | 
        
           |  |  | 619 |    such as addRule('-foo','{ color: red }') or addRule('._abc','{...}')
 | 
        
           |  |  | 620 |  * IE's addRule doesn't support comma separated selectors such as
 | 
        
           |  |  | 621 |    addRule('.foo, .bar','{..}')
 | 
        
           |  |  | 622 |  * IE throws an error on valid values with leading/trailing white space.
 | 
        
           |  |  | 623 |  * When creating an entire sheet at once, only FF2/3 & Opera allow creating a
 | 
        
           |  |  | 624 |    style node, setting its innerHTML and appending to head.
 | 
        
           |  |  | 625 |  * When creating an entire sheet at once, Safari requires the style node to be
 | 
        
           |  |  | 626 |    created with content in innerHTML of another element.
 | 
        
           |  |  | 627 |  * When creating an entire sheet at once, IE requires the style node content to
 | 
        
           |  |  | 628 |    be set via node.styleSheet.cssText
 | 
        
           |  |  | 629 |  * When creating an entire sheet at once in IE, styleSheet.cssText can't be
 | 
        
           |  |  | 630 |    written until node.type = 'text/css'; is performed.
 | 
        
           |  |  | 631 |  * When creating an entire sheet at once in IE, load-time fork on
 | 
        
           |  |  | 632 |    var styleNode = d.createElement('style'); _method = styleNode.styleSheet ?..
 | 
        
           |  |  | 633 |    fails (falsey).  During run-time, the test for .styleSheet works fine
 | 
        
           |  |  | 634 |  * Setting complex properties in cssText will SOMETIMES allow child properties
 | 
        
           |  |  | 635 |    to be unset
 | 
        
           |  |  | 636 |    set         unset              FF2  FF3  S3.1  IE6  IE7  Op9.27  Op9.5
 | 
        
           |  |  | 637 |    ----------  -----------------  ---  ---  ----  ---  ---  ------  -----
 | 
        
           |  |  | 638 |    border      -top               NO   NO   YES   YES  YES  YES     YES
 | 
        
           |  |  | 639 |                -top-color         NO   NO   YES             YES     YES
 | 
        
           |  |  | 640 |                -color             NO   NO   NO              NO      NO
 | 
        
           |  |  | 641 |    background  -color             NO   NO   YES             YES     YES
 | 
        
           |  |  | 642 |                -position          NO   NO   YES             YES     YES
 | 
        
           |  |  | 643 |                -position-x        NO   NO   NO              NO      NO
 | 
        
           |  |  | 644 |    font        line-height        YES  YES  NO    NO   NO   NO      YES
 | 
        
           |  |  | 645 |                -style             YES  YES  NO              YES     YES
 | 
        
           |  |  | 646 |                -size              YES  YES  NO              YES     YES
 | 
        
           |  |  | 647 |                -size-adjust       ???  ???  n/a   n/a  n/a  ???     ???
 | 
        
           |  |  | 648 |    padding     -top               NO   NO   YES             YES     YES
 | 
        
           |  |  | 649 |    margin      -top               NO   NO   YES             YES     YES
 | 
        
           |  |  | 650 |    list-style  -type              YES  YES  YES             YES     YES
 | 
        
           |  |  | 651 |                -position          YES  YES  YES             YES     YES
 | 
        
           |  |  | 652 |    overflow    -x                 NO   NO   YES             n/a     YES
 | 
        
           |  |  | 653 |   | 
        
           |  |  | 654 |    ??? - unsetting font-size-adjust has the same effect as unsetting font-size
 | 
        
           |  |  | 655 |  * FireFox and WebKit populate rule.cssText as "SELECTOR { CSSTEXT }", but
 | 
        
           |  |  | 656 |    Opera and IE do not.
 | 
        
           |  |  | 657 |  * IE6 and IE7 silently ignore the { and } if passed into addRule('.foo','{
 | 
        
           |  |  | 658 |    color:#000}',0).  IE8 does not and creates an empty rule.
 | 
        
           |  |  | 659 |  * IE6-8 addRule('.foo','',n) throws an error.  Must supply *some* cssText
 | 
        
           |  |  | 660 | */
 | 
        
           |  |  | 661 |   | 
        
           |  |  | 662 | YAHOO.register("stylesheet", YAHOO.util.StyleSheet, {version: "2.9.0", build: "2800"});
 | 
        
           |  |  | 663 |   | 
        
           |  |  | 664 | }, '2.9.0' ,{"requires": ["yui2-yahoo"]});
 |