1 /* See license.txt for terms of usage */
  2 
  3 define([
  4     "firebug/lib/trace",
  5     "firebug/lib/url",
  6     "firebug/lib/options",
  7     "firebug/chrome/window",
  8     "firebug/lib/xml",
  9     "firebug/lib/http",
 10     "firebug/lib/xpath",
 11 ],
 12 function(FBTrace, Url, Options, Win, Xml, Http, Xpath) {
 13 
 14 // ********************************************************************************************* //
 15 // Module Implementation
 16 
 17 /**
 18  * @name Css
 19  * @lib Utility for styles
 20  */
 21 var Css = {};
 22 
 23 // ************************************************************************************************
 24 // CSS
 25 
 26 var cssKeywordMap = {};
 27 var cssPropNames = {};
 28 var cssColorNames = null;
 29 var imageRules = null;
 30 
 31 Css.getCSSKeywordsByProperty = function(nodeType, propName, avoid)
 32 {
 33     if (!cssKeywordMap[nodeType])
 34     {
 35         cssKeywordMap[nodeType] = {};
 36 
 37         for (var name in Css.cssInfo[nodeType])
 38         {
 39             var list = [];
 40 
 41             var types = Css.cssInfo[nodeType][name];
 42             for (var i = 0; i < types.length; ++i)
 43             {
 44                 var keywords = Css.cssKeywords[types[i]];
 45                 if (keywords)
 46                     list.push.apply(list, keywords);
 47                 else
 48                     list.push(types[i]);
 49             }
 50 
 51             cssKeywordMap[nodeType][name] = list;
 52         }
 53     }
 54 
 55     propName = propName.toLowerCase();
 56 
 57     if (avoid)
 58         return getCSSPropertyKeywordsExcludingCategories(nodeType, propName, avoid);
 59 
 60     return cssKeywordMap[nodeType][propName] || [];
 61 };
 62 
 63 function getCSSPropertyKeywordsExcludingCategories(nodeType, propName, avoid)
 64 {
 65     if (!(nodeType in Css.cssInfo) || !(propName in Css.cssInfo[nodeType]))
 66         return [];
 67 
 68     var list = [];
 69     var types = Css.cssInfo[nodeType][propName];
 70     for (var i = 0; i < types.length; ++i)
 71     {
 72         var type = types[i];
 73         if (avoid.indexOf(type) !== -1)
 74             continue;
 75         var keywords = Css.cssKeywords[type];
 76         if (keywords)
 77             list.push.apply(list, keywords);
 78         else
 79             list.push(type);
 80     }
 81     return list;
 82 }
 83 
 84 Css.getCSSPropertyNames = function(nodeType)
 85 {
 86     if (!cssPropNames[nodeType])
 87     {
 88         cssPropNames[nodeType] = [];
 89 
 90         for (var name in Css.cssInfo[nodeType])
 91             cssPropNames[nodeType].push(name);
 92     }
 93 
 94     return cssPropNames[nodeType];
 95 };
 96 
 97 Css.getCSSShorthandCategory = function(nodeType, shorthandProp, keyword)
 98 {
 99     if (!(nodeType in Css.cssInfo) || !(shorthandProp in Css.cssInfo[nodeType]))
100         return null;
101 
102     var category = null;
103     var types = Css.cssInfo[nodeType][shorthandProp];
104     for (var i = 0; i < types.length; ++i)
105     {
106         var type = types[i];
107         var keywords = Css.cssKeywords[type];
108         if (keywords ? (keywords.indexOf(keyword) !== -1) : (type === keyword))
109         {
110             // Set this as the matched category, or if there is one already
111             // bail out (we don't have a unique one).
112             if (category)
113                 return null;
114             category = type;
115         }
116     }
117     return category;
118 };
119 
120 /**
121  * Parses the CSS properties of a CSSStyleRule
122  * @param {Object} style CSSStyleRule to get the properties of
123  * @param {Object} element Element to which the style applies. Needed for parsing shorthand properties correctly.
124  * @returns {Array} Properties represented by {name, value, priority, longhandProps}
125  */
126 Css.parseCSSProps = function(style, element)
127 {
128     var props = [];
129 
130     if (!element)
131     {
132         for (var i = 0, len = style.length; i < len; ++i)
133         {
134             var prop = style.item(i);
135             props.push({name: prop,
136                 value: style.getPropertyValue(prop),
137                 priority: style.getPropertyPriority(longhandProp)});
138         }
139     }
140     else
141     {
142         var lineRE = /(?:[^;\(]*(?:\([^\)]*?\))?[^;\(]*)*;?/g;
143         var propRE = /\s*([^:\s]*)\s*:\s*(.*?)\s*(?:! (important))?;?$/;
144         var lines = style.cssText.match(lineRE);
145         for (var i = 0, len = lines.length; i < len; ++i)
146         {
147             var match = propRE.exec(lines[i]);
148             if (!match)
149                 continue;
150 
151             if (match[2])
152             {
153                 var prop = {name: match[1], value: match[2], priority: match[3] || ""};
154 
155                 // Add longhand properties to shorthand property
156                 var doc = element.ownerDocument;
157                 var dummyElement = doc.createElementNS(element.namespaceURI, element.tagName);
158                 var dummyStyle = dummyElement.style;
159                 dummyStyle.cssText = "";
160                 dummyStyle.setProperty(prop.name, prop.value, prop.priority);
161 
162                 if (dummyStyle.length > 1)
163                 {
164                     prop.longhandProps = [];
165                     for (var j = 0, propLen = dummyStyle.length; j < propLen; ++j)
166                     {
167                         var longhandProp = dummyStyle.item(j);
168                         prop.longhandProps.push({name: longhandProp,
169                             value: dummyStyle.getPropertyValue(longhandProp),
170                             priority: dummyStyle.getPropertyPriority(longhandProp)});
171                     }
172                 }
173 
174                 props.push(prop);
175             }
176         }
177     }
178 
179     return props;
180 };
181 
182 Css.isColorKeyword = function(keyword)
183 {
184     if (keyword == "transparent")
185         return false;
186 
187     if (!cssColorNames)
188     {
189         cssColorNames = [];
190 
191         var colors = Css.cssKeywords["color"];
192         for (var i = 0; i < colors.length; ++i)
193             cssColorNames.push(colors[i].toLowerCase());
194     }
195 
196     return cssColorNames.indexOf(keyword.toLowerCase()) != -1;
197 };
198 
199 Css.isImageRule = function(nodeType,rule)
200 {
201     if (!imageRules)
202     {
203         imageRules = [];
204 
205         for (var i in Css.cssInfo[nodeType])
206         {
207             var r = i.toLowerCase();
208             var suffix = "image";
209             if (r.match(suffix + "$") == suffix || r == "background")
210                 imageRules.push(r);
211         }
212     }
213 
214     return imageRules.indexOf(rule.toLowerCase()) != -1;
215 };
216 
217 Css.copyTextStyles = function(fromNode, toNode, style)
218 {
219     var view = fromNode ? fromNode.ownerDocument.defaultView : null;
220     if (view)
221     {
222         if (!style)
223             style = view.getComputedStyle(fromNode, "");
224 
225         toNode.style.fontFamily = style.fontFamily;
226         toNode.style.fontSize = style.fontSize;
227         toNode.style.fontWeight = style.fontWeight;
228         toNode.style.fontStyle = style.fontStyle;
229         toNode.style.fontSizeAdjust = style.fontSizeAdjust;
230         toNode.style.fontStretch = style.fontStretch;
231         toNode.style.fontVariant = style.fontVariant;
232         toNode.style.MozFontFeatureSettings = style.MozFontFeatureSettings;
233 
234         return style;
235     }
236 };
237 
238 Css.copyBoxStyles = function(fromNode, toNode, style)
239 {
240     var view = fromNode.ownerDocument.defaultView;
241     if (view)
242     {
243         if (!style)
244             style = view.getComputedStyle(fromNode, "");
245 
246         toNode.style.marginTop = style.getPropertyCSSValue("margin-top").cssText;
247         toNode.style.marginRight = style.marginRight;
248         toNode.style.marginBottom = style.marginBottom;
249         toNode.style.marginLeft = style.marginLeft;
250         toNode.style.borderTopWidth = style.borderTopWidth;
251         toNode.style.borderRightWidth = style.borderRightWidth;
252         toNode.style.borderBottomWidth = style.borderBottomWidth;
253         toNode.style.borderLeftWidth = style.borderLeftWidth;
254         toNode.style.unicodeBidi = style.unicodeBidi;
255 
256         return style;
257     }
258 };
259 
260 Css.readBoxStyles = function(style)
261 {
262     const styleNames = {
263         "margin-top": "marginTop", "margin-right": "marginRight",
264         "margin-left": "marginLeft", "margin-bottom": "marginBottom",
265         "border-top-width": "borderTop", "border-right-width": "borderRight",
266         "border-left-width": "borderLeft", "border-bottom-width": "borderBottom",
267         "padding-top": "paddingTop", "padding-right": "paddingRight",
268         "padding-left": "paddingLeft", "padding-bottom": "paddingBottom",
269         "z-index": "zIndex",
270     };
271 
272     var styles = {};
273     for (var styleName in styleNames)
274         styles[styleNames[styleName]] = parseInt(style.getPropertyCSSValue(styleName).cssText) || 0;
275 
276     if (FBTrace.DBG_INSPECT)
277         FBTrace.sysout("readBoxStyles ", styles);
278 
279     return styles;
280 };
281 
282 Css.getBoxFromStyles = function(style, element)
283 {
284     var args = Css.readBoxStyles(style);
285     args.width = element.offsetWidth
286         - (args.paddingLeft+args.paddingRight+args.borderLeft+args.borderRight);
287     args.height = element.offsetHeight
288         - (args.paddingTop+args.paddingBottom+args.borderTop+args.borderBottom);
289     return args;
290 };
291 
292 Css.getElementCSSSelector = function(element)
293 {
294     if (!element || !element.localName)
295         return "null";
296 
297     var label = Xml.getLocalName(element);
298     if (element.id)
299         label += "#" + element.id;
300 
301     if (element.classList && element.classList.length > 0)
302         label += "." + element.classList.item(0);
303 
304     return label;
305 };
306 
307 Css.getElementCSSPath = function(element)
308 {
309     var paths = [];
310 
311     for (; element && element.nodeType == Node.ELEMENT_NODE; element = element.parentNode)
312     {
313         var selector = Css.getElementCSSSelector(element);
314         paths.splice(0, 0, selector);
315     }
316 
317     return paths.length ? paths.join(" ") : null;
318 };
319 
320 // ************************************************************************************************
321 // CSS classes
322 
323 var classNameReCache={};
324 
325 Css.hasClass = function(node, name)
326 {
327     if (!node || node.nodeType != Node.ELEMENT_NODE || !node.className || name == '')
328         return false;
329 
330     if (name.indexOf(" ") != -1)
331     {
332         return name.split(" ").every(function(cls)
333         {
334             return !cls || node.classList.contains(cls);
335         });
336     }
337 
338     return node.classList.contains(name);
339 };
340 
341 Css.setClass = function(node, name)
342 {
343     if (!node || node.nodeType != Node.ELEMENT_NODE || name == '')
344         return;
345 
346     if (name.indexOf(" ") != -1)
347     {
348         name.split(" ").forEach(function(cls)
349         {
350             if (cls)
351                 node.classList.add(cls);
352         });
353     }
354     else
355     {
356         node.classList.add(name);
357     }
358 };
359 
360 Css.getClassValue = function(node, name)
361 {
362     var re = new RegExp(name+"-([^ ]+)");
363     var m = re.exec(node.className);
364     return m ? m[1] : "";
365 };
366 
367 Css.removeClass = function(node, name)
368 {
369     if (!node || node.nodeType != Node.ELEMENT_NODE || node.className == '' || name == '')
370         return;
371 
372     if (name.indexOf(" ") != -1)
373     {
374         name.split(" ").forEach(function(cls)
375         {
376             if (cls)
377                 node.classList.remove(cls);
378         });
379     }
380     else
381     {
382         node.classList.remove(name);
383     }
384 };
385 
386 Css.toggleClass = function(elt, name)
387 {
388     if (Css.hasClass(elt, name))
389         Css.removeClass(elt, name);
390     else
391         Css.setClass(elt, name);
392 };
393 
394 Css.obscure = function(elt, obscured)
395 {
396     if (obscured)
397         Css.setClass(elt, "obscured");
398     else
399         Css.removeClass(elt, "obscured");
400 };
401 
402 Css.setClassTimed = function(elt, name, context, timeout)
403 {
404     if (FBTrace.DBG_HTML || FBTrace.DBG_SOURCEFILES)
405     {
406         FBTrace.sysout("css.setClassTimed elt.__setClassTimeout: "+elt.__setClassTimeout+
407                 " Xml.isVisible(elt): "+Xml.isVisible(elt)+
408                 " elt.__invisibleAtSetPoint: "+elt.__invisibleAtSetPoint);
409     }
410 
411     if (!timeout)
412         timeout = 1300;
413 
414     if (elt.__setClassTimeout)  // then we are already waiting to remove the class mark
415         context.clearTimeout(elt.__setClassTimeout);  // reset the timer
416     else                        // then we are not waiting to remove the mark
417         Css.setClass(elt, name);
418 
419     if (!Xml.isVisible(elt))
420     {
421         if (elt.__invisibleAtSetPoint)
422             elt.__invisibleAtSetPoint--;
423         else
424             elt.__invisibleAtSetPoint = 5;
425     }
426     else
427     {
428         delete elt.__invisibleAtSetPoint;
429     }
430 
431     elt.__setClassTimeout = context.setTimeout(function()
432     {
433         delete elt.__setClassTimeout;
434 
435         if (elt.__invisibleAtSetPoint)  // then user can't see it, try again later
436             Css.setClassTimed(elt, name, context, timeout);
437         else
438         {
439             delete elt.__invisibleAtSetPoint;  // may be zero
440             Css.removeClass(elt, name);
441         }
442     }, timeout);
443 };
444 
445 Css.cancelClassTimed = function(elt, name, context)
446 {
447     if (elt.__setClassTimeout)
448     {
449         Css.removeClass(elt, name);
450         context.clearTimeout(elt.__setClassTimeout);
451         delete elt.__setClassTimeout;
452     }
453 };
454 
455 Css.safeGetCSSRules = function(styleSheet)
456 {
457     try
458     {
459         return styleSheet.cssRules;
460     }
461     catch (e)
462     {
463         if (FBTrace.DBG_ERRORS)
464             FBTrace.sysout("safeGetCSSRules "+e, e);
465     }
466 
467     return null;
468 }
469 
470 Css.isValidStylesheet = function(styleSheet)
471 {
472     try
473     {
474         var dummy = styleSheet.cssRules; // Mozilla throws
475         return true;
476     }
477     catch (e)
478     {
479         if (FBTrace.DBG_ERRORS)
480             FBTrace.sysout("isValidStylesheet "+e, e);
481     }
482 
483     return false;
484 }
485 
486 // ********************************************************************************************* //
487 // Stylesheet API
488 
489 Css.shouldIgnoreSheet = function(sheet)
490 {
491     // Ignore by the regular method, except for default stylesheets that are
492     // used in case there is no other stylesheet.
493     if (sheet.defaultStylesheet)
494         return false;
495     return (sheet.ownerNode && Firebug.shouldIgnore(sheet.ownerNode));
496 };
497 
498 Css.createStyleSheet = function(doc, url)
499 {
500     var style = doc.createElementNS("http://www.w3.org/1999/xhtml", "style");
501     style.setAttribute("charset", "utf-8");
502     style.setAttribute("type", "text/css");
503 
504     var cssText = url ? Http.getResource(url) : null;
505     if (cssText)
506     {
507         var index = url.lastIndexOf("/");
508         var absURL = url.substr(0, index+1);
509 
510         // Replace all relative URLs with absolute (using the passed url).
511         // Note that stylesheets can come from various extensions and the source can
512         // be even used in a browser env where relative URLs make more sense.
513         var expr = /url\(([\'"]?)(?![\'"]?(?:[a-z]+:|\/))/gi;
514         cssText = cssText.replace(expr, "url($1" + absURL);
515 
516         style.textContent = cssText;
517     }
518 
519     Firebug.setIgnored(style);
520     return style;
521 }
522 
523 Css.addStyleSheet = function(doc, style)
524 {
525     var heads = doc.getElementsByTagName("head");
526     if (heads.length)
527     {
528         heads[0].appendChild(style);
529     }
530     else if (doc.documentElement)
531     {
532         doc.documentElement.appendChild(style);
533     }
534     else
535     {
536         if (FBTrace.DBG_ERRORS)
537             FBTrace.sysout("css.addStyleSheet; ERROR to append a stylesheet");
538     }
539 };
540 
541 Css.appendStylesheet = function(doc, uri)
542 {
543     // Make sure the stylesheet is not appended twice.
544     var styleSheet = doc.getElementById(uri);
545     if (styleSheet)
546         return styleSheet;
547 
548     var styleSheet = Css.createStyleSheet(doc, uri);
549     styleSheet.setAttribute("id", uri);
550     Css.addStyleSheet(doc, styleSheet);
551 
552     return styleSheet;
553 },
554 
555 Css.getStyleSheetByHref = function(url, context)
556 {
557     if (!context.styleSheetMap)
558         Css.createStyleSheetMap(context);  // fill cache
559 
560     // hasOwnProperty is called to prevent possible conflicts with prototype extensions
561     // and strict mode warnings
562     return context.styleSheetMap.hasOwnProperty(url) ? context.styleSheetMap[url] : undefined;
563 };
564 
565 Css.createStyleSheetMap = function(context)
566 {
567     context.styleSheetMap = {};
568 
569     function addSheet(sheet)
570     {
571         var sheetURL = Css.getURLForStyleSheet(sheet);
572         context.styleSheetMap[sheetURL] = sheet;
573 
574         // recurse for imported sheets
575 
576         for (var i = 0; i < sheet.cssRules.length; ++i)
577         {
578             var rule = sheet.cssRules[i];
579             if (rule instanceof CSSStyleRule)
580             {
581                 if (rule.type == CSSRule.STYLE_RULE)  // once we get here no more imports
582                     return;
583             }
584             else if (rule instanceof CSSImportRule)
585             {
586                 addSheet(rule.styleSheet);
587             }
588         }
589     }
590 
591     Win.iterateWindows(context.window, function(subwin)
592     {
593         var rootSheets = subwin.document.styleSheets;
594         if (!rootSheets)
595             return; // XUL?
596 
597         for (var i = 0; i < rootSheets.length; ++i)
598         {
599             try
600             {
601                 addSheet(rootSheets[i]);
602             }
603             catch (err)
604             {
605                 //if (FBTrace.DBG_ERRORS)
606                 //    FBTrace.sysout("css.createStyleSheetMap; EXCEPTION " + err, err);
607             }
608         }
609     });
610 
611     if (FBTrace.DBG_ERRORS && FBTrace.DBG_CSS)
612         FBTrace.sysout("css.createStyleSheetMap for "+context.getName(), context.styleSheetMap);
613 
614     return context.styleSheetMap;
615 };
616 
617 Css.getAllStyleSheets = function(context)
618 {
619     if (!context)
620         return [];
621 
622     var styleSheets = [];
623 
624     var showUACSS = Options.get("showUserAgentCSS");
625     function addSheet(sheet)
626     {
627         var sheetLocation =  Css.getURLForStyleSheet(sheet);
628 
629         if (!showUACSS && Url.isSystemURL(sheetLocation))
630             return;
631 
632         if (Css.shouldIgnoreSheet(sheet))
633             return;
634 
635         styleSheets.push(sheet);
636 
637         try
638         {
639             for (var i = 0; i < sheet.cssRules.length; ++i)
640             {
641                 var rule = sheet.cssRules[i];
642                 if (rule instanceof window.CSSImportRule)
643                     addSheet(rule.styleSheet);
644             }
645         }
646         catch(e)
647         {
648             if (FBTrace.DBG_ERRORS)
649                 FBTrace.sysout("getAllStyleSheets sheet.cssRules FAILS for "+
650                     (sheet?sheet.href:"null sheet")+e, e);
651         }
652     }
653 
654     Win.iterateWindows(context.window, function(subwin)
655     {
656         var rootSheets = subwin.document.styleSheets;
657         for (var i = 0; i < rootSheets.length; ++i)
658             addSheet(rootSheets[i]);
659     });
660 
661     return styleSheets;
662 };
663 
664 Css.getURLForStyleSheet = function(styleSheet)
665 {
666     // http://www.w3.org/TR/DOM-Level-2-Style/stylesheets.html#StyleSheets-StyleSheet.
667     // For inline style sheets, the value of this attribute is null.
668     if (!styleSheet.href && !styleSheet.ownerNode)
669         return null;
670 
671     return (styleSheet.href ? styleSheet.href : styleSheet.ownerNode.ownerDocument.documentURI);
672 };
673 
674 /**
675  * Retrieves the instance number for a given style sheet. The instance number
676  * is sheet's index within the set of all other sheets whose URL is the same.
677  */
678 Css.getInstanceForStyleSheet = function(styleSheet, ownerDocument)
679 {
680     // ownerDocument is an optional hint for performance
681     if (FBTrace.DBG_CSS)
682         FBTrace.sysout("getInstanceForStyleSheet href:" + styleSheet.href + " mediaText:" +
683             styleSheet.media.mediaText + " path to ownerNode" +
684             (styleSheet.ownerNode && Xpath.getElementXPath(styleSheet.ownerNode)), ownerDocument);
685 
686     ownerDocument = ownerDocument || Css.getDocumentForStyleSheet(styleSheet);
687     if (!ownerDocument)
688         return;
689 
690     var ret = 0,
691         styleSheets = ownerDocument.styleSheets,
692         href = styleSheet.href;
693 
694     for (var i = 0; i < styleSheets.length; i++)
695     {
696         var curSheet = styleSheets[i];
697 
698         if (FBTrace.DBG_CSS)
699         {
700             FBTrace.sysout("getInstanceForStyleSheet: compare href " + i +
701                 " " + curSheet.href + " " + curSheet.media.mediaText + " " +
702                 (curSheet.ownerNode && Xpath.getElementXPath(curSheet.ownerNode)));
703         }
704 
705         if (Css.shouldIgnoreSheet(curSheet))
706             break;
707 
708         if (curSheet == styleSheet)
709             break;
710 
711         if (curSheet.href == href)
712             ret++;
713     }
714     return ret;
715 };
716 
717 Css.getDocumentForStyleSheet = function(styleSheet)
718 {
719     if (!styleSheet)
720         return;
721 
722     while (styleSheet.parentStyleSheet && !styleSheet.ownerNode)
723         styleSheet = styleSheet.parentStyleSheet;
724 
725     if (styleSheet.ownerNode)
726         return styleSheet.ownerNode.ownerDocument;
727 };
728 
729 // ********************************************************************************************* //
730 
731 Css.stripUnits = function(value)
732 {
733     // remove units from '0px', '0em' etc. leave non-zero units in-tact.
734     return value.replace(/(url\(.*?\)|[^0]\S*\s*)|0(%|em|ex|px|in|cm|mm|pt|pc)(\s|$)/gi,
735         function(_, skip, remove, whitespace)
736         {
737             return skip || ('0' + whitespace);
738         }
739     );
740 }
741 
742 Css.extractURLs = function(value)
743 {
744     var urls = [];
745     var urlValues = value.match(/url\((["']).*?\1\)/g);
746 
747     for (var i in urlValues)
748         urls.push(urlValues[i].replace(/url\((["'])(.*?)\1\)/, "$2"));
749 
750     return urls;
751 }
752 
753 Css.rgbToHex = function(value)
754 {
755     return value.replace(/\brgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)/gi,
756         function(_, r, g, b) {
757             return "#" + ((1 << 24) + (r << 16) + (g << 8) + (b << 0)).
758                 toString(16).substr(-6).toUpperCase();
759         });
760 }
761 
762 Css.rgbToHSL = function(value)
763 {
764     return value.replace(/\brgba?\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})(,\s*(\d.\d+|\d))?\)/gi,
765         function(_, r, g, b, _, a)
766         {
767             r = parseInt(r);
768             g = parseInt(g);
769             b = parseInt(b);
770 
771             var gray = (r == g && g == b);
772 
773             r /= 255;
774             g /= 255;
775             b /= 255;
776 
777             var max = Math.max(r, g, b);
778             var min = Math.min(r, g, b);
779 
780             var h = 0;
781             var s = 0;
782             var l = (max+min)/2;
783 
784             if (!gray)
785             {
786                 var delta = max - min;
787                 s = l > 0.5 ? delta/(2-max-min) : delta/(max+min);
788 
789                 switch (max)
790                 {
791                     case r:
792                         h = (g-b)/delta + (g < b ? 6 : 0);
793                         break;
794 
795                     case g:
796                         h = (b-r)/delta + 2;
797                         break;
798 
799                     case b:
800                         h = (r-g)/delta + 4;
801                         break;
802                 }
803             }
804 
805             h = Math.round(h * 60);
806             s = Math.round(s * 100);
807             l = Math.round(l * 100);
808 
809             if (a)
810                 return "hsla("+h+", "+s+"%, "+l+"%, "+a+")";
811             else
812                 return "hsl("+h+", "+s+"%, "+l+"%)";
813         });
814 }
815 
816 // ********************************************************************************************* //
817 // CSS Info
818 
819 Css.cssInfo = {};
820 Css.cssInfo.html =
821 {
822     "animation": [],
823     "animation-delay": [],
824     "animation-direction": ["normal", "alternate", "reverse", "alternate-reverse"],
825     "animation-duration": [],
826     "animation-iteration-count": ["infinite"],
827     "animation-name" : ["none"],
828     "animation-play-state": ["running", "paused"],
829     "animation-timing-function": [],
830     "animation-fill-mode": ["none", "forwards", "backwards", "both"],
831 
832     "background": ["bgRepeat", "bgAttachment", "position", "color", "image", "none", "boxModels"],
833     "background-attachment": ["bgAttachment"],
834     "background-color": ["color"],
835     "background-image": ["image", "none"],
836     "background-position": ["position", "length"],
837     "background-repeat": ["bgRepeat"],
838     "background-size": ["bgSize", "length"],
839     "background-clip": ["boxModels"], // FF 4.0
840     "background-origin": ["boxModels"], // FF 4.0
841 
842     "border": ["borderStyle", "thickness", "color"],
843     "border-top": ["borderStyle", "borderCollapse", "color"],
844     "border-right": ["borderStyle", "borderCollapse", "color"],
845     "border-bottom": ["borderStyle", "borderCollapse", "color"],
846     "border-left": ["borderStyle", "borderCollapse", "color"],
847     "border-collapse": ["borderCollapse"],
848     "border-color": ["color"],
849     "border-top-color": ["color"],
850     "border-right-color": ["color"],
851     "border-bottom-color": ["color"],
852     "border-left-color": ["color"],
853     "border-spacing": ["length"],
854     "border-style": ["borderStyle"],
855     "border-top-style": ["borderStyle"],
856     "border-right-style": ["borderStyle"],
857     "border-bottom-style": ["borderStyle"],
858     "border-left-style": ["borderStyle"],
859     "border-width": ["thickness", "length"],
860     "border-top-width": ["thickness", "length"],
861     "border-right-width": ["thickness", "length"],
862     "border-bottom-width": ["thickness", "length"],
863     "border-left-width": ["thickness", "length"],
864     "border-radius": ["length"], // FF 4.0
865     "border-top-left-radius": ["length"], // FF 4.0
866     "border-top-right-radius": ["length"], // FF 4.0
867     "border-bottom-right-radius": ["length"], // FF 4.0
868     "border-bottom-left-radius": ["length"], // FF 4.0
869     "-moz-border-image": ["borderImageRepeat", "thickness", "url()", "none"],
870     "border-image": ["borderImageRepeat", "thickness", "url()", "none"], // FF 15.0
871     "border-image-outset": ["length"], // FF 15.0
872     "border-image-repeat": ["borderImageRepeat"], // FF 15.0
873     "border-image-slice": ["fill"],
874     "border-image-source": ["image", "none"],
875     "border-image-width": ["auto", "length"], // FF 15.0
876 
877     "top": ["auto", "length"],
878     "right": ["auto", "length"],
879     "bottom": ["auto", "length"],
880     "left": ["auto", "length"],
881     "height": ["auto", "length"],
882     "caption-side": ["captionSide"],
883     "clear": ["clear", "none"],
884     "clip": ["shape", "auto"],
885     "color": ["color"],
886     "content": ["string", "none", "normal"],
887     "counter-increment": ["none"],
888     "counter-reset": ["none"],
889     "cursor": ["cursor", "url()", "none"],
890     "direction": ["direction"],
891     "display": ["display"],
892     "empty-cells": ["emptyCells"],
893     "float": ["float"],
894 
895     // specification of font families in "font" is special-cased
896     "font": ["fontStyle", "fontVariant", "namedFontWeight", "fontSize", "lineHeight", "mozFont"],
897     "font-family": ["fontFamily"],
898     "font-size": ["fontSize", "length"],
899     "font-size-adjust": ["none"],
900     "font-stretch": ["fontStretch"],
901     "font-style": ["fontStyle"],
902     "font-variant": ["fontVariant"],
903     "font-weight": ["fontWeight"],
904 
905     "ime-mode": ["imeMode"], // FF 3.0
906     "letter-spacing": ["normal", "length"],
907     "line-height": ["lineHeight", "length"],
908     "word-break": ["wordBreak"],
909 
910     "list-style": ["listStyleType", "listStylePosition"],
911     "list-style-image": ["url()", "none"],
912     "list-style-position": ["listStylePosition"],
913     "list-style-type": ["listStyleType"],
914 
915     "margin": ["auto", "length"],
916     "margin-top": ["auto", "length"],
917     "margin-right": ["auto", "length"],
918     "margin-bottom": ["auto", "length"],
919     "margin-left": ["auto", "length"],
920 
921     "marker-offset": ["auto", "length"],
922     "min-height": ["auto", "length"],
923     "max-height": ["none", "length"],
924     "min-width": ["width", "auto", "length"],
925     "max-width": ["width", "none", "length"],
926 
927     "opacity": [],
928 
929     "outline": ["color", "borderStyle", "thickness", "auto"],
930     "outline-color": ["color"],
931     "outline-style": ["borderStyle", "auto"],
932     "outline-width": ["thickness", "length"],
933     "outline-offset": ["length"],
934 
935     "overflow": ["overflow", "auto"],
936     "overflow-x": ["overflow", "auto"],
937     "overflow-y": ["overflow", "auto"],
938 
939     "padding": ["length"],
940     "padding-top": ["length"],
941     "padding-right": ["length"],
942     "padding-bottom": ["length"],
943     "padding-left": ["length"],
944 
945     "page-break-after": ["pageBreak"],
946     "page-break-before": ["pageBreak"],
947     "pointer-events": ["auto", "none"],
948     "position": ["elPosition"],
949     "quotes": ["none"],
950     "resize": ["resize"], // FF 4.0
951     "table-layout": ["tableLayout"],
952     "text-align": ["textAlign"],
953     "-moz-text-align-last": ["textAlign"], // FF 12.0
954     "box-shadow": ["boxShadow", "color", "none", "length"], // FF 4.0
955     "text-decoration": ["textDecoration"],
956     "text-indent": ["length"],
957     "text-rendering": ["textRendering"],
958     "text-shadow": ["color", "length"],
959     "text-transform": ["textTransform"],
960     "transition": ["transitionProperty", "timingFunction"],
961     "transition-property": ["transitionProperty"],
962     "transition-duration": [],
963     "transition-timing-function": ["timingFunction"],
964     "transition-delay": [],
965     "transform": ["transformFunction", "none", "length"],
966     "transform-origin": ["position", "length"],
967     "transform-style": ["transformStyle"],
968     "unicode-bidi": ["unicodeBidi"],
969     "vertical-align": ["verticalAlign", "length"],
970     "visibility": ["visibility"],
971     "white-space": ["whiteSpace"],
972     "width": ["width", "length", "auto"],
973     "word-spacing": ["normal", "length"],
974     "word-wrap": ["wordWrap"], // FF 3.5
975     "z-index": ["auto"],
976 
977     "-moz-appearance": ["mozAppearance"],
978     "-moz-backface-visibility": ["mozBackfaceVisibility"], // FF 10.0
979     "-moz-border-top-colors": ["color"],
980     "-moz-border-right-colors": ["color"],
981     "-moz-border-bottom-colors": ["color"],
982     "-moz-border-left-colors": ["color"],
983     "-moz-border-start": ["borderStyle", "borderCollapse", "color", "none"],
984     "-moz-border-end": ["borderStyle", "borderCollapse", "color", "none"],
985     "-moz-border-start-color": ["color"],
986     "-moz-border-end-color": ["color"],
987     "-moz-border-start-style": ["borderStyle"],
988     "-moz-border-end-style": ["borderStyle"],
989     "-moz-border-start-width": ["thickness"],
990     "-moz-border-end-width": ["thickness"],
991     "-moz-box-align": ["mozBoxAlign"],
992     "-moz-box-direction": ["mozBoxDirection"],
993     "-moz-box-flex": [],
994     "-moz-box-ordinal-group": [],
995     "-moz-box-orient": ["mozBoxOrient"],
996     "-moz-box-pack": ["mozBoxPack"],
997     "-moz-box-sizing": ["mozBoxSizing"],
998     "-moz-user-focus": ["userFocus", "none"],
999     "-moz-user-input": ["userInput", "none"],
1000     "-moz-user-modify": ["mozUserModify"],
1001     "-moz-user-select": ["userSelect", "none"],
1002     "-moz-background-inline-policy": [],
1003     "-moz-binding": [],
1004     "-moz-columns": ["auto", "length"],
1005     "-moz-column-count": ["auto"],
1006     "-moz-column-gap": ["normal", "length"],
1007     "-moz-column-rule": ["thickness", "borderStyle", "color"],
1008     "-moz-column-rule-width": ["thickness", "length"],
1009     "-moz-column-rule-style": ["borderStyle"],
1010     "-moz-column-rule-color": ["color"],
1011     "-moz-column-width": ["auto", "length"],
1012     "-moz-image-region": [],
1013     "-moz-font-feature-settings": ["mozFontFeatureSettings"], // FF 4.0
1014     "-moz-font-language-override": ["normal"],
1015     "-moz-tab-size": [], // FF 4.0,
1016     "orient": ["horizontal", "vertical"], // FF 6.0
1017     "-moz-text-blink": ["none", "blink"], // FF 6.0
1018     "-moz-text-decoration-color": ["color"], // FF 6.0
1019     "-moz-text-decoration-line": ["mozTextDecorationLine"], // FF 6.0
1020     "-moz-text-decoration-style": ["mozTextDecorationStyle"], // FF 6.0
1021     "-moz-hyphens": ["mozHyphens"], // FF 6.0
1022     "text-overflow": ["textOverflow"], // FF 7.0
1023     "-moz-perspective": ["none", "length"], // FF 10.0
1024     "-moz-perspective-origin": ["position", "length"] // FF 10.0
1025 };
1026 
1027 // ::-moz-progress-bar  // FF 6 TODO
1028 
1029 Css.cssInfo.svg =
1030 {
1031     "alignment-baseline": ["svgAlignmentBaseline"],
1032     "baseline-shift": ["baselineShift"],
1033     "clip": ["auto", "length"],
1034     "clip-path": ["url()", "none"],
1035     "clip-rule": ["clipRule"],
1036     "color": ["color"],
1037     "color-interpolation": ["colorInterpolation"],
1038     "color-interpolation-filters": ["colorInterpolation"],
1039     "color-profile": ["colorProfile"],
1040     "color-rendering": ["colorRendering"],
1041     "cursor": ["cursor", "url()"],
1042     "direction": ["direction"],
1043     "display": ["display"],
1044     "dominant-baseline": ["dominantBaseline"],
1045     "enable-background": ["accumulate"],
1046     "fill": ["clipRule"],
1047     "fill-opacity": [],
1048     "fill-rule": ["clipRule"],
1049     "filter": ["url()", "none"],
1050     "flood-color": ["currentColor"],
1051     "flood-opacity": [],
1052     "font": ["fontStyle", "fontSize", "fontVariant", "namedFontWeight"],
1053     "font-family": ["fontFamily"],
1054     "font-size": ["fontSize"],
1055     "font-size-adjust": [],
1056     "font-stretch": ["fontStretch"],
1057     "font-style": ["fontStyle"],
1058     "font-variant": ["fontVariant"],
1059     "font-weight": ["fontWeight"],
1060     "glyph-orientation-horizontal": [],
1061     "glyph-orientation-vertical": ["auto"],
1062     "image-rendering": ["imageRendering"], // FF 3.6
1063     "kerning": ["auto"],
1064     "letter-spacing": ["normal"],
1065     "lighting-color": ["currentColor"],
1066     "marker": ["none"],
1067     "marker-end": ["none"],
1068     "mask": ["url()", "none"],
1069     "opacity": [],
1070     "overflow": ["auto", "svgOverflow"],
1071     "pointer-events": ["pointerEvents"], // FF 1.5/3.6
1072     "shape-rendering": ["auto", "shapeRendering"],
1073     "stop-color": ["currentColor"],
1074     "stop-opacity": [],
1075     "stroke": [],
1076     "stroke-dasharray": ["none"],
1077     "stroke-dashoffset": [],
1078     "stroke-linecap": ["strokeLinecap"],
1079     "stroke-linejoin": ["strokeLinejoin"],
1080     "stroke-miterlimit": [],
1081     "stroke-opacity": [],
1082     "stroke-width": [],
1083     "text-anchor": ["mozBoxPack"],
1084     "text-decoration": ["textDecoration"],
1085     "text-rendering": ["textRendering"],
1086     "unicode-bidi": ["unicodeBidi"],
1087     "visibility": ["visibility"],
1088     "word-spacing": ["normal"],
1089     "writing-mode": ["writingMode"]
1090 };
1091 
1092 Css.multiValuedProperties =
1093 {
1094     "animation": 1,
1095     "background": 1,
1096     "background-position": 1,
1097     "border": 1,
1098     "border-color": 1,
1099     "border-style": 1,
1100     "border-width": 1,
1101     "border-radius": 1,
1102     "box-shadow": 1,
1103     "font": 1,
1104     "font-family": 1,
1105     "margin": 1,
1106     "padding": 1
1107 };
1108 
1109 Css.unitlessProperties =
1110 {
1111     "counter-increment": 1,
1112     "counter-reset": 1,
1113     "font-size-adjust": 1,
1114     "font-weight": 1,
1115     "line-height": 1,
1116     "opacity": 1,
1117     "orphans": 1,
1118     "widows": 1,
1119     "z-index": 1,
1120     "-moz-column-count": 1
1121 };
1122 
1123 Css.cssKeywords =
1124 {
1125     "mozAppearance":
1126     [
1127         "none",
1128         "button",
1129         "button-arrow-down",
1130         "button-arrow-next",
1131         "button-arrow-previous",
1132         "button-arrow-up",
1133         "button-bevel",
1134         "button-focus",
1135         "caret",
1136         "checkbox",
1137         "checkbox-container",
1138         "checkbox-label",
1139         "checkmenuitem",
1140         "dualbutton",
1141         "groupbox",
1142         "listbox",
1143         "listitem",
1144         "menuarrow",
1145         "menubar",
1146         "menucheckbox",
1147         "menuimage",
1148         "menuitem",
1149         "menuitemtext",
1150         "menulist",
1151         "menulist-button",
1152         "menulist-text",
1153         "menulist-textfield",
1154         "menupopup",
1155         "menuradio",
1156         "menuseparator",
1157         "meterbar",
1158         "meterchunk",
1159         "progressbar",
1160         "progressbar-vertical",
1161         "progresschunk",
1162         "progresschunk-vertical",
1163         "radio",
1164         "radio-container",
1165         "radio-label",
1166         "radiomenuitem",
1167         "resizer",
1168         "resizerpanel",
1169         "scale-horizontal",
1170         "scalethumbend",
1171         "scalethumb-horizontal",
1172         "scalethumbstart",
1173         "scalethumbtick",
1174         "scalethumb-vertical",
1175         "scale-vertical",
1176         "scrollbarbutton-down",
1177         "scrollbarbutton-left",
1178         "scrollbarbutton-right",
1179         "scrollbarbutton-up",
1180         "scrollbarthumb-horizontal",
1181         "scrollbarthumb-vertical",
1182         "scrollbartrack-horizontal",
1183         "scrollbartrack-vertical",
1184         "searchfield",
1185         "separator",
1186         "sheet",
1187         "spinner",
1188         "spinner-downbutton",
1189         "spinner-textfield",
1190         "spinner-upbutton",
1191         "splitter",
1192         "statusbar",
1193         "statusbarpanel",
1194         "tab",
1195         "tabpanel",
1196         "tabpanels",
1197         "tab-scroll-arrow-back",
1198         "tab-scroll-arrow-forward",
1199         "textfield",
1200         "textfield-multiline",
1201         "toolbar",
1202         "toolbarbutton",
1203         "toolbarbutton-dropdown",
1204         "toolbargripper",
1205         "toolbox",
1206         "tooltip",
1207         "treeheader",
1208         "treeheadercell",
1209         "treeheadersortarrow",
1210         "treeitem",
1211         "treeline",
1212         "treetwisty",
1213         "treetwistyopen",
1214         "treeview",
1215 
1216         "-moz-mac-unified-toolbar",
1217         "-moz-win-borderless-glass", // FF 4.0
1218         "-moz-win-browsertabbar-toolbox",
1219         "-moz-win-communicationstext",
1220         "-moz-win-communications-toolbox",
1221         "-moz-win-exclude-glass", // FF 6.0
1222         "-moz-win-glass",
1223         "-moz-win-mediatext",
1224         "-moz-win-media-toolbox",
1225         "-moz-window-button-box",
1226         "-moz-window-button-box-maximized",
1227         "-moz-window-button-close",
1228         "-moz-window-button-maximize",
1229         "-moz-window-button-minimize",
1230         "-moz-window-button-restore",
1231         "-moz-window-frame-bottom",
1232         "-moz-window-frame-left",
1233         "-moz-window-frame-right",
1234         "-moz-window-titlebar",
1235         "-moz-window-titlebar-maximized"
1236     ],
1237 
1238     "mozBackfaceVisibility":
1239     [
1240         "visible",
1241         "hidden"
1242     ],
1243 
1244     "color":
1245     [
1246         // Color functions
1247         "rgb()",
1248         "rgba()",
1249         "hsl()",
1250         "hsla()",
1251 
1252         // Color keywords
1253         "aliceblue",
1254         "antiquewhite",
1255         "aqua",
1256         "aquamarine",
1257         "azure",
1258         "beige",
1259         "bisque",
1260         "black",
1261         "blanchedalmond",
1262         "blue",
1263         "blueviolet",
1264         "brown",
1265         "burlywood",
1266         "cadetblue",
1267         "chartreuse",
1268         "chocolate",
1269         "coral",
1270         "cornflowerblue",
1271         "cornsilk",
1272         "crimson",
1273         "cyan",
1274         "darkblue",
1275         "darkcyan",
1276         "darkgoldenrod",
1277         "darkgray",
1278         "darkgreen",
1279         "darkgrey",
1280         "darkkhaki",
1281         "darkmagenta",
1282         "darkolivegreen",
1283         "darkorange",
1284         "darkorchid",
1285         "darkred",
1286         "darksalmon",
1287         "darkseagreen",
1288         "darkslateblue",
1289         "darkslategray",
1290         "darkslategrey",
1291         "darkturquoise",
1292         "darkviolet",
1293         "deeppink",
1294         "deepskyblue",
1295         "dimgray",
1296         "dimgrey",
1297         "dodgerblue",
1298         "firebrick",
1299         "floralwhite",
1300         "forestgreen",
1301         "fuchsia",
1302         "gainsboro",
1303         "ghostwhite",
1304         "gold",
1305         "goldenrod",
1306         "gray",
1307         "green",
1308         "greenyellow",
1309         "grey",
1310         "honeydew",
1311         "hotpink",
1312         "indianred",
1313         "indigo",
1314         "ivory",
1315         "khaki",
1316         "lavender",
1317         "lavenderblush",
1318         "lawngreen",
1319         "lemonchiffon",
1320         "lightblue",
1321         "lightcoral",
1322         "lightcyan",
1323         "lightgoldenrodyellow",
1324         "lightgray",
1325         "lightgreen",
1326         "lightgrey",
1327         "lightpink",
1328         "lightsalmon",
1329         "lightseagreen",
1330         "lightskyblue",
1331         "lightslategray",
1332         "lightslategrey",
1333         "lightsteelblue",
1334         "lightyellow",
1335         "lime",
1336         "limegreen",
1337         "linen",
1338         "magenta",
1339         "maroon",
1340         "mediumaquamarine",
1341         "mediumblue",
1342         "mediumorchid",
1343         "mediumpurple",
1344         "mediumseagreen",
1345         "mediumslateblue",
1346         "mediumspringgreen",
1347         "mediumturquoise",
1348         "mediumvioletred",
1349         "midnightblue",
1350         "mintcream",
1351         "mistyrose",
1352         "moccasin",
1353         "navajowhite",
1354         "navy",
1355         "oldlace",
1356         "olive",
1357         "olivedrab",
1358         "orange",
1359         "orangered",
1360         "orchid",
1361         "palegoldenrod",
1362         "palegreen",
1363         "paleturquoise",
1364         "palevioletred",
1365         "papayawhip",
1366         "peachpuff",
1367         "peru",
1368         "pink",
1369         "plum",
1370         "powderblue",
1371         "purple",
1372         "red",
1373         "rosybrown",
1374         "royalblue",
1375         "saddlebrown",
1376         "salmon",
1377         "sandybrown",
1378         "seagreen",
1379         "seashell",
1380         "sienna",
1381         "silver",
1382         "skyblue",
1383         "slateblue",
1384         "slategray",
1385         "slategrey",
1386         "snow",
1387         "springgreen",
1388         "steelblue",
1389         "tan",
1390         "teal",
1391         "thistle",
1392         "tomato",
1393         "turquoise",
1394         "violet",
1395         "wheat",
1396         "white",
1397         "whitesmoke",
1398         "yellow",
1399         "yellowgreen",
1400 
1401         // Special color keywords
1402         "transparent",
1403         "currentColor",
1404 
1405         // System colors
1406         "ActiveBorder",
1407         "ActiveCaption",
1408         "AppWorkspace",
1409         "Background",
1410         "ButtonFace",
1411         "ButtonHighlight",
1412         "ButtonShadow",
1413         "ButtonText",
1414         "CaptionText",
1415         "GrayText",
1416         "Highlight",
1417         "HighlightText",
1418         "InactiveBorder",
1419         "InactiveCaption",
1420         "InactiveCaptionText",
1421         "InfoBackground",
1422         "InfoText",
1423         "Menu",
1424         "MenuText",
1425         "Scrollbar",
1426         "ThreeDDarkShadow",
1427         "ThreeDFace",
1428         "ThreeDHighlight",
1429         "ThreeDLightShadow",
1430         "ThreeDShadow",
1431         "Window",
1432         "WindowFrame",
1433         "WindowText",
1434 
1435         // Mozilla system color extensions
1436         "-moz-ButtonDefault",
1437         "-moz-ButtonHoverFace",
1438         "-moz-ButtonHoverText",
1439         "-moz-CellHighlight",
1440         "-moz-CellHighlightText",
1441         "-moz-Combobox",
1442         "-moz-ComboboxText",
1443         "-moz-Dialog",
1444         "-moz-DialogText",
1445         "-moz-dragtargetzone",
1446         "-moz-EvenTreeRow",
1447         "-moz-Field",
1448         "-moz-FieldText",
1449         "-moz-html-CellHighlight",
1450         "-moz-html-CellHighlightText",
1451         "-moz-mac-accentdarkestshadow",
1452         "-moz-mac-accentdarkshadow",
1453         "-moz-mac-accentface",
1454         "-moz-mac-accentlightesthighlight",
1455         "-moz-mac-accentlightshadow",
1456         "-moz-mac-accentregularhighlight",
1457         "-moz-mac-accentregularshadow",
1458         "-moz-mac-chrome-active",
1459         "-moz-mac-chrome-inactive",
1460         "-moz-mac-focusring",
1461         "-moz-mac-menuselect",
1462         "-moz-mac-menushadow",
1463         "-moz-mac-menutextselect",
1464         "-moz-MenuHover",
1465         "-moz-MenuHoverText",
1466         "-moz-MenuBarText",
1467         "-moz-MenuBarHoverText",
1468         "-moz-nativehyperlinktext",
1469         "-moz-OddTreeRow",
1470         "-moz-win-communicationstext",
1471         "-moz-win-mediatext",
1472 
1473         // Mozilla color preference extensions
1474         "-moz-activehyperlinktext",
1475         "-moz-default-background-color", // FF 5.0
1476         "-moz-default-color", // FF 5.0
1477         "-moz-hyperlinktext",
1478         "-moz-visitedhyperlinktext"
1479     ],
1480 
1481     "auto":
1482     [
1483         "auto"
1484     ],
1485 
1486     "none":
1487     [
1488         "none"
1489     ],
1490 
1491     "normal":
1492     [
1493         "normal"
1494     ],
1495 
1496     "captionSide":
1497     [
1498         "top",
1499         "bottom",
1500         "left",
1501         "right"
1502     ],
1503 
1504     "emptyCells":
1505     [
1506         "show",
1507         "hide",
1508         "-moz-show-background"
1509     ],
1510 
1511     "clear":
1512     [
1513         "left",
1514         "right",
1515         "both"
1516     ],
1517 
1518     "cursor":
1519     [
1520         "auto",
1521         "default",
1522         "pointer",
1523         "text",
1524         "crosshair",
1525         "move",
1526         "help",
1527         "no-drop",
1528         "not-allowed",
1529         "none", // FF 3.0
1530         "-moz-grab",
1531         "-moz-grabbing",
1532         "-moz-zoom-in",
1533         "-moz-zoom-out",
1534         "e-resize",
1535         "all-scroll",
1536         "ne-resize",
1537         "nw-resize",
1538         "n-resize",
1539         "se-resize",
1540         "sw-resize",
1541         "s-resize",
1542         "w-resize",
1543         "ew-resize",
1544         "ns-resize",
1545         "nesw-resize",
1546         "nwse-resize",
1547         "col-resize",
1548         "row-resize",
1549         "cell",
1550         "context-menu",
1551         "progress",
1552         "vertical-text",
1553         "wait",
1554         "copy",
1555         "alias"
1556     ],
1557 
1558     "boxModels": // FF 4.0
1559     [
1560         "padding-box",
1561         "border-box",
1562         "content-box"
1563     ],
1564 
1565     "direction":
1566     [
1567         "ltr",
1568         "rtl"
1569     ],
1570 
1571     "bgAttachment":
1572     [
1573         "scroll",
1574         "fixed"
1575     ],
1576 
1577     "position":
1578     [
1579         "top",
1580         "center",
1581         "bottom",
1582         "left",
1583         "right"
1584     ],
1585 
1586     "bgRepeat":
1587     [
1588         "repeat",
1589         "repeat-x",
1590         "repeat-y",
1591         "no-repeat"
1592     ],
1593 
1594     "bgSize": // FF 4.0
1595     [
1596         "auto",
1597         "cover",
1598         "contain"
1599     ],
1600 
1601     "borderStyle":
1602     [
1603         "solid",
1604         "none",
1605         "dotted",
1606         "dashed",
1607         "double",
1608         "hidden",
1609         "groove",
1610         "ridge",
1611         "inset",
1612         "outset",
1613         "-moz-bg-inset",
1614         "-moz-bg-outset",
1615         "-moz-bg-solid"
1616     ],
1617 
1618     "borderCollapse":
1619     [
1620         "collapse",
1621         "separate"
1622     ],
1623 
1624     "overflow":
1625     [
1626         "visible",
1627         "hidden",
1628         "scroll",
1629         "auto",
1630         "-moz-hidden-unscrollable"
1631     ],
1632 
1633     "listStyleType":
1634     [
1635         "none",
1636         "disc",
1637         "circle",
1638         "square",
1639         "decimal",
1640         "decimal-leading-zero",
1641         "lower-roman",
1642         "upper-roman",
1643         "lower-greek",
1644         "lower-alpha",
1645         "lower-latin",
1646         "upper-alpha",
1647         "upper-latin",
1648         "armenian",
1649         "georgian",
1650         "hebrew",
1651         "cjk-ideographic",
1652         "hiragana",
1653         "katakana",
1654         "hiragana-iroha",
1655         "katakana-iroha",
1656         "-moz-arabic-indic",
1657         "-moz-bengali",
1658         "-moz-cjk-earthly-branch",
1659         "-moz-cjk-heavenly-stem",
1660         "-moz-devanagari",
1661         "-moz-ethiopic-halehame",
1662         "-moz-ethiopic-halehame-am",
1663         "-moz-ethiopic-halehame-ti-er",
1664         "-moz-ethiopic-halehame-ti-et",
1665         "-moz-ethiopic-numeric",
1666         "-moz-gujarati",
1667         "-moz-gurmukhi",
1668         "-moz-hangul",
1669         "-moz-hangul-consonant",
1670         "-moz-japanese-formal",
1671         "-moz-japanese-informal",
1672         "-moz-kannada",
1673         "-moz-khmer",
1674         "-moz-lao",
1675         "-moz-malayalam",
1676         "-moz-myanmar",
1677         "-moz-oriya",
1678         "-moz-persian",
1679         "-moz-simp-chinese-formal",
1680         "-moz-simp-chinese-informal",
1681         "-moz-tamil",
1682         "-moz-telugu",
1683         "-moz-thai",
1684         "-moz-trad-chinese-formal",
1685         "-moz-trad-chinese-informal",
1686         "-moz-urdu"
1687     ],
1688 
1689     "listStylePosition":
1690     [
1691         "inside",
1692         "outside"
1693     ],
1694 
1695     "string":
1696     [
1697         "open-quote",
1698         "close-quote",
1699         "no-open-quote",
1700         "no-close-quote",
1701         "url()",
1702         "attr()",
1703         "counter()",
1704         "counters()"
1705     ],
1706 
1707     "fontStyle":
1708     [
1709         "normal",
1710         "italic",
1711         "oblique"
1712     ],
1713 
1714     "fontVariant":
1715     [
1716         "normal",
1717         "small-caps"
1718     ],
1719 
1720     // Named font-weight values, worth completing in "font"
1721     "namedFontWeight":
1722     [
1723         // Absolute keywords
1724         "normal",
1725         "bold",
1726 
1727         // Relative keywords
1728         "bolder",
1729         "lighter"
1730     ],
1731 
1732     "fontWeight":
1733     [
1734         // Absolute keywords
1735         "normal",
1736         "bold",
1737 
1738         // Relative keywords
1739         "bolder",
1740         "lighter",
1741 
1742         // Numeric values
1743         "100",
1744         "200",
1745         "300",
1746         "400",
1747         "500",
1748         "600",
1749         "700",
1750         "800",
1751         "900"
1752     ],
1753 
1754     "fontSize":
1755     [
1756         // Absolute size keywords
1757         "xx-small",
1758         "x-small",
1759         "small",
1760         "medium",
1761         "large",
1762         "x-large",
1763         "xx-large",
1764 
1765         // Relative size keywords
1766         "smaller",
1767         "larger"
1768     ],
1769 
1770     "lineHeight":
1771     [
1772         "normal"
1773     ],
1774 
1775     "wordBreak":
1776     [
1777         "normal",
1778         "break-all",
1779         "keep-all"
1780     ],
1781 
1782     "fontFamily":
1783     [
1784         // Common font families
1785         "Arial",
1786         "Comic Sans MS",
1787         "Georgia",
1788         "Tahoma",
1789         "Verdana",
1790         "Times New Roman",
1791         "Trebuchet MS",
1792         "Lucida Console",
1793         "Lucida Grande",
1794         "Helvetica",
1795 
1796         // Generic font families
1797         "serif",
1798         "sans-serif",
1799         "cursive",
1800         "fantasy",
1801         "monospace",
1802 
1803         // Additional font families
1804         "caption",
1805         "icon",
1806         "menu",
1807         "message-box",
1808         "small-caption",
1809         "status-bar",
1810         "-moz-fixed"
1811     ],
1812 
1813     "mozFont":
1814     [
1815         "-moz-button",
1816         "-moz-info",
1817         "-moz-desktop",
1818         "-moz-dialog",
1819         "-moz-document",
1820         "-moz-workspace",
1821         "-moz-window",
1822         "-moz-list",
1823         "-moz-pull-down-menu",
1824         "-moz-field"
1825     ],
1826 
1827     "display":
1828     [
1829         "block",
1830         "none",
1831         "inline",
1832         "inline-block",
1833         "list-item",
1834         "marker",
1835         "run-in",
1836         "compact",
1837         "table",
1838         "inline-table",
1839         "table-row-group",
1840         "table-column",
1841         "table-column-group",
1842         "table-header-group",
1843         "table-footer-group",
1844         "table-row",
1845         "table-cell",
1846         "table-caption",
1847         "-moz-box",
1848         "-moz-compact",
1849         "-moz-deck",
1850         "-moz-grid",
1851         "-moz-grid-group",
1852         "-moz-grid-line",
1853         "-moz-groupbox",
1854         "-moz-inline-box",
1855         "-moz-inline-grid",
1856         "-moz-inline-stack",
1857         "-moz-marker",
1858         "-moz-popup",
1859         "-moz-stack"
1860     ],
1861 
1862     "elPosition":
1863     [
1864         "static",
1865         "relative",
1866         "absolute",
1867         "fixed"
1868     ],
1869 
1870     "float":
1871     [
1872         "left",
1873         "right",
1874         "none"
1875     ],
1876 
1877     "textAlign":
1878     [
1879         "left",
1880         "right",
1881         "center",
1882         "justify",
1883         "start",
1884         "end", // FF 3.6
1885 
1886         "-moz-center",
1887         "-moz-left",
1888         "-moz-right"
1889     ],
1890 
1891     "tableLayout":
1892     [
1893         "fixed",
1894         "auto"
1895     ],
1896 
1897     "textDecoration":
1898     [
1899         "none",
1900         "underline",
1901         "overline",
1902         "line-through",
1903         "blink",
1904         "-moz-anchor-decoration"
1905     ],
1906 
1907     "textTransform":
1908     [
1909         "capitalize",
1910         "lowercase",
1911         "uppercase",
1912         "none"
1913     ],
1914 
1915     "unicodeBidi":
1916     [
1917         "normal",
1918         "embed",
1919         "bidi-override",
1920         "-moz-isolate", // FF 10.0
1921         "-moz-plaintext" // FF 10.0
1922     ],
1923 
1924     "visibility":
1925     [
1926         "visible",
1927         "hidden",
1928         "collapse"
1929     ],
1930 
1931     "whiteSpace":
1932     [
1933         "normal",
1934         "pre",
1935         "nowrap",
1936         "pre-wrap", // FF 3.0
1937         "pre-line" // FF 3.5
1938     ],
1939 
1940     "verticalAlign":
1941     [
1942         "baseline",
1943         "sub",
1944         "super",
1945         "top",
1946         "middle",
1947         "bottom",
1948         "text-top",
1949         "text-bottom"
1950     ],
1951 
1952     "thickness":
1953     [
1954         "thin",
1955         "medium",
1956         "thick"
1957     ],
1958 
1959     "shape":
1960     [
1961         "rect()"
1962     ],
1963 
1964     "userFocus":
1965     [
1966         "ignore",
1967         "normal"
1968     ],
1969 
1970     "userInput":
1971     [
1972         "disabled",
1973         "enabled"
1974     ],
1975 
1976     "mozUserModify":
1977     [
1978         "read-only",
1979         "read-write",
1980         "write-only"
1981     ],
1982 
1983     "userSelect":
1984     [
1985         "text",
1986         "-moz-none",
1987         "all",
1988         "element"
1989     ],
1990 
1991     "mozBoxSizing":
1992     [
1993         "content-box",
1994         "padding-box",
1995         "border-box"
1996     ],
1997 
1998     "mozBoxAlign":
1999     [
2000         "start",
2001         "center",
2002         "end",
2003         "baseline",
2004         "stretch"
2005     ],
2006 
2007     "mozBoxDirection":
2008     [
2009         "normal",
2010         "reverse"
2011     ],
2012 
2013     "mozBoxOrient":
2014     [
2015         "horizontal",
2016         "vertical",
2017         "inline-axis",
2018         "block-axis"
2019     ],
2020 
2021     "mozBoxPack":
2022     [
2023         "start",
2024         "center",
2025         "end",
2026         "justify"
2027     ],
2028 
2029     "boxShadow":
2030     [
2031         "inset"
2032     ],
2033 
2034     "borderImageRepeat":
2035     [
2036         "stretch",
2037         "round",
2038         "repeat",
2039         "space"
2040     ],
2041 
2042     "image":
2043     [
2044         "url()",
2045         "linear-gradient()",
2046         "radial-gradient()",
2047         "repeating-linear-gradient()",
2048         "repeating-radial-gradient()",
2049         "-moz-linear-gradient()",
2050         "-moz-radial-gradient()",
2051         "-moz-repeating-linear-gradient()",
2052         "-moz-repeating-radial-gradient()",
2053         "-moz-image-rect()",
2054         "-moz-element()",
2055     ],
2056 
2057     "length":
2058     [
2059         "calc()"
2060     ],
2061 
2062     "transformFunction":
2063     [
2064         "matrix()",
2065         "matrix3d()",
2066         "rotate()",
2067         "rotateX()",
2068         "rotateY()",
2069         "rotateZ()",
2070         "scale()",
2071         "scaleX()",
2072         "scaleY()",
2073         "scaleZ()",
2074         "scale3d()",
2075         "scaleZ()",
2076         "skewX()",
2077         "skewY()",
2078         "translate()",
2079         "translateX()",
2080         "translateY()",
2081         "translateZ()"
2082     ],
2083 
2084     "mozFontFeatureSettings":
2085     [
2086         "normal",
2087         "on",
2088         "off",
2089 
2090         // Font features
2091         // Doesn't include cv01-cv99
2092         "\"aalt\"",
2093         "\"abvf\"",
2094         "\"abvm\"",
2095         "\"abvs\"",
2096         "\"afrc\"",
2097         "\"akhn\"",
2098         "\"blwf\"",
2099         "\"blwm\"",
2100         "\"blws\"",
2101         "\"calt\"",
2102         "\"case\"",
2103         "\"ccmp\"",
2104         "\"cfar\"",
2105         "\"cjct\"",
2106         "\"clig\"",
2107         "\"cpct\"",
2108         "\"cpsp\"",
2109         "\"cswh\"",
2110         "\"curs\"",
2111         "\"c2pc\"",
2112         "\"c2sc\"",
2113         "\"dist\"",
2114         "\"dlig\"",
2115         "\"dnom\"",
2116         "\"expt\"",
2117         "\"falt\"",
2118         "\"fin2\"",
2119         "\"fin3\"",
2120         "\"fina\"",
2121         "\"frac\"",
2122         "\"fwid\"",
2123         "\"half\"",
2124         "\"haln\"",
2125         "\"halt\"",
2126         "\"hist\"",
2127         "\"hkna\"",
2128         "\"hlig\"",
2129         "\"hngl\"",
2130         "\"hojo\"",
2131         "\"hwid\"",
2132         "\"init\"",
2133         "\"isol\"",
2134         "\"ital\"",
2135         "\"jalt\"",
2136         "\"jp78\"",
2137         "\"jp83\"",
2138         "\"jp90\"",
2139         "\"jp04\"",
2140         "\"kern\"",
2141         "\"lfbd\"",
2142         "\"liga\"",
2143         "\"ljmo\"",
2144         "\"lnum\"",
2145         "\"locl\"",
2146         "\"ltra\"",
2147         "\"ltrm\"",
2148         "\"mark\"",
2149         "\"med2\"",
2150         "\"medi\"",
2151         "\"mgrk\"",
2152         "\"mkmk\"",
2153         "\"mset\"",
2154         "\"nalt\"",
2155         "\"nlck\"",
2156         "\"nukt\"",
2157         "\"numr\"",
2158         "\"onum\"",
2159         "\"opbd\"",
2160         "\"ordn\"",
2161         "\"ornm\"",
2162         "\"palt\"",
2163         "\"pcap\"",
2164         "\"pkna\"",
2165         "\"pnum\"",
2166         "\"pref\"",
2167         "\"pres\"",
2168         "\"pstf\"",
2169         "\"psts\"",
2170         "\"pwid\"",
2171         "\"qwid\"",
2172         "\"rand\"",
2173         "\"rkrf\"",
2174         "\"rlig\"",
2175         "\"rphf\"",
2176         "\"rtbd\"",
2177         "\"rtla\"",
2178         "\"rtlm\"",
2179         "\"ruby\"",
2180         "\"salt\"",
2181         "\"sinf\"",
2182         "\"size\"",
2183         "\"smcp\"",
2184         "\"smpl\"",
2185         "\"ss01\"",
2186         "\"ss02\"",
2187         "\"ss03\"",
2188         "\"ss04\"",
2189         "\"ss05\"",
2190         "\"ss06\"",
2191         "\"ss07\"",
2192         "\"ss08\"",
2193         "\"ss09\"",
2194         "\"ss10\"",
2195         "\"ss11\"",
2196         "\"ss12\"",
2197         "\"ss13\"",
2198         "\"ss14\"",
2199         "\"ss15\"",
2200         "\"ss16\"",
2201         "\"ss17\"",
2202         "\"ss18\"",
2203         "\"ss19\"",
2204         "\"ss20\"",
2205         "\"subs\"",
2206         "\"sups\"",
2207         "\"swsh\"",
2208         "\"titl\"",
2209         "\"tjmo\"",
2210         "\"tnam\"",
2211         "\"tnum\"",
2212         "\"trad\"",
2213         "\"twid\"",
2214         "\"unic\"",
2215         "\"valt\"",
2216         "\"vatu\"",
2217         "\"vert\"",
2218         "\"vhal\"",
2219         "\"vjmo\"",
2220         "\"vkna\"",
2221         "\"vkrn\"",
2222         "\"vpal\"",
2223         "\"vrt2\"",
2224         "\"zero\""
2225     ],
2226 
2227     // FF 10.0
2228     "transformStyle":
2229     [
2230         "preserve-3d",
2231         "flat"
2232     ],
2233 
2234     // FF 4.0
2235     "transitionProperty":
2236     [
2237         "none",
2238         "all",
2239         "background-color",
2240         "background-image",
2241         "background-position",
2242         "background-size",
2243         "border-color",
2244         "border-radius",
2245         "border-width",
2246         "border-spacing",
2247         "bottom",
2248         "box-shadow",
2249         "color",
2250         "clip",
2251         "fill",
2252         "fill-opacity",
2253         "flood-color",
2254         "font-size",
2255         "font-size-adjust",
2256         "font-stretch",
2257         "font-weight",
2258         "height",
2259         "left",
2260         "letter-spacing",
2261         "lighting-color",
2262         "line-height",
2263         "margin ",
2264         "marker-offset",
2265         "max-height",
2266         "max-width",
2267         "min-height",
2268         "min-width",
2269         "opacity",
2270         "outline-color",
2271         "outline-offset",
2272         "outline-width",
2273         "padding",
2274         "right",
2275         "stop-color",
2276         "stop-opacity",
2277         "stroke",
2278         "stroke-dasharray",
2279         "stroke-dashoffset",
2280         "stroke-miterlimit",
2281         "stroke-opacity",
2282         "stroke-width",
2283         "text-indent",
2284         "text-shadow",
2285         "top",
2286         "transform-origin",
2287         "transform",
2288         "vertical-align",
2289         "visibility",
2290         "width",
2291         "word-spacing",
2292         "z-index",
2293         "-moz-box-flex",
2294         "-moz-column-count",
2295         "-moz-column-gap",
2296         "-moz-column-rule-color",
2297         "-moz-column-rule-width",
2298         "-moz-column-width",
2299         "-moz-image-region",
2300         "-moz-outline-radius"
2301     ],
2302 
2303     "timingFunction": // FF 4.0
2304     [
2305         "cubic-bezier()",
2306         "ease",
2307         "ease-in",
2308         "ease-in-out",
2309         "ease-out",
2310         "linear",
2311         "step-start",
2312         "step-end",
2313         "steps()"
2314     ],
2315 
2316     "mozTextDecorationLine": // FF 6.0
2317     [
2318         "underline",
2319         "overline",
2320         "line-through",
2321         "none"
2322     ],
2323 
2324     "mozTextDecorationStyle": // FF 6.0
2325     [
2326         "solid",
2327         "double",
2328         "dotted",
2329         "dashed",
2330         "wavy"
2331     ],
2332 
2333     "mozHyphens": // FF 6.0
2334     [
2335         "none",
2336         "manual",
2337         "auto"
2338     ],
2339 
2340     // FF 7.0
2341     "textOverflow":
2342     [
2343        "clip",
2344        "ellipsis"
2345     ],
2346 
2347     // FF 3.0
2348     "width":
2349     [
2350         "-moz-max-content",
2351         "-moz-min-content",
2352         "-moz-fit-content",
2353         "-moz-available"
2354     ],
2355 
2356     "imeMode":
2357     [
2358         "auto",
2359         "normal",
2360         "active",
2361         "inactive",
2362         "disabled"
2363     ],
2364 
2365     // FF 3.0
2366     "textRendering":
2367     [
2368         "auto",
2369         "optimizeSpeed",
2370         "optimizeLegibility",
2371         "geometricPrecision"
2372     ],
2373 
2374     "wordWrap":
2375     [
2376         "normal",
2377         "break-word"
2378     ],
2379 
2380     "pageBreak":
2381     [
2382         "auto",
2383         "always",
2384         "avoid",
2385         "left",
2386         "right"
2387     ],
2388 
2389     // start SVG specific
2390 
2391     "alignmentBaseline":
2392     [
2393         "auto",
2394         "baseline",
2395         "before-edge",
2396         "text-before-edge",
2397         "middle",
2398         "central",
2399         "after-edge",
2400         "text-after-edge",
2401         "ideographic",
2402         "alphabetic",
2403         "hanging",
2404         "mathematical"
2405     ],
2406 
2407     "baselineShift":
2408     [
2409         "baseline",
2410         "sub",
2411         "super"
2412     ],
2413 
2414     "colorInterpolation":
2415     [
2416         "auto",
2417         "sRGB",
2418         "linearRGB"
2419     ],
2420 
2421     "clipRule":
2422     [
2423         "nonzero",
2424         "evenodd"
2425     ],
2426 
2427     "colorProfile":
2428     [
2429         "auto",
2430         "sRGB"
2431     ],
2432 
2433     "colorRendering":
2434     [
2435         "auto",
2436         "optimizeSpeed",
2437         "optimizeQuality"
2438     ],
2439 
2440     "dominantBaseline":
2441     [
2442         "auto",
2443         "use-script",
2444         "no-change",
2445         "reset-size",
2446         "ideographic",
2447         "alphabetic",
2448         "hanging",
2449         "mathematical",
2450         "central",
2451         "middle",
2452         "text-after-edge",
2453         "text-before-edge"
2454     ],
2455 
2456     "accumulate":
2457     [
2458         "accumulate"
2459     ],
2460 
2461     "fontStretch":
2462     [
2463         "normal",
2464         "wider",
2465         "narrower",
2466         "ultra-condensed",
2467         "extra-condensed",
2468         "condensed",
2469         "semi-condensed",
2470         "semi-expanded",
2471         "expanded",
2472         "extra-expanded",
2473         "ultra-expanded"
2474     ],
2475 
2476     "imageRendering":
2477     [
2478         "auto",
2479         "optimizespeed",
2480         "optimizequality",
2481         "-moz-crisp-edges"
2482     ],
2483 
2484     "svgOverflow":
2485     [
2486         "visible",
2487         "hidden",
2488         "scroll"
2489     ],
2490 
2491     "pointerEvents":
2492     [
2493         "none",
2494         "all",
2495         "auto",
2496         "visiblePainted",
2497         "visibleFill",
2498         "visibleStroke",
2499         "visible",
2500         "painted",
2501         "fill",
2502         "stroke"
2503     ],
2504 
2505     "shapeRendering":
2506     [
2507         "optimizeSpeed",
2508         "crispEdges",
2509         "geometricPrecision"
2510     ],
2511 
2512     "strokeLinecap":
2513     [
2514         "butt",
2515         "round",
2516         "square"
2517     ],
2518 
2519     "strokeLinejoin":
2520     [
2521         "miter",
2522         "round",
2523         "bevel"
2524     ],
2525 
2526     "writingMode":
2527     [
2528         "lr-tb",
2529         "rl-tb",
2530         "tb-rl",
2531         "lr",
2532         "rl",
2533         "tb"
2534     ],
2535 
2536     "resize":
2537     [
2538         "none",
2539         "both",
2540         "horizontal",
2541         "vertical"
2542     ]
2543 };
2544 
2545 // Most common supported charsets according to http://en.wikipedia.org/wiki/Character_encoding
2546 Css.charsets =
2547 [
2548     "Big5",
2549     "Big5-HKSCS",
2550     "EUC-JP",
2551     "EUC-KR",
2552     "GB18030",
2553     "GB2312",
2554     "GBK",
2555     "ISO-2022-JP",
2556     "ISO-2022-JP-2",
2557     "ISO-2022-KR",
2558     "ISO-8859-1",
2559     "ISO-8859-2",
2560     "ISO-8859-3",
2561     "ISO-8859-4",
2562     "ISO-8859-5",
2563     "ISO-8859-6",
2564     "ISO-8859-7",
2565     "ISO-8859-8",
2566     "ISO-8859-9",
2567     "ISO-8859-10",
2568     "JIS_Encoding",
2569     "KOI8-R",
2570     "KOI8-U",
2571     "Shift_JIS",
2572     "TSCII",
2573     "UTF-8",
2574     "US-ASCII",
2575     "VISCII",
2576     "Windows-1250",
2577     "Windows-1251",
2578     "Windows-1252",
2579     "Windows-1253",
2580     "Windows-1254",
2581     "Windows-1255",
2582     "Windows-1256",
2583     "Windows-1257",
2584     "Windows-1258"
2585 ];
2586 
2587 // http://mxr.mozilla.org/mozilla-central/source/layout/style/nsCSSPseudoClassList.h
2588 // Also http://mxr.mozilla.org/mozilla-central/source/layout/style/nsCSSAnonBoxList.h
2589 // but that's not relevant for our purposes.
2590 Css.pseudoClasses =
2591 [
2592     ":active",
2593     ":checked",
2594     ":default",
2595     ":disabled",
2596     ":empty",
2597     ":enabled",
2598     ":first-child",
2599     ":first-of-type",
2600     ":focus",
2601     ":hover",
2602     ":indeterminate",
2603     ":in-range",
2604     ":invalid",
2605     ":lang()",
2606     ":last-child",
2607     ":last-of-type",
2608     ":link",
2609     ":not()",
2610     ":nth-child()",
2611     ":nth-last-child()",
2612     ":nth-last-of-type()",
2613     ":nth-of-type()",
2614     ":only-child",
2615     ":only-of-type",
2616     ":optional",
2617     ":out-of-range",
2618     ":required",
2619     ":root",
2620     ":target",
2621     ":valid",
2622     ":visited",
2623     ":-moz-any()",
2624     ":-moz-any-link",
2625     ":-moz-bound-element",
2626     ":-moz-broken",
2627     ":-moz-drag-over",
2628     ":-moz-empty-except-children-with-localname()",
2629     ":-moz-first-node",
2630     ":-moz-focusring",
2631     ":-moz-full-screen",
2632     ":-moz-full-screen-ancestor",
2633     ":-moz-handler-blocked",
2634     ":-moz-handler-clicktoplay",
2635     ":-moz-handler-crashed",
2636     ":-moz-handler-disabled",
2637     ":-moz-has-handlerref",
2638     ":-moz-is-html",
2639     ":-moz-last-node",
2640     ":-moz-loading",
2641     // ":-moz-locale-dir(ltr)", // http://bugzil.la/588996
2642     // ":-moz-locale-dir(rtl)",
2643     ":-moz-lwtheme",
2644     ":-moz-lwtheme-brighttext",
2645     ":-moz-lwtheme-darktext",
2646     ":-moz-math-increment-script-level",
2647     ":-moz-meter-optimum",
2648     ":-moz-meter-sub-optimum",
2649     ":-moz-meter-sub-sub-optimum",
2650     ":-moz-only-whitespace",
2651     ":-moz-placeholder",
2652     ":-moz-read-only",
2653     ":-moz-read-write",
2654     ":-moz-submit-invalid",
2655     ":-moz-suppressed",
2656     ":-moz-system-metric(images-in-menus)",
2657     ":-moz-system-metric(mac-graphite-theme)",
2658     ":-moz-system-metric(scrollbar-end-backward)",
2659     ":-moz-system-metric(scrollbar-end-forward)",
2660     ":-moz-system-metric(scrollbar-start-backward)",
2661     ":-moz-system-metric(scrollbar-start-forward)",
2662     ":-moz-system-metric(scrollbar-thumb-proportional)",
2663     ":-moz-system-metric(touch-enabled)",
2664     ":-moz-system-metric(windows-default-theme)",
2665     ":-moz-table-border-nonzero",
2666     ":-moz-type-unsupported",
2667     ":-moz-ui-invalid",
2668     ":-moz-ui-valid",
2669     ":-moz-user-disabled",
2670     ":-moz-window-inactive"
2671 ];
2672 
2673 // http://mxr.mozilla.org/mozilla-central/source/browser/devtools/styleinspector/CssLogic.jsm
2674 Css.pseudoElements =
2675 [
2676     "::after",
2677     "::before",
2678     "::first-letter",
2679     "::first-line",
2680     "::selection",
2681     "::-moz-focus-inner",
2682     "::-moz-focus-outer",
2683     "::-moz-list-bullet",
2684     "::-moz-list-number",
2685     "::-moz-math-anonymous",
2686     "::-moz-math-stretchy",
2687     "::-moz-progress-bar",
2688     "::-moz-selection"
2689 ];
2690 
2691 Css.nonEditableTags =
2692 {
2693     "HTML": 1, "html": 1,
2694     "HEAD": 1, "head": 1
2695 };
2696 
2697 Css.innerEditableTags =
2698 {
2699     "BODY": 1, "body": 1
2700 };
2701 
2702 Css.nonDeletableTags =
2703 {
2704     "HTML": 1, "html": 1,
2705     "HEAD": 1, "head": 1,
2706     "BODY": 1, "body": 1
2707 };
2708 
2709 // ********************************************************************************************* //
2710 // Registration
2711 
2712 return Css;
2713 
2714 // ********************************************************************************************* //
2715 });
2716