Вход Регистрация
Файл: modules/public/js/cssParser.js
Строк: 5601
<?php
/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is mozilla.org code.
 *
 * The Initial Developer of the Original Code is
 * Netscape Communications Corporation.
 * Portions created by the Initial Developer are Copyright (C) 1998
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *   emk <VYV03354@nifty.ne.jp>
 *   Daniel Glazman <glazman@netscape.com>
 *   L. David Baron <dbaron@dbaron.org>
 *   Boris Zbarsky <bzbarsky@mit.edu>
 *   Mats Palmgren <mats.palmgren@bredband.net>
 *   Christian Biesinger <cbiesinger@web.de>
 *   Jeff Walden <jwalden+code@mit.edu>
 *   Jonathon Jongsma <jonathon.jongsma@collabora.co.uk>, Collabora Ltd.
 *   Siraj Razick <siraj.razick@collabora.co.uk>, Collabora Ltd.
 *   Daniel Glazman <daniel.glazman@disruptive-innovations.com>
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either of the GNU General Public License Version 2 or later (the "GPL"),
 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

;
var 
kCHARSET_RULE_MISSING_SEMICOLON "Missing semicolon at the end of @charset rule";
var 
kCHARSET_RULE_CHARSET_IS_STRING "The charset in the @charset rule should be a string";
var 
kCHARSET_RULE_MISSING_WS "Missing mandatory whitespace after @charset";
var 
kIMPORT_RULE_MISSING_URL "Missing URL in @import rule";
var 
kURL_EOF "Unexpected end of stylesheet";
var 
kURL_WS_INSIDE "Multiple tokens inside a url() notation";
var 
kVARIABLES_RULE_POSITION "@variables rule invalid at this position in the stylesheet";
var 
kIMPORT_RULE_POSITION "@import rule invalid at this position in the stylesheet";
var 
kNAMESPACE_RULE_POSITION "@namespace rule invalid at this position in the stylesheet";
var 
kCHARSET_RULE_CHARSET_SOF "@charset rule invalid at this position in the stylesheet";
var 
kUNKNOWN_AT_RULE "Unknow @-rule";

/* FROM http://peter.sh/data/vendor-prefixed-css.php?js=1 */

var kENGINES = [
  
"webkit",
  
"presto",
  
"trident",
  
"generic"
];

var 
kCSS_VENDOR_VALUES = {
  
"-moz-box":             {"webkit""-webkit-box",        "presto""""trident""""generic""box" },
  
"-moz-inline-box":      {"webkit""-webkit-inline-box""presto""""trident""""generic""inline-box" },
  
"-moz-initial":         {"webkit""",                   "presto""""trident""""generic""initial" },
  
"-moz-linear-gradient": {"webkit20110101"FilterLinearGradientForOutput,
                           
"webkit"FilterLinearGradientForOutput,
                           
"presto""",
                           
"trident""",
                           
"generic"FilterLinearGradientForOutput },
  
"-moz-radial-gradient": {"webkit20110101"FilterRadialGradientForOutput,
                           
"webkit"FilterRadialGradientForOutput,
                           
"presto""",
                           
"trident""",
                           
"generic"FilterRadialGradientForOutput },
  
"-moz-repeating-linear-gradient": {"webkit20110101""",
                           
"webkit"FilterRepeatingGradientForOutput,
                           
"presto""",
                           
"trident""",
                           
"generic"FilterRepeatingGradientForOutput },
  
"-moz-repeating-radial-gradient": {"webkit20110101""",
                           
"webkit"FilterRepeatingGradientForOutput,
                           
"presto""",
                           
"trident""",
                           
"generic"FilterRepeatingGradientForOutput }
};

var 
kCSS_VENDOR_PREFIXES = {"lastUpdate":1304175007,"properties":[{"gecko":"","webkit":"","presto":"","trident":"-ms-accelerator","status":"P"},
{
"gecko":"","webkit":"","presto":"-wap-accesskey","trident":"","status":""},
{
"gecko":"-moz-animation","webkit":"-webkit-animation","presto":"","trident":"","status":"WD"},
{
"gecko":"-moz-animation-delay","webkit":"-webkit-animation-delay","presto":"","trident":"","status":"WD"},
{
"gecko":"-moz-animation-direction","webkit":"-webkit-animation-direction","presto":"","trident":"","status":"WD"},
{
"gecko":"-moz-animation-duration","webkit":"-webkit-animation-duration","presto":"","trident":"","status":"WD"},
{
"gecko":"-moz-animation-fill-mode","webkit":"-webkit-animation-fill-mode","presto":"","trident":"","status":"ED"},
{
"gecko":"-moz-animation-iteration-count","webkit":"-webkit-animation-iteration-count","presto":"","trident":"","status":"WD"},
{
"gecko":"-moz-animation-name","webkit":"-webkit-animation-name","presto":"","trident":"","status":"WD"},
{
"gecko":"-moz-animation-play-state","webkit":"-webkit-animation-play-state","presto":"","trident":"","status":"WD"},
{
"gecko":"-moz-animation-timing-function","webkit":"-webkit-animation-timing-function","presto":"","trident":"","status":"WD"},
{
"gecko":"-moz-appearance","webkit":"-webkit-appearance","presto":"","trident":"","status":"CR"},
{
"gecko":"","webkit":"-webkit-backface-visibility","presto":"","trident":"","status":"WD"},
{
"gecko":"background-clip","webkit":"-webkit-background-clip","presto":"background-clip","trident":"background-clip","status":"WD"},
{
"gecko":"","webkit":"-webkit-background-composite","presto":"","trident":"","status":""},
{
"gecko":"-moz-background-inline-policy","webkit":"","presto":"","trident":"","status":"P"},
{
"gecko":"background-origin","webkit":"-webkit-background-origin","presto":"background-origin","trident":"background-origin","status":"WD"},
{
"gecko":"","webkit":"background-position-x","presto":"","trident":"-ms-background-position-x","status":""},
{
"gecko":"","webkit":"background-position-y","presto":"","trident":"-ms-background-position-y","status":""},
{
"gecko":"background-size","webkit":"-webkit-background-size","presto":"background-size","trident":"background-size","status":"WD"},
{
"gecko":"","webkit":"","presto":"","trident":"-ms-behavior","status":""},
{
"gecko":"-moz-binding","webkit":"","presto":"","trident":"","status":"P"},
{
"gecko":"","webkit":"","presto":"","trident":"-ms-block-progression","status":""},
{
"gecko":"","webkit":"-webkit-border-after","presto":"","trident":"","status":"ED"},
{
"gecko":"","webkit":"-webkit-border-after-color","presto":"","trident":"","status":"ED"},
{
"gecko":"","webkit":"-webkit-border-after-style","presto":"","trident":"","status":"ED"},
{
"gecko":"","webkit":"-webkit-border-after-width","presto":"","trident":"","status":"ED"},
{
"gecko":"","webkit":"-webkit-border-before","presto":"","trident":"","status":"ED"},
{
"gecko":"","webkit":"-webkit-border-before-color","presto":"","trident":"","status":"ED"},
{
"gecko":"","webkit":"-webkit-border-before-style","presto":"","trident":"","status":"ED"},
{
"gecko":"","webkit":"-webkit-border-before-width","presto":"","trident":"","status":"ED"},
{
"gecko":"-moz-border-bottom-colors","webkit":"","presto":"","trident":"","status":"P"},
{
"gecko":"border-bottom-left-radius","webkit":"-webkit-border-bottom-left-radius","presto":"border-bottom-left-radius","trident":"border-bottom-left-radius","status":"WD"},
{
"gecko":"","webkit":"-webkit-border-bottom-left-radius = border-bottom-left-radius","presto":"","trident":"","status":""},
{
"gecko":"border-bottom-right-radius","webkit":"-webkit-border-bottom-right-radius","presto":"border-bottom-right-radius","trident":"border-bottom-right-radius","status":"WD"},
{
"gecko":"","webkit":"-webkit-border-bottom-right-radius = border-bottom-right-radius","presto":"","trident":"","status":""},
{
"gecko":"-moz-border-end","webkit":"-webkit-border-end","presto":"","trident":"","status":"ED"},
{
"gecko":"-moz-border-end-color","webkit":"-webkit-border-end-color","presto":"","trident":"","status":"ED"},
{
"gecko":"-moz-border-end-style","webkit":"-webkit-border-end-style","presto":"","trident":"","status":"ED"},
{
"gecko":"-moz-border-end-width","webkit":"-webkit-border-end-width","presto":"","trident":"","status":"ED"},
{
"gecko":"","webkit":"-webkit-border-fit","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-border-horizontal-spacing","presto":"","trident":"","status":""},
{
"gecko":"-moz-border-image","webkit":"-webkit-border-image","presto":"-o-border-image","trident":"","status":"WD"},
{
"gecko":"-moz-border-left-colors","webkit":"","presto":"","trident":"","status":"P"},
{
"gecko":"border-radius","webkit":"-webkit-border-radius","presto":"border-radius","trident":"border-radius","status":"WD"},
{
"gecko":"-moz-border-right-colors","webkit":"","presto":"","trident":"","status":"P"},
{
"gecko":"-moz-border-start","webkit":"-webkit-border-start","presto":"","trident":"","status":"ED"},
{
"gecko":"-moz-border-start-color","webkit":"-webkit-border-start-color","presto":"","trident":"","status":"ED"},
{
"gecko":"-moz-border-start-style","webkit":"-webkit-border-start-style","presto":"","trident":"","status":"ED"},
{
"gecko":"-moz-border-start-width","webkit":"-webkit-border-start-width","presto":"","trident":"","status":"ED"},
{
"gecko":"-moz-border-top-colors","webkit":"","presto":"","trident":"","status":"P"},
{
"gecko":"border-top-left-radius","webkit":"-webkit-border-top-left-radius","presto":"border-top-left-radius","trident":"border-top-left-radius","status":"WD"},
{
"gecko":"","webkit":"-webkit-border-top-left-radius = border-top-left-radius","presto":"","trident":"","status":""},
{
"gecko":"border-top-right-radius","webkit":"-webkit-border-top-right-radius","presto":"border-top-right-radius","trident":"border-top-right-radius","status":"WD"},
{
"gecko":"","webkit":"-webkit-border-top-right-radius = border-top-right-radius","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-border-vertical-spacing","presto":"","trident":"","status":""},
{
"gecko":"-moz-box-align","webkit":"-webkit-box-align","presto":"","trident":"-ms-box-align","status":"WD"},
{
"gecko":"-moz-box-direction","webkit":"-webkit-box-direction","presto":"","trident":"-ms-box-direction","status":"WD"},
{
"gecko":"-moz-box-flex","webkit":"-webkit-box-flex","presto":"","trident":"-ms-box-flex","status":"WD"},
{
"gecko":"","webkit":"-webkit-box-flex-group","presto":"","trident":"","status":"WD"},
{
"gecko":"","webkit":"","presto":"","trident":"-ms-box-line-progression","status":""},
{
"gecko":"","webkit":"-webkit-box-lines","presto":"","trident":"-ms-box-lines","status":"WD"},
{
"gecko":"-moz-box-ordinal-group","webkit":"-webkit-box-ordinal-group","presto":"","trident":"-ms-box-ordinal-group","status":"WD"},
{
"gecko":"-moz-box-orient","webkit":"-webkit-box-orient","presto":"","trident":"-ms-box-orient","status":"WD"},
{
"gecko":"-moz-box-pack","webkit":"-webkit-box-pack","presto":"","trident":"-ms-box-pack","status":"WD"},
{
"gecko":"","webkit":"-webkit-box-reflect","presto":"","trident":"","status":""},
{
"gecko":"box-shadow","webkit":"-webkit-box-shadow","presto":"box-shadow","trident":"box-shadow","status":"WD"},
{
"gecko":"-moz-box-sizing","webkit":"box-sizing","presto":"box-sizing","trident":"","status":"CR"},
{
"gecko":"","webkit":"-webkit-box-sizing = box-sizing","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-epub-caption-side = caption-side","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-color-correction","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-column-break-after","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-column-break-before","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-column-break-inside","presto":"","trident":"","status":""},
{
"gecko":"-moz-column-count","webkit":"-webkit-column-count","presto":"column-count","trident":"column-count","status":"CR"},
{
"gecko":"-moz-column-gap","webkit":"-webkit-column-gap","presto":"column-gap","trident":"column-gap","status":"CR"},
{
"gecko":"-moz-column-rule","webkit":"-webkit-column-rule","presto":"column-rule","trident":"column-rule","status":"CR"},
{
"gecko":"-moz-column-rule-color","webkit":"-webkit-column-rule-color","presto":"column-rule-color","trident":"column-rule-color","status":"CR"},
{
"gecko":"-moz-column-rule-style","webkit":"-webkit-column-rule-style","presto":"column-rule-style","trident":"column-rule-style","status":"CR"},
{
"gecko":"-moz-column-rule-width","webkit":"-webkit-column-rule-width","presto":"column-rule-width","trident":"column-rule-width","status":"CR"},
{
"gecko":"","webkit":"-webkit-column-span","presto":"column-span","trident":"column-span","status":"CR"},
{
"gecko":"-moz-column-width","webkit":"-webkit-column-width","presto":"column-width","trident":"column-width","status":"CR"},
{
"gecko":"","webkit":"-webkit-columns","presto":"columns","trident":"columns","status":"CR"},
{
"gecko":"","webkit":"-webkit-dashboard-region","presto":"-apple-dashboard-region","trident":"","status":""},
{
"gecko":"filter","webkit":"","presto":"filter","trident":"-ms-filter","status":""},
{
"gecko":"-moz-float-edge","webkit":"","presto":"","trident":"","status":"P"},
{
"gecko":"","webkit":"","presto":"-o-focus-opacity","trident":"","status":""},
{
"gecko":"-moz-font-feature-settings","webkit":"","presto":"","trident":"","status":""},
{
"gecko":"-moz-font-language-override","webkit":"","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-font-size-delta","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-font-smoothing","presto":"","trident":"","status":""},
{
"gecko":"-moz-force-broken-image-icon","webkit":"","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"","presto":"","trident":"-ms-grid-column","status":"WD"},
{
"gecko":"","webkit":"","presto":"","trident":"-ms-grid-column-align","status":"WD"},
{
"gecko":"","webkit":"","presto":"","trident":"-ms-grid-column-span","status":"WD"},
{
"gecko":"","webkit":"","presto":"","trident":"-ms-grid-columns","status":"WD"},
{
"gecko":"","webkit":"","presto":"","trident":"-ms-grid-layer","status":"WD"},
{
"gecko":"","webkit":"","presto":"","trident":"-ms-grid-row","status":"WD"},
{
"gecko":"","webkit":"","presto":"","trident":"-ms-grid-row-align","status":"WD"},
{
"gecko":"","webkit":"","presto":"","trident":"-ms-grid-row-span","status":"WD"},
{
"gecko":"","webkit":"","presto":"","trident":"-ms-grid-rows","status":"WD"},
{
"gecko":"","webkit":"-webkit-highlight","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-hyphenate-character","presto":"","trident":"","status":"WD"},
{
"gecko":"","webkit":"-webkit-hyphenate-limit-after","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-hyphenate-limit-before","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-hyphens","presto":"","trident":"","status":"WD"},
{
"gecko":"","webkit":"-epub-hyphens = -webkit-hyphens","presto":"","trident":"","status":""},
{
"gecko":"-moz-image-region","webkit":"","presto":"","trident":"","status":"P"},
{
"gecko":"ime-mode","webkit":"","presto":"","trident":"-ms-ime-mode","status":""},
{
"gecko":"","webkit":"","presto":"-wap-input-format","trident":"","status":""},
{
"gecko":"","webkit":"","presto":"-wap-input-required","trident":"","status":""},
{
"gecko":"","webkit":"","presto":"","trident":"-ms-interpolation-mode","status":""},
{
"gecko":"","webkit":"","presto":"-xv-interpret-as","trident":"","status":""},
{
"gecko":"","webkit":"","presto":"","trident":"-ms-layout-flow","status":""},
{
"gecko":"","webkit":"","presto":"","trident":"-ms-layout-grid","status":""},
{
"gecko":"","webkit":"","presto":"","trident":"-ms-layout-grid-char","status":""},
{
"gecko":"","webkit":"","presto":"","trident":"-ms-layout-grid-line","status":""},
{
"gecko":"","webkit":"","presto":"","trident":"-ms-layout-grid-mode","status":""},
{
"gecko":"","webkit":"","presto":"","trident":"-ms-layout-grid-type","status":""},
{
"gecko":"","webkit":"-webkit-line-box-contain","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-line-break","presto":"","trident":"-ms-line-break","status":""},
{
"gecko":"","webkit":"-webkit-line-clamp","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"","presto":"","trident":"-ms-line-grid-mode","status":""},
{
"gecko":"","webkit":"","presto":"-o-link","trident":"","status":""},
{
"gecko":"","webkit":"","presto":"-o-link-source","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-locale","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-logical-height","presto":"","trident":"","status":"ED"},
{
"gecko":"","webkit":"-webkit-logical-width","presto":"","trident":"","status":"ED"},
{
"gecko":"","webkit":"-webkit-margin-after","presto":"","trident":"","status":"ED"},
{
"gecko":"","webkit":"-webkit-margin-after-collapse","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-margin-before","presto":"","trident":"","status":"ED"},
{
"gecko":"","webkit":"-webkit-margin-before-collapse","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-margin-bottom-collapse","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-margin-collapse","presto":"","trident":"","status":""},
{
"gecko":"-moz-margin-end","webkit":"-webkit-margin-end","presto":"","trident":"","status":"ED"},
{
"gecko":"-moz-margin-start","webkit":"-webkit-margin-start","presto":"","trident":"","status":"ED"},
{
"gecko":"","webkit":"-webkit-margin-top-collapse","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-marquee","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"","presto":"-wap-marquee-dir","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-marquee-direction","presto":"","trident":"","status":"WD"},
{
"gecko":"","webkit":"-webkit-marquee-increment","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"","presto":"-wap-marquee-loop","trident":"","status":"WD"},
{
"gecko":"","webkit":"-webkit-marquee-repetition","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-marquee-speed","presto":"-wap-marquee-speed","trident":"","status":"WD"},
{
"gecko":"","webkit":"-webkit-marquee-style","presto":"-wap-marquee-style","trident":"","status":"WD"},
{
"gecko":"mask","webkit":"-webkit-mask","presto":"mask","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-mask-attachment","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-mask-box-image","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-mask-clip","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-mask-composite","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-mask-image","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-mask-origin","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-mask-position","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-mask-position-x","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-mask-position-y","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-mask-repeat","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-mask-repeat-x","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-mask-repeat-y","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-mask-size","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-match-nearest-mail-blockquote-color","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-max-logical-height","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-max-logical-width","presto":"","trident":"","status":"ED"},
{
"gecko":"","webkit":"-webkit-min-logical-height","presto":"","trident":"","status":"ED"},
{
"gecko":"","webkit":"-webkit-min-logical-width","presto":"","trident":"","status":"ED"},
{
"gecko":"","webkit":"","presto":"-o-mini-fold","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-nbsp-mode","presto":"","trident":"","status":"P"},
{
"gecko":"","webkit":"","presto":"-o-object-fit","trident":"","status":"ED"},
{
"gecko":"","webkit":"","presto":"-o-object-position","trident":"","status":"ED"},
{
"gecko":"opacity","webkit":"-webkit-opacity","presto":"opacity","trident":"opacity","status":"WD"},
{
"gecko":"","webkit":"-webkit-opacity = opacity","presto":"","trident":"","status":""},
{
"gecko":"-moz-outline-radius","webkit":"","presto":"","trident":"","status":"P"},
{
"gecko":"-moz-outline-radius-bottomleft","webkit":"","presto":"","trident":"","status":"P"},
{
"gecko":"-moz-outline-radius-bottomright","webkit":"","presto":"","trident":"","status":"P"},
{
"gecko":"-moz-outline-radius-topleft","webkit":"","presto":"","trident":"","status":"P"},
{
"gecko":"-moz-outline-radius-topright","webkit":"","presto":"","trident":"","status":"P"},
{
"gecko":"overflow-x","webkit":"overflow-x","presto":"overflow-x","trident":"-ms-overflow-x","status":"WD"},
{
"gecko":"overflow-y","webkit":"overflow-y","presto":"overflow-y","trident":"-ms-overflow-y","status":"WD"},
{
"gecko":"","webkit":"-webkit-padding-after","presto":"","trident":"","status":"ED"},
{
"gecko":"","webkit":"-webkit-padding-before","presto":"","trident":"","status":"ED"},
{
"gecko":"-moz-padding-end","webkit":"-webkit-padding-end","presto":"","trident":"","status":"ED"},
{
"gecko":"-moz-padding-start","webkit":"-webkit-padding-start","presto":"","trident":"","status":"ED"},
{
"gecko":"","webkit":"-webkit-perspective","presto":"","trident":"","status":"WD"},
{
"gecko":"","webkit":"-webkit-perspective-origin","presto":"","trident":"","status":"WD"},
{
"gecko":"","webkit":"-webkit-perspective-origin-x","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-perspective-origin-y","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"","presto":"-xv-phonemes","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-rtl-ordering","presto":"","trident":"","status":"P"},
{
"gecko":"-moz-script-level","webkit":"","presto":"","trident":"","status":""},
{
"gecko":"-moz-script-min-size","webkit":"","presto":"","trident":"","status":""},
{
"gecko":"-moz-script-size-multiplier","webkit":"","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"","presto":"scrollbar-3dlight-color","trident":"-ms-scrollbar-3dlight-color","status":"P"},
{
"gecko":"","webkit":"","presto":"scrollbar-arrow-color","trident":"-ms-scrollbar-arrow-color","status":"P"},
{
"gecko":"","webkit":"","presto":"scrollbar-base-color","trident":"-ms-scrollbar-base-color","status":"P"},
{
"gecko":"","webkit":"","presto":"scrollbar-darkshadow-color","trident":"-ms-scrollbar-darkshadow-color","status":"P"},
{
"gecko":"","webkit":"","presto":"scrollbar-face-color","trident":"-ms-scrollbar-face-color","status":"P"},
{
"gecko":"","webkit":"","presto":"scrollbar-highlight-color","trident":"-ms-scrollbar-highlight-color","status":"P"},
{
"gecko":"","webkit":"","presto":"scrollbar-shadow-color","trident":"-ms-scrollbar-shadow-color","status":"P"},
{
"gecko":"","webkit":"","presto":"scrollbar-track-color","trident":"-ms-scrollbar-track-color","status":"P"},
{
"gecko":"-moz-stack-sizing","webkit":"","presto":"","trident":"","status":"P"},
{
"gecko":"","webkit":"-webkit-svg-shadow","presto":"","trident":"","status":""},
{
"gecko":"-moz-tab-size","webkit":"","presto":"-o-tab-size","trident":"","status":""},
{
"gecko":"","webkit":"","presto":"-o-table-baseline","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-tap-highlight-color","presto":"","trident":"","status":"P"},
{
"gecko":"","webkit":"","presto":"","trident":"-ms-text-align-last","status":"WD"},
{
"gecko":"","webkit":"","presto":"","trident":"-ms-text-autospace","status":"WD"},
{
"gecko":"-moz-text-blink","webkit":"","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-text-combine","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-epub-text-combine = -webkit-text-combine","presto":"","trident":"","status":""},
{
"gecko":"-moz-text-decoration-color","webkit":"","presto":"","trident":"","status":""},
{
"gecko":"-moz-text-decoration-line","webkit":"","presto":"","trident":"","status":""},
{
"gecko":"-moz-text-decoration-style","webkit":"","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-text-decorations-in-effect","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-text-emphasis","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-epub-text-emphasis = -webkit-text-emphasis","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-text-emphasis-color","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-epub-text-emphasis-color = -webkit-text-emphasis-color","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-text-emphasis-position","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-text-emphasis-style","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-epub-text-emphasis-style = -webkit-text-emphasis-style","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-webkit-text-fill-color","presto":"","trident":"","status":"P"},
{
"gecko":"","webkit":"","presto":"","trident":"-ms-text-justify","status":"WD"},
{
"gecko":"","webkit":"","presto":"","trident":"-ms-text-kashida-space","status":"P"},
{
"gecko":"","webkit":"-webkit-text-orientation","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"-epub-text-orientation = -webkit-text-orientation","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"text-overflow","presto":"text-overflow","trident":"-ms-text-overflow","status":"WD"},
{
"gecko":"","webkit":"-webkit-text-security","presto":"","trident":"","status":"P"},
{
"gecko":"","webkit":"-webkit-text-size-adjust","presto":"","trident":"-ms-text-size-adjust","status":""},
{
"gecko":"","webkit":"-webkit-text-stroke","presto":"","trident":"","status":"P"},
{
"gecko":"","webkit":"-webkit-text-stroke-color","presto":"","trident":"","status":"P"},
{
"gecko":"","webkit":"-webkit-text-stroke-width","presto":"","trident":"","status":"P"},
{
"gecko":"","webkit":"-epub-text-transform = text-transform","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"","presto":"","trident":"-ms-text-underline-position","status":"P"},
{
"gecko":"","webkit":"-webkit-touch-callout","presto":"","trident":"","status":"P"},
{
"gecko":"-moz-transform","webkit":"-webkit-transform","presto":"-o-transform","trident":"-ms-transform","status":"WD"},
{
"gecko":"-moz-transform-origin","webkit":"-webkit-transform-origin","presto":"-o-transform-origin","trident":"-ms-transform-origin","status":"WD"},
{
"gecko":"","webkit":"-webkit-transform-origin-x","presto":"","trident":"","status":"P"},
{
"gecko":"","webkit":"-webkit-transform-origin-y","presto":"","trident":"","status":"P"},
{
"gecko":"","webkit":"-webkit-transform-origin-z","presto":"","trident":"","status":"P"},
{
"gecko":"","webkit":"-webkit-transform-style","presto":"","trident":"","status":"WD"},
{
"gecko":"-moz-transition","webkit":"-webkit-transition","presto":"-o-transition","trident":"","status":"WD"},
{
"gecko":"-moz-transition-delay","webkit":"-webkit-transition-delay","presto":"-o-transition-delay","trident":"","status":"WD"},
{
"gecko":"-moz-transition-duration","webkit":"-webkit-transition-duration","presto":"-o-transition-duration","trident":"","status":"WD"},
{
"gecko":"-moz-transition-property","webkit":"-webkit-transition-property","presto":"-o-transition-property","trident":"","status":"WD"},
{
"gecko":"-moz-transition-timing-function","webkit":"-webkit-transition-timing-function","presto":"-o-transition-timing-function","trident":"","status":"WD"},
{
"gecko":"","webkit":"-webkit-user-drag","presto":"","trident":"","status":"P"},
{
"gecko":"-moz-user-focus","webkit":"","presto":"","trident":"","status":"P"},
{
"gecko":"-moz-user-input","webkit":"","presto":"","trident":"","status":"P"},
{
"gecko":"-moz-user-modify","webkit":"-webkit-user-modify","presto":"","trident":"","status":"P"},
{
"gecko":"-moz-user-select","webkit":"-webkit-user-select","presto":"","trident":"","status":"P"},
{
"gecko":"","webkit":"","presto":"-xv-voice-balance","trident":"","status":""},
{
"gecko":"","webkit":"","presto":"-xv-voice-duration","trident":"","status":""},
{
"gecko":"","webkit":"","presto":"-xv-voice-pitch","trident":"","status":""},
{
"gecko":"","webkit":"","presto":"-xv-voice-pitch-range","trident":"","status":""},
{
"gecko":"","webkit":"","presto":"-xv-voice-rate","trident":"","status":""},
{
"gecko":"","webkit":"","presto":"-xv-voice-stress","trident":"","status":""},
{
"gecko":"","webkit":"","presto":"-xv-voice-volume","trident":"","status":""},
{
"gecko":"-moz-window-shadow","webkit":"","presto":"","trident":"","status":"P"},
{
"gecko":"","webkit":"word-break","presto":"","trident":"-ms-word-break","status":"WD"},
{
"gecko":"","webkit":"-epub-word-break = word-break","presto":"","trident":"","status":""},
{
"gecko":"word-wrap","webkit":"word-wrap","presto":"word-wrap","trident":"-ms-word-wrap","status":"WD"},
{
"gecko":"","webkit":"-webkit-writing-mode","presto":"writing-mode","trident":"-ms-writing-mode","status":"ED"},
{
"gecko":"","webkit":"-epub-writing-mode = -webkit-writing-mode","presto":"","trident":"","status":""},
{
"gecko":"","webkit":"zoom","presto":"","trident":"-ms-zoom","status":""}]};

var 
kCSS_PREFIXED_VALUE = [
  {
"gecko""-moz-box""webkit""-moz-box""presto""""trident""""generic""box"}
];

var 
CssInspector = {

  
mVENDOR_PREFIXESnull,

  
kEXPORTS_FOR_GECKO:   true,
  
kEXPORTS_FOR_WEBKIT:  true,
  
kEXPORTS_FOR_PRESTO:  true,
  
kEXPORTS_FOR_TRIDENTtrue,

  
cleanPrefixes: function()
  {
    
this.mVENDOR_PREFIXES null;
  },

  
prefixesForProperty: function(aProperty)
  {
    if (!
this.mVENDOR_PREFIXES) {

      
this.mVENDOR_PREFIXES = {};
      for (var 
0kCSS_VENDOR_PREFIXES.properties.lengthi++) {
        var 
kCSS_VENDOR_PREFIXES.properties[i];
        if (
p.gecko && (p.webkit || p.presto || p.trident)) {
          var 
= {};
          if (
this.kEXPORTS_FOR_GECKOo[p.gecko] = true;
          if (
this.kEXPORTS_FOR_WEBKIT && p.webkit)  o[p.webkit] = true;
          if (
this.kEXPORTS_FOR_PRESTO && p.presto)  o[p.presto] = true;
          if (
this.kEXPORTS_FOR_TRIDENT && p.tridento[p.trident] = true;
          
this.mVENDOR_PREFIXES[p.gecko] = [];
          for (var 
j in o)
            
this.mVENDOR_PREFIXES[p.gecko].push(j)
        }
      }
    }
    if (
aProperty in this.mVENDOR_PREFIXES)
      return 
this.mVENDOR_PREFIXES[aProperty].sort();
    return 
null;
  },

  
parseColorStop: function(parsertoken)
  {
    var 
color parser.parseColor(token);
    var 
position "";
    if (!
color)
      return 
null;
    
token parser.getToken(truetrue);
    if (
token.isPercentage() ||
        
token.isDimensionOfUnit("cm") ||
        
token.isDimensionOfUnit("mm") ||
        
token.isDimensionOfUnit("in") ||
        
token.isDimensionOfUnit("pc") ||
        
token.isDimensionOfUnit("px") ||
        
token.isDimensionOfUnit("em") ||
        
token.isDimensionOfUnit("ex") ||
        
token.isDimensionOfUnit("pt")) {
      
position token.value;
      
token parser.getToken(truetrue);
    }
    return { 
colorcolorpositionposition }
  },

  
parseGradient: function (parsertoken)
  {
    var 
isRadial false;
    var 
gradient = { isRepeatingfalse };
    if (
token.isNotNull()) {
      if (
token.isFunction("-moz-linear-gradient(") ||
          
token.isFunction("-moz-radial-gradient(") ||
          
token.isFunction("-moz-repeating-linear-gradient(") ||
          
token.isFunction("-moz-repeating-radial-gradient(")) {
        if (
token.isFunction("-moz-radial-gradient(") ||
            
token.isFunction("-moz-repeating-radial-gradient(")) {
          
gradient.isRadial true;
        }
        if (
token.isFunction("-moz-repeating-linear-gradient(") ||
            
token.isFunction("-moz-repeating-radial-gradient(")) {
          
gradient.isRepeating true;
        }
        

        
token parser.getToken(truetrue);
        var 
haveGradientLine false;
        var 
foundHorizPosition false;
        var 
haveAngle false;

        if (
token.isAngle()) {
          
gradient.angle token.value;
          
haveGradientLine true;
          
haveAngle true;
          
token parser.getToken(truetrue);
        }

        if (
token.isLength()
            || 
token.isIdent("top")
            || 
token.isIdent("center")
            || 
token.isIdent("bottom")
            || 
token.isIdent("left")
            || 
token.isIdent("right")) {
          
haveGradientLine true;
          if (
token.isLength()
            || 
token.isIdent("left")
            || 
token.isIdent("right")) {
            
foundHorizPosition true;
          }
          
gradient.position token.value;
          
token parser.getToken(truetrue);
        }

        if (
haveGradientLine) {
          if (!
haveAngle && token.isAngle()) { // we have an angle here
            
gradient.angle token.value;
            
haveAngle true;
            
token parser.getToken(truetrue);
          }

          else if (
token.isLength()
                  || (
foundHorizPosition && (token.isIdent("top")
                                             || 
token.isIdent("center")
                                             || 
token.isIdent("bottom")))
                  || (!
foundHorizPosition && (token.isLength()
                                              || 
token.isIdent("top")
                                              || 
token.isIdent("center")
                                              || 
token.isIdent("bottom")
                                              || 
token.isIdent("left")
                                              || 
token.isIdent("right")))) {
            
gradient.position = ("position" in gradient) ? gradient.position " """;
            
gradient.position += token.value;
            
token parser.getToken(truetrue);
          }

          if (!
haveAngle && token.isAngle()) { // we have an angle here
            
gradient.angle token.value;
            
haveAngle true;
            
token parser.getToken(truetrue);
          }

          
// we must find a comma here
          
if (!token.isSymbol(","))
            return 
null;
          
token parser.getToken(truetrue);
        }

        
// ok... Let's deal with the rest now
        
if (gradient.isRadial) {
          if (
token.isIdent("circle") ||
              
token.isIdent("ellipse")) {
            
gradient.shape token.value;
            
token parser.getToken(truetrue);
          }
          if (
token.isIdent("closest-side") ||
                   
token.isIdent("closest-corner") ||
                   
token.isIdent("farthest-side") ||
                   
token.isIdent("farthest-corner") ||
                   
token.isIdent("contain") ||
                   
token.isIdent("cover")) {
            
gradient.size token.value;
            
token parser.getToken(truetrue);
          }
          if (!(
"shape" in gradient) &&
              (
token.isIdent("circle") ||
               
token.isIdent("ellipse"))) {
            
// we can still have the second value...
            
gradient.shape token.value;
            
token parser.getToken(truetrue);
          }
          if (((
"shape" in gradient) || ("size" in gradient)) && !token.isSymbol(","))
            return 
null;
          else if ((
"shape" in gradient) || ("size" in gradient))
            
token parser.getToken(truetrue);
        }

        
// now color stops...
        
var stop1 this.parseColorStop(parsertoken);
        if (!
stop1)
          return 
null;
        
token parser.currentToken();
        if (!
token.isSymbol(","))
          return 
null;
        
token parser.getToken(truetrue);
        var 
stop2 this.parseColorStop(parsertoken);
        if (!
stop2)
          return 
null;
        
token parser.currentToken();
        if (
token.isSymbol(",")) {
          
token parser.getToken(truetrue);
        }
        
// ok we have at least two color stops
        
gradient.stops = [stop1stop2];
        while (!
token.isSymbol(")")) {
          var 
colorstop this.parseColorStop(parsertoken);
          if (!
colorstop)
            return 
null;
          
token parser.currentToken();
          if (!
token.isSymbol(")") && !token.isSymbol(","))
            return 
null;
          if (
token.isSymbol(","))
            
token parser.getToken(truetrue);
          
gradient.stops.push(colorstop);
        }
        return 
gradient;
      }
    }
    return 
null;
  },

  
parseBoxShadows: function(aString)
  {
    var 
parser = new CSSParser();
    
parser._init();
    
parser.mPreserveWS       false;
    
parser.mPreserveComments false;
    
parser.mPreservedTokens = [];
    
parser.mScanner.init(aString);

    var 
shadows = [];
    var 
token parser.getToken(truetrue);
    var 
color ""blurRadius "0px"offsetX "0px"offsetY "0px"spreadRadius "0px";
    var 
inset false;
    while (
token.isNotNull()) {
      if (
token.isIdent("none")) {
        
shadows.push( { nonetrue } );
        
token parser.getToken(truetrue);
      }
      else {
        if (
token.isIdent('inset')) {
          
inset true;
          
token parser.getToken(truetrue);
        }

        if (
token.isPercentage() ||
            
token.isDimensionOfUnit("cm") ||
            
token.isDimensionOfUnit("mm") ||
            
token.isDimensionOfUnit("in") ||
            
token.isDimensionOfUnit("pc") ||
            
token.isDimensionOfUnit("px") ||
            
token.isDimensionOfUnit("em") ||
            
token.isDimensionOfUnit("ex") ||
            
token.isDimensionOfUnit("pt")) {
          var 
offsetX token.value;
          
token parser.getToken(truetrue);
        }
        else
          return [];

        if (!
inset && token.isIdent('inset')) {
          
inset true;
          
token parser.getToken(truetrue);
        }

        if (
token.isPercentage() ||
            
token.isDimensionOfUnit("cm") ||
            
token.isDimensionOfUnit("mm") ||
            
token.isDimensionOfUnit("in") ||
            
token.isDimensionOfUnit("pc") ||
            
token.isDimensionOfUnit("px") ||
            
token.isDimensionOfUnit("em") ||
            
token.isDimensionOfUnit("ex") ||
            
token.isDimensionOfUnit("pt")) {
          var 
offsetX token.value;
          
token parser.getToken(truetrue);
        }
        else
          return [];

        if (!
inset && token.isIdent('inset')) {
          
inset true;
          
token parser.getToken(truetrue);
        }

        if (
token.isPercentage() ||
            
token.isDimensionOfUnit("cm") ||
            
token.isDimensionOfUnit("mm") ||
            
token.isDimensionOfUnit("in") ||
            
token.isDimensionOfUnit("pc") ||
            
token.isDimensionOfUnit("px") ||
            
token.isDimensionOfUnit("em") ||
            
token.isDimensionOfUnit("ex") ||
            
token.isDimensionOfUnit("pt")) {
          var 
blurRadius token.value;
          
token parser.getToken(truetrue);
        }

        if (!
inset && token.isIdent('inset')) {
          
inset true;
          
token parser.getToken(truetrue);
        }

        if (
token.isPercentage() ||
            
token.isDimensionOfUnit("cm") ||
            
token.isDimensionOfUnit("mm") ||
            
token.isDimensionOfUnit("in") ||
            
token.isDimensionOfUnit("pc") ||
            
token.isDimensionOfUnit("px") ||
            
token.isDimensionOfUnit("em") ||
            
token.isDimensionOfUnit("ex") ||
            
token.isDimensionOfUnit("pt")) {
          var 
spreadRadius token.value;
          
token parser.getToken(truetrue);
        }

        if (!
inset && token.isIdent('inset')) {
          
inset true;
          
token parser.getToken(truetrue);
        }

        if (
token.isFunction("rgb(") ||
            
token.isFunction("rgba(") ||
            
token.isFunction("hsl(") ||
            
token.isFunction("hsla(") ||
            
token.isSymbol("#") ||
            
token.isIdent()) {
          var 
color parser.parseColor(token);
          
token parser.getToken(truetrue);
        }

        if (!
inset && token.isIdent('inset')) {
          
inset true;
          
token parser.getToken(truetrue);
        }

        
shadows.push( { nonefalse,
                        
colorcolor,
                        
offsetXoffsetXoffsetYoffsetY,
                        
blurRadiusblurRadius,
                        
spreadRadiusspreadRadius } );

        if (
token.isSymbol(",")) {
          
inset false;
          
color "";
          
blurRadius "0px";
          
spreadRadius "0px"
          
offsetX "0px";
          
offsetY "0px"
          
token parser.getToken(truetrue);
        }
        else if (!
token.isNotNull())
          return 
shadows;
        else
          return [];
      }
    }
    return 
shadows;
  },

  
parseTextShadows: function(aString)
  {
    var 
parser = new CSSParser();
    
parser._init();
    
parser.mPreserveWS       false;
    
parser.mPreserveComments false;
    
parser.mPreservedTokens = [];
    
parser.mScanner.init(aString);

    var 
shadows = [];
    var 
token parser.getToken(truetrue);
    var 
color ""blurRadius "0px"offsetX "0px"offsetY "0px"
    while (
token.isNotNull()) {
      if (
token.isIdent("none")) {
        
shadows.push( { nonetrue } );
        
token parser.getToken(truetrue);
      }
      else {
        if (
token.isFunction("rgb(") ||
            
token.isFunction("rgba(") ||
            
token.isFunction("hsl(") ||
            
token.isFunction("hsla(") ||
            
token.isSymbol("#") ||
            
token.isIdent()) {
          var 
color parser.parseColor(token);
          
token parser.getToken(truetrue);
        }
        if (
token.isPercentage() ||
            
token.isDimensionOfUnit("cm") ||
            
token.isDimensionOfUnit("mm") ||
            
token.isDimensionOfUnit("in") ||
            
token.isDimensionOfUnit("pc") ||
            
token.isDimensionOfUnit("px") ||
            
token.isDimensionOfUnit("em") ||
            
token.isDimensionOfUnit("ex") ||
            
token.isDimensionOfUnit("pt")) {
          var 
offsetX token.value;
          
token parser.getToken(truetrue);
        }
        else
          return [];
        if (
token.isPercentage() ||
            
token.isDimensionOfUnit("cm") ||
            
token.isDimensionOfUnit("mm") ||
            
token.isDimensionOfUnit("in") ||
            
token.isDimensionOfUnit("pc") ||
            
token.isDimensionOfUnit("px") ||
            
token.isDimensionOfUnit("em") ||
            
token.isDimensionOfUnit("ex") ||
            
token.isDimensionOfUnit("pt")) {
          var 
offsetY token.value;
          
token parser.getToken(truetrue);
        }
        else
          return [];
        if (
token.isPercentage() ||
            
token.isDimensionOfUnit("cm") ||
            
token.isDimensionOfUnit("mm") ||
            
token.isDimensionOfUnit("in") ||
            
token.isDimensionOfUnit("pc") ||
            
token.isDimensionOfUnit("px") ||
            
token.isDimensionOfUnit("em") ||
            
token.isDimensionOfUnit("ex") ||
            
token.isDimensionOfUnit("pt")) {
          var 
blurRadius token.value;
          
token parser.getToken(truetrue);
        }
        if (!
color &&
            (
token.isFunction("rgb(") ||
             
token.isFunction("rgba(") ||
             
token.isFunction("hsl(") ||
             
token.isFunction("hsla(") ||
             
token.isSymbol("#") ||
             
token.isIdent())) {
          var 
color parser.parseColor(token);
          
token parser.getToken(truetrue);
        }

        
shadows.push( { nonefalse,
                        
colorcolor,
                        
offsetXoffsetXoffsetYoffsetY,
                        
blurRadiusblurRadius } );

        if (
token.isSymbol(",")) {
          
color "";
          
blurRadius "0px";
          
offsetX "0px";
          
offsetY "0px"
          
token parser.getToken(truetrue);
        }
        else if (!
token.isNotNull())
          return 
shadows;
        else
          return [];
      }
    }
    return 
shadows;
  },

  
parseBackgroundImages: function(aString)
  {
    var 
parser = new CSSParser();
    
parser._init();
    
parser.mPreserveWS       false;
    
parser.mPreserveComments false;
    
parser.mPreservedTokens = [];
    
parser.mScanner.init(aString);

    var 
backgrounds = [];
    var 
token parser.getToken(truetrue);
    while (
token.isNotNull()) {
      
/*if (token.isFunction("rgb(") ||
          token.isFunction("rgba(") ||
          token.isFunction("hsl(") ||
          token.isFunction("hsla(") ||
          token.isSymbol("#") ||
          token.isIdent()) {
        var color = parser.parseColor(token);
        backgrounds.push( { type: "color", value: color });
        token = parser.getToken(true, true);
      }
      else */
      
if (token.isFunction("url(")) {
        
token parser.getToken(truetrue);
        var 
urlContent parser.parseURL(token);
        
backgrounds.push( { type"image"value"url(" urlContent });
        
token parser.getToken(truetrue);
      }
      else if (
token.isFunction("-moz-linear-gradient(") ||
               
token.isFunction("-moz-radial-gradient(") ||
               
token.isFunction("-moz-repeating-linear-gradient(") ||
               
token.isFunction("-moz-repeating-radial-gradient(")) {
        var 
gradient this.parseGradient(parsertoken);
        
backgrounds.push( { typegradient.isRadial "radial-gradient" "linear-gradient"valuegradient });
        
token parser.getToken(truetrue);
      }
      else
        return 
null;
      if (
token.isSymbol(",")) {
        
token parser.getToken(truetrue);
        if (!
token.isNotNull())
          return 
null;
      }
    }
    return 
backgrounds;
  },

  
serializeGradient: function(gradient)
  {
    var 
gradient.isRadial
              
? (gradient.isRepeating "-moz-repeating-radial-gradient(" "-moz-radial-gradient(" )
              : (
gradient.isRepeating "-moz-repeating-linear-gradient(" "-moz-linear-gradient(" );
    if (
gradient.angle || gradient.position)
      
+= (gradient.angle gradient.angle " """) +
           (
gradient.position gradient.position "") +
           
", ";
    if (
gradient.isRadial && (gradient.shape || gradient.size))
      
+= (gradient.shape gradient.shape "") +
           
" " +
           (
gradient.size gradient.size "") +
           
", ";
    for (var 
0gradient.stops.lengthi++) {
      var 
colorstop gradient.stops[i];
      
+= colorstop.color + (colorstop.position " " colorstop.position "");
      if (
!= gradient.stops.length -1)
        
+= ", ";
    }
    
+= ")";
    return 
s;
  },

  
parseBorderImage: function(aString)
  {
    var 
parser = new CSSParser();
    
parser._init();
    
parser.mPreserveWS       false;
    
parser.mPreserveComments false;
    
parser.mPreservedTokens = [];
    
parser.mScanner.init(aString);

    var 
borderImage = {url""offsets: [], widths: [], sizes: []};
    var 
token parser.getToken(truetrue);
    if (
token.isFunction("url(")) {
      
token parser.getToken(truetrue);
      var 
urlContent parser.parseURL(token);
      if (
urlContent) {
        
borderImage.url urlContent.substr(0urlContent.length 1).trim();
        if ((
borderImage.url[0] == '"' && borderImage.url[borderImage.url.length 1] == '"') ||
             (
borderImage.url[0] == "'" && borderImage.url[borderImage.url.length 1] == "'"))
        
borderImage.url borderImage.url.substr(1borderImage.url.length 2);
      }
      else
        return 
null;
    }
    else
      return 
null

    
token parser.getToken(truetrue);
    if (
token.isNumber() || token.isPercentage())
      
borderImage.offsets.push(token.value);
    else
      return 
null;
    var 
i;
    for (
i03i++) {
      
token parser.getToken(truetrue);
      if (
token.isNumber() || token.isPercentage())
        
borderImage.offsets.push(token.value);
      else
        break;
    }
    if (
== 3)
      
token parser.getToken(truetrue);

    if (
token.isSymbol("/")) {
      
token parser.getToken(truetrue);
      if (
token.isDimension()
          || 
token.isNumber("0")
          || (
token.isIdent() && token.value in parser.kBORDER_WIDTH_NAMES))
        
borderImage.widths.push(token.value);
      else
        return 
null;

      for (var 
03i++) {
        
token parser.getToken(truetrue);
        if (
token.isDimension()
            || 
token.isNumber("0")
            || (
token.isIdent() && token.value in parser.kBORDER_WIDTH_NAMES))
          
borderImage.widths.push(token.value);
        else
          break;
      }
      if (
== 3)
        
token parser.getToken(truetrue);
    }

    for (var 
02i++) {
      if (
token.isIdent("stretch")
          || 
token.isIdent("repeat")
          || 
token.isIdent("round"))
        
borderImage.sizes.push(token.value);
      else if (!
token.isNotNull())
        return 
borderImage;
      else
        return 
null;
      
token parser.getToken(truetrue);
    }
    if (!
token.isNotNull())
      return 
borderImage;

    return 
null;
  },

  
parseMediaQuery: function(aString)
  {
    var 
kCONSTRAINTS = {
      
"width"true,
      
"min-width"true,
      
"max-width"true,
      
"height"true,
      
"min-height"true,
      
"max-height"true,
      
"device-width"true,
      
"min-device-width"true,
      
"max-device-width"true,
      
"device-height"true,
      
"min-device-height"true,
      
"max-device-height"true,
      
"orientation"true,
      
"aspect-ratio"true,
      
"min-aspect-ratio"true,
      
"max-aspect-ratio"true,
      
"device-aspect-ratio"true,
      
"min-device-aspect-ratio"true,
      
"max-device-aspect-ratio"true,
      
"color"true,
      
"min-color"true,
      
"max-color"true,
      
"color-index"true,
      
"min-color-index"true,
      
"max-color-index"true,
      
"monochrome"true,
      
"min-monochrome"true,
      
"max-monochrome"true,
      
"resolution"true,
      
"min-resolution"true,
      
"max-resolution"true,
      
"scan"true,
      
"grid"true
    
};
    var 
parser = new CSSParser();
    
parser._init();
    
parser.mPreserveWS       false;
    
parser.mPreserveComments false;
    
parser.mPreservedTokens = [];
    
parser.mScanner.init(aString);

    var 
= {amplifier""medium""constraints: []};
    var 
token parser.getToken(truetrue);

    if (
token.isIdent("all") ||
        
token.isIdent("aural") ||
        
token.isIdent("braille") ||
        
token.isIdent("handheld") ||
        
token.isIdent("print") ||
        
token.isIdent("projection") ||
        
token.isIdent("screen") ||
        
token.isIdent("tty") ||
        
token.isIdent("tv")) {
       
m.medium token.value;
       
token parser.getToken(truetrue);
    }
    else if (
token.isIdent("not") || token.isIdent("only")) {
      
m.amplifier token.value;
      
token parser.getToken(truetrue);
      if (
token.isIdent("all") ||
          
token.isIdent("aural") ||
          
token.isIdent("braille") ||
          
token.isIdent("handheld") ||
          
token.isIdent("print") ||
          
token.isIdent("projection") ||
          
token.isIdent("screen") ||
          
token.isIdent("tty") ||
          
token.isIdent("tv")) {
         
m.medium token.value;
         
token parser.getToken(truetrue);
      }
      else
        return 
null;
    }

    if (
m.medium) {
      if (!
token.isNotNull())
        return 
m;
      if (
token.isIdent("and")) {
        
token parser.getToken(truetrue);
      }
      else
        return 
null;
    }

    while (
token.isSymbol("(")) {
      
token parser.getToken(truetrue);
      if (
token.isIdent() && (token.value in kCONSTRAINTS)) {
        var 
constraint token.value;
        
token parser.getToken(truetrue);
        if (
token.isSymbol(":")) {
          
token parser.getToken(truetrue);
          var 
values = [];
          while (!
token.isSymbol(")")) {
            
values.push(token.value);
            
token parser.getToken(truetrue);
          }
          if (
token.isSymbol(")")) {
            
m.constraints.push({constraintconstraintvaluevalues});
            
token parser.getToken(truetrue);
            if (
token.isNotNull()) {
              if (
token.isIdent("and")) {
                
token parser.getToken(truetrue);
              }
              else
                return 
null;
            }
            else
              return 
m;
          }
          else
            return 
null;
        }
        else if (
token.isSymbol(")")) {
          
m.constraints.push({constraintconstraintvaluenull});
          
token parser.getToken(truetrue);
          if (
token.isNotNull()) {
            if (
token.isIdent("and")) {
              
token parser.getToken(truetrue);
            }
            else
              return 
null;
          }
          else
            return 
m;
        }
        else
          return 
null;
      }
      else
        return 
null;
    }
    return 
m;
  }

};


/************************************************************/
/************************** JSCSSP **************************/
/************************************************************/

var CSS_ESCAPE  '\';

var IS_HEX_DIGIT  = 1;
var START_IDENT   = 2;
var IS_IDENT      = 4;
var IS_WHITESPACE = 8;

var W   = IS_WHITESPACE;
var I   = IS_IDENT;
var S   =          START_IDENT;
var SI  = IS_IDENT|START_IDENT;
var XI  = IS_IDENT            |IS_HEX_DIGIT;
var XSI = IS_IDENT|START_IDENT|IS_HEX_DIGIT;

function CSSScanner(aString)
{
  this.init(aString);
}

CSSScanner.prototype = {

  kLexTable: [
  //                                     TAB LF      FF  CR
     0,  0,  0,  0,  0,  0,  0,  0,  0,  W,  W,  0,  W,  W,  0,  0,
  //
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  // SPC !   "   #   $   %   &   '   
(   )   *   +   ,   -   .   /
     
W,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  I,  0,  0,
  
// 0   1   2   3   4   5   6   7   8   9   :   ;   <   =   >   ?
     
XIXIXIXIXIXIXIXIXIXI0,  0,  0,  0,  0,  0,
  
// @   A   B   C   D   E   F   G   H   I   J   K   L   M   N   O
     
0,  XSI,XSI,XSI,XSI,XSI,XSI,SISISISISISISISISI,
  
// P   Q   R   S   T   U   V   W   X   Y   Z   [      ]   ^   _
     
SISISISISISISISISISISI0,  S,  0,  0,  SI,
  
// `   a   b   c   d   e   f   g   h   i   j   k   l   m   n   o
     
0,  XSI,XSI,XSI,XSI,XSI,XSI,SISISISISISISISISI,
  
// p   q   r   s   t   u   v   w   x   y   z   {   |   }   ~
     
SISISISISISISISISISISI0,  0,  0,  0,  0,
  
//
     
0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  
//
     
0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
  
//     ¡   ¢   £   ¤   ¥   ¦   §   ¨   ©   ª   «   ¬   ­   ®   ¯
     
0,  SISISISISISISISISISISISISISISI,
  
// °   ±   ²   ³   ´   µ   ¶   ·   ¸   ¹   º   »   ¼   ½   ¾   ¿
     
SISISISISISISISISISISISISISISISI,
  
// À   Á   Â   Ã   Ä   Å   Æ   Ç   È   É   Ê   Ë   Ì   Í   Î   Ï
     
SISISISISISISISISISISISISISISISI,
  
// Ð   Ñ   Ò   Ó   Ô   Õ   Ö   ×   Ø   Ù   Ú   Û   Ü   Ý   Þ   ß
     
SISISISISISISISISISISISISISISISI,
  
// à   á   â   ã   ä   å   æ   ç   è   é   ê   ë   ì   í   î   ï
     
SISISISISISISISISISISISISISISISI,
  
// ð   ñ   ò   ó   ô   õ   ö   ÷   ø   ù   ú   û   ü   ý   þ   ÿ
     
SISISISISISISISISISISISISISISISI
  
],

  
kHexValues: {
    
"0"0"1"1"2"2"3"3"4"4"5"5"6"6"7"7"8"8"9"9,
    
"a"10"b"11"c"12"d"13"e"14"f"15
  
},

  
mString "",
  
mPos 0,
  
mPreservedPos : [],

  
init: function(aString) {
    
this.mString aString;
    
this.mPos 0;
    
this.mPreservedPos = [];
  },

  
getCurrentPos: function() {
    return 
this.mPos;
  },

  
getAlreadyScanned: function()
  {
    return 
this.mString.substr(0this.mPos);
  },

  
preserveState: function() {
    
this.mPreservedPos.push(this.mPos);
  },

  
restoreState: function() {
    if (
this.mPreservedPos.length) {
      
this.mPos this.mPreservedPos.pop();
    }
  },

  
forgetState: function() {
    if (
this.mPreservedPos.length) {
      
this.mPreservedPos.pop();
    }
  },

  
read: function() {
    if (
this.mPos this.mString.length)
      return 
this.mString.charAt(this.mPos++);
    return -
1;
  },

  
peek: function() {
    if (
this.mPos this.mString.length)
      return 
this.mString.charAt(this.mPos);
    return -
1;
  },

  
isHexDigit: function(c) {
    var 
code c.charCodeAt(0);
    return (
code 256 && (this.kLexTable[code] & IS_HEX_DIGIT) != 0);
  },

  
isIdentStart: function(c) {
    var 
code c.charCodeAt(0);
    return (
code >= 256 || (this.kLexTable[code] & START_IDENT) != 0);
  },

  
startsWithIdent: function(aFirstCharaSecondChar) {
    var 
code aFirstChar.charCodeAt(0);
    return 
this.isIdentStart(aFirstChar) ||
           (
aFirstChar == "-" && this.isIdentStart(aSecondChar));
  },

  
isIdent: function(c) {
    var 
code c.charCodeAt(0);
    return (
code >= 256 || (this.kLexTable[code] & IS_IDENT) != 0);
  },

  
isSymbol: function(c) {
    var 
code c.charCodeAt(0);
    return (
this.kLexTable[code] & IS_IDENT) != 1;
  },

  
pushback: function() {
    
this.mPos--;
  },

  
nextHexValue: function() {
    var 
this.read();
    if (
== -|| !this.isHexDigit(c))
      return new 
jscsspToken(jscsspToken.NULL_TYPEnull);
    var 
c;
    
this.read();
    while (
!= -&& this.isHexDigit(c)) {
      
+= c;
      
this.read();
    }
    if (
!= -1)
      
this.pushback();
    return new 
jscsspToken(jscsspToken.HEX_TYPEs);
  },

  
gatherEscape: function() {
    var 
this.peek();
    if (
== -1)
      return 
"";
    if (
this.isHexDigit(c)) {
      var 
code 0;
      for (var 
06i++) {
        
this.read();
        if (
this.isHexDigit(c))
          
code code 16 this.kHexValues[c.toLowerCase()];
        else if (!
this.isHexDigit(c) && !this.isWhiteSpace(c)) {
          
this.pushback();
          break;
        }
        else
          break;
      }
      if (
== 6) {
        
this.peek();
        if (
this.isWhiteSpace(c))
          
this.read();
      }
      return 
String.fromCharCode(code);
    }
    
this.read();
    if (
!= "n")
      return 
c;
    return 
"";
  },

  
gatherIdent: function(c) {
    var 
"";
    if (
== CSS_ESCAPE)
      
+= this.gatherEscape();
    else
      
+= c;
    
this.read();
    if(!
this.mMediaQueryMode){
        while (
!= -1
               
&& (this.isIdent(c) || == CSS_ESCAPE)) {
          if (
== CSS_ESCAPE)
            
+= this.gatherEscape();
          else
            
+= c;
          
this.read();
        }
    }
    else {
        while (
!= -1
               
&& != '{' 
               
&& != ',') {
            
+= c;
          
this.read();
        }
    }
    if (
!= -1)
      
this.pushback();
      
this.mMediaQueryMode false;
    return 
s;
  },

  
parseIdent: function(c) {
    var 
value this.gatherIdent(c);
    var 
nextChar this.peek();
    if (
nextChar == "(") {
      
value += this.read();
      return new 
jscsspToken(jscsspToken.FUNCTION_TYPEvalue);
    }
    return new 
jscsspToken(jscsspToken.IDENT_TYPEvalue);
  },

  
isDigit: function(c) {
    return (
>= '0') && (<= '9');
  },

  
parseComment: function(c) {
    var 
c;
    while ((
this.read()) != -1) {
      
+= c;
      if (
== "*") {
        
this.read();
        if (
== -1)
          break;
        if (
== "/") {
          
+= c;
          break;
        }
        
this.pushback();
      }
    }
    return new 
jscsspToken(jscsspToken.COMMENT_TYPEs);
  },

  
parseNumber: function(c) {
    var 
c;
    var 
foundDot false;
    while ((
this.read()) != -1) {
      if (
== ".") {
        if (
foundDot)
          break;
        else {
          
+= c;
          
foundDot true;
        }
      } else if (
this.isDigit(c))
        
+= c;
      else
        break;
    }

    if (
!= -&& this.startsWithIdent(cthis.peek())) { // DIMENSION
      
var unit this.gatherIdent(c);
      
+= unit;
      return new 
jscsspToken(jscsspToken.DIMENSION_TYPEsunit);
    }
    else if (
== "%") {
      
+= "%";
      return new 
jscsspToken(jscsspToken.PERCENTAGE_TYPEs);
    }
    else if (
!= -1)
      
this.pushback();
    return new 
jscsspToken(jscsspToken.NUMBER_TYPEs);
  },

  
parseString: function(aStop) {
    var 
aStop;
    var 
previousChar aStop;
    var 
c;
    while ((
this.read()) != -1) {
      if (
== aStop && previousChar != CSS_ESCAPE) {
        
+= c;
        break;
      }
      else if (
== CSS_ESCAPE) {
        
this.peek();
        if (
== -1)
          break;
        else if (
== "n" || == "r" || == "f") {
          
c;
          
this.read();
          
// special for Opera that preserves rn...
          
if (== "r") {
            
this.peek();
            if (
== "n")
              
this.read();
          }
        }
        else {
          
+= this.gatherEscape();
          
this.peek();
        }
      }
      else if (
== "n" || == "r" || == "f") {
        break;
      }
      else
        
+= c;

      
previousChar c;
    }
    return new 
jscsspToken(jscsspToken.STRING_TYPEs);
  },

  
isWhiteSpace: function(c) {
    var 
code c.charCodeAt(0);
    return 
code 256 && (this.kLexTable[code] & IS_WHITESPACE) != 0;
  },

  
eatWhiteSpace: function(c) {
    var 
c;
    while ((
this.read()) != -1) {
      if (!
this.isWhiteSpace(c))
        break;
      
+= c;
    }
    if (
!= -1)
      
this.pushback();
    return 
s;
  },

  
parseAtKeyword: function(c) {
    return new 
jscsspToken(jscsspToken.ATRULE_TYPEthis.gatherIdent(c));
  },

  
nextToken: function() {
    var 
this.read();
    if (
== -1)
      return new 
jscsspToken(jscsspToken.NULL_TYPEnull);

    if (
this.startsWithIdent(cthis.peek()))
      return 
this.parseIdent(c);

    if (
== '@') {
      var 
nextChar this.read();
      if (
nextChar != -1) {
        var 
followingChar this.peek();
        
this.pushback();
        if (
this.startsWithIdent(nextCharfollowingChar))
          return 
this.parseAtKeyword(c);
      }
    }

    if (
== "." || == "+" || == "-") {
      var 
nextChar this.peek();
      if (
this.isDigit(nextChar))
        return 
this.parseNumber(c);
      else if (
nextChar == "." && != ".") {
        
firstChar this.read();
        var 
secondChar this.peek();
        
this.pushback();
        if (
this.isDigit(secondChar))
          return 
this.parseNumber(c);
      }
    }
    if (
this.isDigit(c)) {
      return 
this.parseNumber(c);
    }

    if (
== "'" || == '"')
      return 
this.parseString(c);

    if (
this.isWhiteSpace(c)) {
      var 
this.eatWhiteSpace(c);
      
      return new 
jscsspToken(jscsspToken.WHITESPACE_TYPEs);
    }

    if (
== "|" || == "~" || == "^" || == "$" || == "*") {
      var 
nextChar this.read();
      if (
nextChar == "=") {
        switch (
c) {
          case 
"~" :
            return new 
jscsspToken(jscsspToken.INCLUDES_TYPE"~=");
          case 
"|" :
            return new 
jscsspToken(jscsspToken.DASHMATCH_TYPE"|=");
          case 
"^" :
            return new 
jscsspToken(jscsspToken.BEGINSMATCH_TYPE"^=");
          case 
"$" :
            return new 
jscsspToken(jscsspToken.ENDSMATCH_TYPE"$=");
          case 
"*" :
            return new 
jscsspToken(jscsspToken.CONTAINSMATCH_TYPE"*=");
          default :
            break;
        }
      } else if (
nextChar != -1)
        
this.pushback();
    }

    if (
== "/" && this.peek() == "*")
      return 
this.parseComment(c);

    return new 
jscsspToken(jscsspToken.SYMBOL_TYPEc);
  }
};

function 
CSSParser(aString)
{
  
this.mToken null;
  
this.mLookAhead null;
  
this.mScanner = new CSSScanner(aString);

  
this.mPreserveWS true;
  
this.mPreserveComments true;

  
this.mPreservedTokens = [];
  
  
this.mError null;
}

CSSParser.prototype = {

  
_init:function() {
    
this.mToken null;
    
this.mLookAhead null;
    
this.mMediaQueryMode false;
  },

  
kINHERIT"inherit",

  
kBORDER_WIDTH_NAMES: {
      
"thin"true,
      
"medium"true,
      
"thick"true
  
},

  
kBORDER_STYLE_NAMES: {
    
"none"true,
    
"hidden"true,
    
"dotted"true,
    
"dashed"true,
    
"solid"true,
    
"double"true,
    
"groove"true,
    
"ridge"true,
    
"inset"true,
    
"outset"true
  
},

  
kCOLOR_NAMES: {
    
"transparent"true,
  
    
"black"true,
    
"silver"true,
    
"gray"true,
    
"white"true,
    
"maroon"true,
    
"red"true,
    
"purple"true,
    
"fuchsia"true,
    
"green"true,
    
"lime"true,
    
"olive"true,
    
"yellow"true,
    
"navy"true,
    
"blue"true,
    
"teal"true,
    
"aqua"true,
    
    
"aliceblue"true,
    
"antiquewhite"true,
    
"aqua"true,
    
"aquamarine"true,
    
"azure"true,
    
"beige"true,
    
"bisque"true,
    
"black"true,
    
"blanchedalmond"true,
    
"blue"true,
    
"blueviolet"true,
    
"brown"true,
    
"burlywood"true,
    
"cadetblue"true,
    
"chartreuse"true,
    
"chocolate"true,
    
"coral"true,
    
"cornflowerblue"true,
    
"cornsilk"true,
    
"crimson"true,
    
"cyan"true,
    
"darkblue"true,
    
"darkcyan"true,
    
"darkgoldenrod"true,
    
"darkgray"true,
    
"darkgreen"true,
    
"darkgrey"true,
    
"darkkhaki"true,
    
"darkmagenta"true,
    
"darkolivegreen"true,
    
"darkorange"true,
    
"darkorchid"true,
    
"darkred"true,
    
"darksalmon"true,
    
"darkseagreen"true,
    
"darkslateblue"true,
    
"darkslategray"true,
    
"darkslategrey"true,
    
"darkturquoise"true,
    
"darkviolet"true,
    
"deeppink"true,
    
"deepskyblue"true,
    
"dimgray"true,
    
"dimgrey"true,
    
"dodgerblue"true,
    
"firebrick"true,
    
"floralwhite"true,
    
"forestgreen"true,
    
"fuchsia"true,
    
"gainsboro"true,
    
"ghostwhite"true,
    
"gold"true,
    
"goldenrod"true,
    
"gray"true,
    
"green"true,
    
"greenyellow"true,
    
"grey"true,
    
"honeydew"true,
    
"hotpink"true,
    
"indianred"true,
    
"indigo"true,
    
"ivory"true,
    
"khaki"true,
    
"lavender"true,
    
"lavenderblush"true,
    
"lawngreen"true,
    
"lemonchiffon"true,
    
"lightblue"true,
    
"lightcoral"true,
    
"lightcyan"true,
    
"lightgoldenrodyellow"true,
    
"lightgray"true,
    
"lightgreen"true,
    
"lightgrey"true,
    
"lightpink"true,
    
"lightsalmon"true,
    
"lightseagreen"true,
    
"lightskyblue"true,
    
"lightslategray"true,
    
"lightslategrey"true,
    
"lightsteelblue"true,
    
"lightyellow"true,
    
"lime"true,
    
"limegreen"true,
    
"linen"true,
    
"magenta"true,
    
"maroon"true,
    
"mediumaquamarine"true,
    
"mediumblue"true,
    
"mediumorchid"true,
    
"mediumpurple"true,
    
"mediumseagreen"true,
    
"mediumslateblue"true,
    
"mediumspringgreen"true,
    
"mediumturquoise"true,
    
"mediumvioletred"true,
    
"midnightblue"true,
    
"mintcream"true,
    
"mistyrose"true,
    
"moccasin"true,
    
"navajowhite"true,
    
"navy"true,
    
"oldlace"true,
    
"olive"true,
    
"olivedrab"true,
    
"orange"true,
    
"orangered"true,
    
"orchid"true,
    
"palegoldenrod"true,
    
"palegreen"true,
    
"paleturquoise"true,
    
"palevioletred"true,
    
"papayawhip"true,
    
"peachpuff"true,
    
"peru"true,
    
"pink"true,
    
"plum"true,
    
"powderblue"true,
    
"purple"true,
    
"red"true,
    
"rosybrown"true,
    
"royalblue"true,
    
"saddlebrown"true,
    
"salmon"true,
    
"sandybrown"true,
    
"seagreen"true,
    
"seashell"true,
    
"sienna"true,
    
"silver"true,
    
"skyblue"true,
    
"slateblue"true,
    
"slategray"true,
    
"slategrey"true,
    
"snow"true,
    
"springgreen"true,
    
"steelblue"true,
    
"tan"true,
    
"teal"true,
    
"thistle"true,
    
"tomato"true,
    
"turquoise"true,
    
"violet"true,
    
"wheat"true,
    
"white"true,
    
"whitesmoke"true,
    
"yellow"true,
    
"yellowgreen"true,
  
    
"activeborder"true,
    
"activecaption"true,
    
"appworkspace"true,
    
"background"true,
    
"buttonface"true,
    
"buttonhighlight"true,
    
"buttonshadow"true,
    
"buttontext"true,
    
"captiontext"true,
    
"graytext"true,
    
"highlight"true,
    
"highlighttext"true,
    
"inactiveborder"true,
    
"inactivecaption"true,
    
"inactivecaptiontext"true,
    
"infobackground"true,
    
"infotext"true,
    
"menu"true,
    
"menutext"true,
    
"scrollbar"true,
    
"threeddarkshadow"true,
    
"threedface"true,
    
"threedhighlight"true,
    
"threedlightshadow"true,
    
"threedshadow"true,
    
"window"true,
    
"windowframe"true,
    
"windowtext"true
  
},

  
kLIST_STYLE_TYPE_NAMES: {
    
"decimal"true,
    
"decimal-leading-zero"true,
    
"lower-roman"true,
    
"upper-roman"true,
    
"georgian"true,
    
"armenian"true,
    
"lower-latin"true,
    
"lower-alpha"true,
    
"upper-latin"true,
    
"upper-alpha"true,
    
"lower-greek"true,

    
"disc"true,
    
"circle"true,
    
"square"true,
    
"none"true,
    
    
/* CSS 3 */
    
"box"true,
    
"check"true,
    
"diamond"true,
    
"hyphen"true,

    
"lower-armenian"true,
    
"cjk-ideographic"true,
    
"ethiopic-numeric"true,
    
"hebrew"true,
    
"japanese-formal"true,
    
"japanese-informal"true,
    
"simp-chinese-formal"true,
    
"simp-chinese-informal"true,
    
"syriac"true,
    
"tamil"true,
    
"trad-chinese-formal"true,
    
"trad-chinese-informal"true,
    
"upper-armenian"true,
    
"arabic-indic"true,
    
"binary"true,
    
"bengali"true,
    
"cambodian"true,
    
"khmer"true,
    
"devanagari"true,
    
"gujarati"true,
    
"gurmukhi"true,
    
"kannada"true,
    
"lower-hexadecimal"true,
    
"lao"true,
    
"malayalam"true,
    
"mongolian"true,
    
"myanmar"true,
    
"octal"true,
    
"oriya"true,
    
"persian"true,
    
"urdu"true,
    
"telugu"true,
    
"tibetan"true,
    
"upper-hexadecimal"true,
    
"afar"true,
    
"ethiopic-halehame-aa-et"true,
    
"ethiopic-halehame-am-et"true,
    
"amharic-abegede"true,
    
"ehiopic-abegede-am-et"true,
    
"cjk-earthly-branch"true,
    
"cjk-heavenly-stem"true,
    
"ethiopic"true,
    
"ethiopic-abegede"true,
    
"ethiopic-abegede-gez"true,
    
"hangul-consonant"true,
    
"hangul"true,
    
"hiragana-iroha"true,
    
"hiragana"true,
    
"katakana-iroha"true,
    
"katakana"true,
    
"lower-norwegian"true,
    
"oromo"true,
    
"ethiopic-halehame-om-et"true,
    
"sidama"true,
    
"ethiopic-halehame-sid-et"true,
    
"somali"true,
    
"ethiopic-halehame-so-et"true,
    
"tigre"true,
    
"ethiopic-halehame-tig"true,
    
"tigrinya-er-abegede"true,
    
"ethiopic-abegede-ti-er"true,
    
"tigrinya-et"true,
    
"ethiopic-halehame-ti-et"true,
    
"upper-greek"true,
    
"asterisks"true,
    
"footnotes"true,
    
"circled-decimal"true,
    
"circled-lower-latin"true,
    
"circled-upper-latin"true,
    
"dotted-decimal"true,
    
"double-circled-decimal"true,
    
"filled-circled-decimal"true,
    
"parenthesised-decimal"true,
    
"parenthesised-lower-latin"true
  
},

  
reportError: function(aMsg) {
    
this.mError aMsg;
  },

  
consumeError: function() {
    var 
this.mError;
    
this.mError null;
    return 
e;
  },

  
currentToken: function() {
    return 
this.mToken;
  },

  
getHexValue: function() {
    
this.mToken this.mScanner.nextHexValue();
    return 
this.mToken;
  },

  
getToken: function(aSkipWSaSkipComment) {
    if (
this.mLookAhead) {
      
this.mToken this.mLookAhead;
      
this.mLookAhead null;
      return 
this.mToken;
    }

    
this.mToken this.mScanner.nextToken();
    while (
this.mToken &&
           ((
aSkipWS && this.mToken.isWhiteSpace()) ||
            (
aSkipComment && this.mToken.isComment())))
      
this.mToken this.mScanner.nextToken();
    return 
this.mToken;
  },

  
lookAhead: function(aSkipWSaSkipComment) {
    var 
preservedToken this.mToken;
    
this.mScanner.preserveState();
    var 
token this.getToken(aSkipWSaSkipComment);
    
this.mScanner.restoreState();
    
this.mToken preservedToken;

    return 
token;
  },

  
ungetToken: function() {
    
this.mLookAhead this.mToken;
  },

  
addUnknownAtRule: function(aSheetaString) {
    var 
currentLine CountLF(this.mScanner.getAlreadyScanned());
    var 
blocks = [];
    var 
token this.getToken(falsefalse);
    while (
token.isNotNull()) {
      
aString += token.value;
      if (
token.isSymbol(";") && !blocks.length)
        break;
      else if (
token.isSymbol("{")
               || 
token.isSymbol("(")
               || 
token.isSymbol("[")
               || 
token.type == "function") {
        
blocks.push(token.isFunction() ? "(" token.value);
      } else if (
token.isSymbol("}")
                 || 
token.isSymbol(")")
                 || 
token.isSymbol("]")) {
        if (
blocks.length) {
          var 
ontop blocks[blocks.length 1];
          if ((
token.isSymbol("}") && ontop == "{")
              || (
token.isSymbol(")") && ontop == "(")
              || (
token.isSymbol("]") && ontop == "[")) {
            
blocks.pop();
            if (!
blocks.length && token.isSymbol("}"))
              break;
          }
        }
      }
      
token this.getToken(falsefalse);
    }

    
this.addUnknownRule(aSheetaStringcurrentLine);
  },

  
addUnknownRule: function(aSheetaStringaCurrentLine) {
    var 
errorMsg this.consumeError();
    var 
rule = new jscsspErrorRule(errorMsg);
    
rule.currentLine aCurrentLine;
    
rule.parsedCssText aString;
    
rule.parentStyleSheet aSheet;
    
aSheet.cssRules.push(rule);
  },

  
addWhitespace: function(aSheetaString) {
    var 
rule = new jscsspWhitespace();
    
rule.parsedCssText aString;
    
rule.parentStyleSheet aSheet;
    
aSheet.cssRules.push(rule);
  },

  
addComment: function(aSheetaString) {
    var 
rule = new jscsspComment();
    
rule.parsedCssText aString;
    
rule.parentStyleSheet aSheet;
    
aSheet.cssRules.push(rule);
  },

  
parseCharsetRule: function(aTokenaSheet) {
    var 
aToken.value;
    var 
token this.getToken(falsefalse);
    
+= token.value;
    if (
token.isWhiteSpace(" ")) {
      
token this.getToken(falsefalse);
      
+= token.value;
      if (
token.isString()) {
        var 
encoding token.value;
        
token this.getToken(falsefalse);
        
+= token.value;
        if (
token.isSymbol(";")) {
          var 
rule = new jscsspCharsetRule();
          
rule.encoding encoding;
          
rule.parsedCssText s;
          
rule.parentStyleSheet aSheet;
          
aSheet.cssRules.push(rule);
          return 
true;
        }
        else
          
this.reportError(kCHARSET_RULE_MISSING_SEMICOLON);
      }
      else
        
this.reportError(kCHARSET_RULE_CHARSET_IS_STRING);
    }
    else
      
this.reportError(kCHARSET_RULE_MISSING_WS);

    
this.addUnknownAtRule(aSheets);
    return 
false;
  },

  
parseImportRule: function(aTokenaSheet) {
    var 
currentLine CountLF(this.mScanner.getAlreadyScanned());
    var 
aToken.value;
    
this.preserveState();
    var 
token this.getToken(truetrue);
    var 
media = [];
    var 
href "";
    if (
token.isString()) {
      
href token.value;
      
+= " " href;
    }
    else if (
token.isFunction("url(")) {
      
token this.getToken(truetrue);
      var 
urlContent this.parseURL(token);
      if (
urlContent) {
        
href "url(" urlContent;
        
+= " " href;
      }
    }
    else
      
this.reportError(kIMPORT_RULE_MISSING_URL);

    if (
href) {
      
token this.getToken(truetrue);
      while (
token.isIdent()) {
        
+= " " token.value;
        
media.push(token.value);
        
token this.getToken(truetrue);
        if (!
token)
          break;
        if (
token.isSymbol(",")) {
          
+= ",";
        } else if (
token.isSymbol(";")) {
          break;
        } else
          break;
        
token this.getToken(truetrue);
      }

      if (!
media.length) {
        
media.push("all");
      }
  
      if (
token.isSymbol(";")) {
        
+= ";"
        
this.forgetState();
        var 
rule = new jscsspImportRule();
        
rule.currentLine currentLine;
        
rule.parsedCssText s;
        
rule.href href;
        
rule.media media;
        
rule.parentStyleSheet aSheet;
        
aSheet.cssRules.push(rule);
        return 
true;
      }
    }

    
this.restoreState();
    
this.addUnknownAtRule(aSheet"@import");
    return 
false;
  },

  
parseVariablesRule: function(tokenaSheet) {
    var 
currentLine CountLF(this.mScanner.getAlreadyScanned());
    var 
token.value;
    var 
declarations = [];
    var 
valid false;
    
this.preserveState();
    
token this.getToken(truetrue);
    var 
media = [];
    var 
foundMedia false;
    while (
token.isNotNull()) {
      if (
token.isIdent()) {
        
foundMedia true;
        
+= " " token.value;
        
media.push(token.value);
        
token this.getToken(truetrue);
        if (
token.isSymbol(",")) {
          
+= ",";
        } else {
          if (
token.isSymbol("{"))
            
this.ungetToken();
          else {
            
// error...
            
token.type jscsspToken.NULL_TYPE;
            break;
          }
        }
      } else if (
token.isSymbol("{"))
        break;
      else if (
foundMedia) {
        
token.type jscsspToken.NULL_TYPE;
        
// not a media list
        
break;
      }
      
token this.getToken(truetrue);
    }

    if (
token.isSymbol("{")) {
      
+= " {";
      
token this.getToken(truetrue);
      while (
true) {
        if (!
token.isNotNull()) {
          
valid true;
          break;
        }
        if (
token.isSymbol("}")) {
          
+= "}";
          
valid true;
          break;
        } else {
          var 
this.parseDeclaration(tokendeclarationstruefalseaSheet);
          
+= ((&& declarations.length) ? " " "") + d;
        }
        
token this.getToken(truefalse);
      }
    }
    if (
valid) {
      
this.forgetState();
      var 
rule = new jscsspVariablesRule();
      
rule.currentLine currentLine;
      
rule.parsedCssText s;
      
rule.declarations declarations;
      
rule.media media;
      
rule.parentStyleSheet aSheet;
      
aSheet.cssRules.push(rule)
      return 
true;
    }
    
this.restoreState();
    return 
false;
  },

  
parseNamespaceRule: function(aTokenaSheet) {
    var 
currentLine CountLF(this.mScanner.getAlreadyScanned());
    var 
aToken.value;
    var 
valid false;
    
this.preserveState();
    var 
token this.getToken(truetrue);
    if (
token.isNotNull()) {
      var 
prefix "";
      var 
url "";
      if (
token.isIdent()) {
        
prefix token.value;
        
+= " " prefix;
        
token this.getToken(truetrue);
      }
      if (
token) {
        var 
foundURL false;
        if (
token.isString()) {
          
foundURL true;
          
url token.value;
          
+= " " url;
        } else if (
token.isFunction("url(")) {
          
// get a url here...
          
token this.getToken(truetrue);
          var 
urlContent this.parseURL(token);
          if (
urlContent) {
            
url += "url(" urlContent;
            
foundURL true;
            
+= " " urlContent;
          }
        }
      }
      if (
foundURL) {
        
token this.getToken(truetrue);
        if (
token.isSymbol(";")) {
          
+= ";";
          
this.forgetState();
          var 
rule = new jscsspNamespaceRule();
          
rule.currentLine currentLine;
          
rule.parsedCssText s;
          
rule.prefix prefix;
          
rule.url url;
          
rule.parentStyleSheet aSheet;
          
aSheet.cssRules.push(rule);
          return 
true;
        }
      }

    }
    
this.restoreState();
    
this.addUnknownAtRule(aSheet"@namespace");
    return 
false;
  },

  
parseFontFaceRule: function(aTokenaSheet) {
    var 
currentLine CountLF(this.mScanner.getAlreadyScanned());
    var 
aToken.value;
    var 
valid false;
    var 
descriptors = [];
    
this.preserveState();
    var 
token this.getToken(truetrue);
    if (
token.isNotNull()) {
      
// expecting block start
      
if (token.isSymbol("{")) {
        
+= " " token.value;
        var 
token this.getToken(truefalse);
        while (
true) {
          if (
token.isSymbol("}")) {
            
+= "}";
            
valid true;
            break;
          } else {
            var 
this.parseDeclaration(tokendescriptorsfalsefalseaSheet);
            
+= ((&& descriptors.length) ? " " "") + d;
          }
          
token this.getToken(truefalse);
        }
      }
    }
    if (
valid) {
      
this.forgetState();
      var 
rule = new jscsspFontFaceRule();
      
rule.currentLine currentLine;
      
rule.parsedCssText s;
      
rule.descriptors descriptors;
      
rule.parentStyleSheet aSheet;
      
aSheet.cssRules.push(rule)
      return 
true;
    }
    
this.restoreState();
    return 
false;
  },

  
parsePageRule: function(aTokenaSheet) {
    var 
currentLine CountLF(this.mScanner.getAlreadyScanned());
    var 
aToken.value;
    var 
valid false;
    var 
declarations = [];
    
this.preserveState();
    var 
token this.getToken(truetrue);
    var 
pageSelector "";
    if (
token.isSymbol(":") || token.isIdent()) {
      if (
token.isSymbol(":")) {
        
pageSelector ":";
        
token this.getToken(falsefalse);
      }
      if (
token.isIdent()) {
        
pageSelector += token.value;
        
+= " " pageSelector;
        
token this.getToken(truetrue);
      }
    }
    if (
token.isNotNull()) {
      
// expecting block start
      
if (token.isSymbol("{")) {
        
+= " " token.value;
        var 
token this.getToken(truefalse);
        while (
true) {
          if (
token.isSymbol("}")) {
            
+= "}";
            
valid true;
            break;
          } else {
            var 
this.parseDeclaration(tokendeclarationstruetrueaSheet);
            
+= ((&& declarations.length) ? " " "") + d;
          }
          
token this.getToken(truefalse);
        }
      }
    }
    if (
valid) {
      
this.forgetState();
      var 
rule = new jscsspPageRule();
      
rule.currentLine currentLine;
      
rule.parsedCssText s;
      
rule.pageSelector pageSelector;
      
rule.declarations declarations;
      
rule.parentStyleSheet aSheet;
      
aSheet.cssRules.push(rule)
      return 
true;
    }
    
this.restoreState();
    return 
false;
  },

  
parseDefaultPropertyValue: function(tokenaDeclaAcceptPrioritydescriptoraSheet) {
    var 
valueText "";
    var 
blocks = [];
    var 
foundPriority false;
    var 
values = [];
    while (
token.isNotNull()) {

      if ((
token.isSymbol(";")
           || 
token.isSymbol("}")
           || 
token.isSymbol("!"))
          && !
blocks.length) {
        if (
token.isSymbol("}"))
          
this.ungetToken();
        break;
      }
  
      if (
token.isIdent(this.kINHERIT)) {
        if (
values.length) {
          return 
"";
        }
        else {
          
valueText this.kINHERIT;
          var 
value = new jscsspVariable(kJscsspINHERIT_VALUEaSheet);
          
values.push(value);
          
token this.getToken(truetrue);
          break;
        }
      }
      else if (
token.isSymbol("{")
                 || 
token.isSymbol("(")
                 || 
token.isSymbol("[")) {
        
blocks.push(token.value);
      }
      else if (
token.isSymbol("}")
                 || 
token.isSymbol("]")) {
        if (
blocks.length) {
          var 
ontop blocks[blocks.length 1];
          if ((
token.isSymbol("}") && ontop == "{")
              || (
token.isSymbol(")") && ontop == "(")
              || (
token.isSymbol("]") && ontop == "[")) {
            
blocks.pop();
          }
        }
      }
      
// XXX must find a better way to store individual values
      // probably a |values: []| field holding dimensions, percentages
      // functions, idents, numbers and symbols, in that order.
      
if (token.isFunction()) {
        if (
token.isFunction("var(")) {
          
token this.getToken(truetrue);
          if (
token.isIdent()) {
            var 
name token.value;
            
token this.getToken(truetrue);
            if (
token.isSymbol(")")) {
              var 
value = new jscsspVariable(kJscsspVARIABLE_VALUEaSheet);
              
valueText += "var(" name ")";
              
value.name name;
              
values.push(value);
            }
            else
              return 
"";
          }
          else
            return 
"";
        }
        else {
          var 
fn token.value;
          
token this.getToken(falsetrue);
          var 
arg this.parseFunctionArgument(token);
          if (
arg) {
            
valueText += fn arg;
            var 
value = new jscsspVariable(kJscsspPRIMITIVE_VALUEaSheet);
            
value.value fn arg;
            
values.push(value);
          }
          else
            return 
"";
        }
      }
      else if (
token.isSymbol("#")) {
        var 
color this.parseColor(token);
        if (
color) {
          
valueText += color;
          var 
value = new jscsspVariable(kJscsspPRIMITIVE_VALUEaSheet);
          
value.value color;
          
values.push(value);
        }
        else
          return 
"";
      }
      else if (!
token.isWhiteSpace() && !token.isSymbol(",")) {
        var 
value = new jscsspVariable(kJscsspPRIMITIVE_VALUEaSheet);
        
value.value token.value;
        
values.push(value);
        
valueText += token.value;
      }
      else
        
valueText += token.value;
      
token this.getToken(falsetrue);
    }
    if (
values.length && valueText) {
      
this.forgetState();
      
aDecl.push(this._createJscsspDeclarationFromValuesArray(descriptorvaluesvalueText));
      return 
valueText;
    }
    return 
"";
  },

  
parseMarginOrPaddingShorthand: function(tokenaDeclaAcceptPriorityaProperty)
  {
    var 
top null;
    var 
bottom null;
    var 
left null;
    var 
right null;

    var 
values = [];
    while (
true) {

      if (!
token.isNotNull())
        break;

      if (
token.isSymbol(";")
          || (
aAcceptPriority && token.isSymbol("!"))
          || 
token.isSymbol("}")) {
        if (
token.isSymbol("}"))
          
this.ungetToken();
        break;
      }

      else if (!
values.length && token.isIdent(this.kINHERIT)) {
        
values.push(token.value);
        
token this.getToken(truetrue);
        break;
      }

      else if (
token.isDimension()
              || 
token.isNumber("0")
              || 
token.isPercentage()
              || 
token.isIdent("auto")) {
        
values.push(token.value);
      }
      else
        return 
"";

      
token this.getToken(truetrue);
    }

    var 
count values.length;
    switch (
count) {
      case 
1:
        
top values[0];
        
bottom top;
        
left top;
        
right top;
        break;
      case 
2:
        
top values[0];
        
bottom top;
        
left values[1];
        
right left;
        break;
      case 
3:
        
top values[0];
        
left values[1];
        
right left;
        
bottom values[2];
        break;
      case 
4:
        
top values[0];
        
right values[1];
        
bottom values[2];
        
left values[3];
        break;
      default:
        return 
"";
    }
    
this.forgetState();
    
aDecl.push(this._createJscsspDeclarationFromValue(aProperty "-top"top));
    
aDecl.push(this._createJscsspDeclarationFromValue(aProperty "-right"right));
    
aDecl.push(this._createJscsspDeclarationFromValue(aProperty "-bottom"bottom));
    
aDecl.push(this._createJscsspDeclarationFromValue(aProperty "-left"left));
   return 
top " " right " " bottom " " left;
  },

  
parseBorderColorShorthand: function(tokenaDeclaAcceptPriority)
  {
    var 
top null;
    var 
bottom null;
    var 
left null;
    var 
right null;

    var 
values = [];
    while (
true) {

      if (!
token.isNotNull())
        break;

      if (
token.isSymbol(";")
          || (
aAcceptPriority && token.isSymbol("!"))
          || 
token.isSymbol("}")) {
        if (
token.isSymbol("}"))
          
this.ungetToken();
        break;
      }

      else if (!
values.length && token.isIdent(this.kINHERIT)) {
        
values.push(token.value);
        
token this.getToken(truetrue);
        break;
      }
      
      else {
        var 
color this.parseColor(token);
        if (
color)
          
values.push(color);
        else
          return 
"";
      }

      
token this.getToken(truetrue);
    }

    var 
count values.length;
    switch (
count) {
      case 
1:
        
top values[0];
        
bottom top;
        
left top;
        
right top;
        break;
      case 
2:
        
top values[0];
        
bottom top;
        
left values[1];
        
right left;
        break;
      case 
3:
        
top values[0];
        
left values[1];
        
right left;
        
bottom values[2];
        break;
      case 
4:
        
top values[0];
        
right values[1];
        
bottom values[2];
        
left values[3];
        break;
      default:
        return 
"";
    }
    
this.forgetState();
    
aDecl.push(this._createJscsspDeclarationFromValue("border-top-color"top));
    
aDecl.push(this._createJscsspDeclarationFromValue("border-right-color"right));
    
aDecl.push(this._createJscsspDeclarationFromValue("border-bottom-color"bottom));
    
aDecl.push(this._createJscsspDeclarationFromValue("border-left-color"left));
    return 
top " " right " " bottom " " left;
  },

  
parseCueShorthand: function(tokendeclarationsaAcceptPriority)
  {
    var 
before "";
    var 
after "";

    var 
values = [];
    var 
values = [];
    while (
true) {

      if (!
token.isNotNull())
        break;

      if (
token.isSymbol(";")
          || (
aAcceptPriority && token.isSymbol("!"))
          || 
token.isSymbol("}")) {
        if (
token.isSymbol("}"))
          
this.ungetToken();
        break;
      }

      else if (!
values.length && token.isIdent(this.kINHERIT)) {
        
values.push(token.value);
      }

      else if (
token.isIdent("none"))
        
values.push(token.value);

        else if (
token.isFunction("url(")) {
        var 
token this.getToken(truetrue);
        var 
urlContent this.parseURL(token);
        if (
urlContent)
          
values.push("url(" urlContent);
        else
          return 
"";
      }
      else
        return 
"";

      
token this.getToken(truetrue);
    }

    var 
count values.length;
    switch (
count) {
      case 
1:
        
before values[0];
        
after before;
        break;
      case 
2:
        
before values[0];
        
after values[1];
        break;
      default:
        return 
"";
    }
    
this.forgetState();
    
aDecl.push(this._createJscsspDeclarationFromValue("cue-before"before));
    
aDecl.push(this._createJscsspDeclarationFromValue("cue-after"after));
    return 
before " " after;
  },

  
parsePauseShorthand: function(tokendeclarationsaAcceptPriority)
  {
    var 
before "";
    var 
after "";

    var 
values = [];
    var 
values = [];
    while (
true) {

      if (!
token.isNotNull())
        break;

      if (
token.isSymbol(";")
          || (
aAcceptPriority && token.isSymbol("!"))
          || 
token.isSymbol("}")) {
        if (
token.isSymbol("}"))
          
this.ungetToken();
        break;
      }

      else if (!
values.length && token.isIdent(this.kINHERIT)) {
        
values.push(token.value);
      }

      else if (
token.isDimensionOfUnit("ms")
               || 
token.isDimensionOfUnit("s")
               || 
token.isPercentage()
               || 
token.isNumber("0"))
        
values.push(token.value);
      else
        return 
"";

      
token this.getToken(truetrue);
    }

    var 
count values.length;
    switch (
count) {
      case 
1:
        
before values[0];
        
after before;
        break;
      case 
2:
        
before values[0];
        
after values[1];
        break;
      default:
        return 
"";
    }
    
this.forgetState();
    
aDecl.push(this._createJscsspDeclarationFromValue("pause-before"before));
    
aDecl.push(this._createJscsspDeclarationFromValue("pause-after"after));
    return 
before " " after;
  },

  
parseBorderWidthShorthand: function(tokenaDeclaAcceptPriority)
  {
    var 
top null;
    var 
bottom null;
    var 
left null;
    var 
right null;

    var 
values = [];
    while (
true) {

      if (!
token.isNotNull())
        break;

      if (
token.isSymbol(";")
          || (
aAcceptPriority && token.isSymbol("!"))
          || 
token.isSymbol("}")) {
        if (
token.isSymbol("}"))
          
this.ungetToken();
        break;
      }

      else if (!
values.length && token.isIdent(this.kINHERIT)) {
        
values.push(token.value);
      }
      
      else if (
token.isDimension()
               || 
token.isNumber("0")
               || (
token.isIdent() && token.value in this.kBORDER_WIDTH_NAMES)) {
        
values.push(token.value);
      }
      else
        return 
"";

      
token this.getToken(truetrue);
    }

    var 
count values.length;
    switch (
count) {
      case 
1:
        
top values[0];
        
bottom top;
        
left top;
        
right top;
        break;
      case 
2:
        
top values[0];
        
bottom top;
        
left values[1];
        
right left;
        break;
      case 
3:
        
top values[0];
        
left values[1];
        
right left;
        
bottom values[2];
        break;
      case 
4:
        
top values[0];
        
right values[1];
        
bottom values[2];
        
left values[3];
        break;
      default:
        return 
"";
    }
    
this.forgetState();
    
aDecl.push(this._createJscsspDeclarationFromValue("border-top-width"top));
    
aDecl.push(this._createJscsspDeclarationFromValue("border-right-width"right));
    
aDecl.push(this._createJscsspDeclarationFromValue("border-bottom-width"bottom));
    
aDecl.push(this._createJscsspDeclarationFromValue("border-left-width"left));
    return 
top " " right " " bottom " " left;
  },

  
parseBorderStyleShorthand: function(tokenaDeclaAcceptPriority)
  {
    var 
top null;
    var 
bottom null;
    var 
left null;
    var 
right null;

    var 
values = [];
    while (
true) {

      if (!
token.isNotNull())
        break;

      if (
token.isSymbol(";")
          || (
aAcceptPriority && token.isSymbol("!"))
          || 
token.isSymbol("}")) {
        if (
token.isSymbol("}"))
          
this.ungetToken();
        break;
      }

      else if (!
values.length && token.isIdent(this.kINHERIT)) {
        
values.push(token.value);
      }
      
      else if (
token.isIdent() && token.value in this.kBORDER_STYLE_NAMES) {
        
values.push(token.value);
      }
      else
        return 
"";

      
token this.getToken(truetrue);
    }

    var 
count values.length;
    switch (
count) {
      case 
1:
        
top values[0];
        
bottom top;
        
left top;
        
right top;
        break;
      case 
2:
        
top values[0];
        
bottom top;
        
left values[1];
        
right left;
        break;
      case 
3:
        
top values[0];
        
left values[1];
        
right left;
        
bottom values[2];
        break;
      case 
4:
        
top values[0];
        
right values[1];
        
bottom values[2];
        
left values[3];
        break;
      default:
        return 
"";
    }
    
this.forgetState();
    
aDecl.push(this._createJscsspDeclarationFromValue("border-top-style"top));
    
aDecl.push(this._createJscsspDeclarationFromValue("border-right-style"right));
    
aDecl.push(this._createJscsspDeclarationFromValue("border-bottom-style"bottom));
    
aDecl.push(this._createJscsspDeclarationFromValue("border-left-style"left));
    return 
top " " right " " bottom " " left;
  },

  
parseBorderEdgeOrOutlineShorthand: function(tokenaDeclaAcceptPriorityaProperty)
  {
    var 
bWidth null;
    var 
bStyle null;
    var 
bColor null;

    while (
true) {
      if (!
token.isNotNull())
        break;

      if (
token.isSymbol(";")
          || (
aAcceptPriority && token.isSymbol("!"))
          || 
token.isSymbol("}")) {
        if (
token.isSymbol("}"))
          
this.ungetToken();
        break;
      }

      else if (!
bWidth && !bStyle && !bColor
               
&& token.isIdent(this.kINHERIT)) {
        
bWidth this.kINHERIT;
        
bStyle this.kINHERIT;
        
bColor this.kINHERIT;
      }

      else if (!
bWidth &&
               (
token.isDimension()
                || (
token.isIdent() && token.value in this.kBORDER_WIDTH_NAMES)
                || 
token.isNumber("0"))) {
        
bWidth token.value;
      }

      else if (!
bStyle &&
               (
token.isIdent() && token.value in this.kBORDER_STYLE_NAMES)) {
        
bStyle token.value;
      }

      else {
        var 
color = (aProperty == "outline" && token.isIdent("invert"))
                    ? 
"invert" this.parseColor(token);
        if (!
bColor && color)
          
bColor color;
        else
          return 
"";
      }
      
token this.getToken(truetrue);
    }

    
// create the declarations
    
this.forgetState();
    
bWidth bWidth bWidth "medium";
    
bStyle bStyle bStyle "none";
    
bColor bColor bColor "-moz-initial";

    function 
addPropertyToDecl(aSelfaDeclpropertywsc) {
      
aDecl.push(aSelf._createJscsspDeclarationFromValue(property "-width"w));
      
aDecl.push(aSelf._createJscsspDeclarationFromValue(property "-style"s));
      
aDecl.push(aSelf._createJscsspDeclarationFromValue(property "-color"c));
    }

    if (
aProperty == "border") {
      
addPropertyToDecl(thisaDecl"border-top"bWidthbStylebColor);
      
addPropertyToDecl(thisaDecl"border-right"bWidthbStylebColor);
      
addPropertyToDecl(thisaDecl"border-bottom"bWidthbStylebColor);
      
addPropertyToDecl(thisaDecl"border-left"bWidthbStylebColor);
    }
    else
      
addPropertyToDecl(thisaDeclaPropertybWidthbStylebColor);
    return 
bWidth " " bStyle " " bColor;
  },

  
parseBackgroundShorthand: function(tokenaDeclaAcceptPriority)
  {
    var 
kHPos = {"left"true"right"true };

    var 
kVPos = {"top"true"bottom"true };
    var 
kPos = {"left"true"right"true"top"true"bottom"true"center"true};

    var 
bgColor null;
    var 
bgRepeat null;
    var 
bgAttachment null;
    var 
bgImage null;
    var 
bgPosition null;

    while (
true) {

      if (!
token.isNotNull())
        break;

      if (
token.isSymbol(";")
          || (
aAcceptPriority && token.isSymbol("!"))
          || 
token.isSymbol("}")) {
        if (
token.isSymbol("}"))
          
this.ungetToken();
        break;
      }

      else if (!
bgColor && !bgRepeat && !bgAttachment && !bgImage && !bgPosition
               
&& token.isIdent(this.kINHERIT)) {
        
bgColor this.kINHERIT;
        
bgRepeat this.kINHERIT;
        
bgAttachment this.kINHERIT;
        
bgImage this.kINHERIT;
        
bgPosition this.kINHERIT;
      }

      else {
        if (!
bgAttachment &&
            (
token.isIdent("scroll")
             || 
token.isIdent("fixed"))) {
          
bgAttachment token.value;
        }

        else if (!
bgPosition &&
                 ((
token.isIdent() && token.value in kPos)
                  || 
token.isDimension()
                  || 
token.isNumber("0")
                  || 
token.isPercentage())) {
          
bgPosition token.value;
          
token this.getToken(truetrue);
          if (
token.isDimension() || token.isNumber("0") || token.isPercentage()) {
            
bgPosition += " " token.value;
          }
          else if (
token.isIdent() && token.value in kPos) {
            if ((
bgPosition in kHPos && token.value in kHPos) ||
                (
bgPosition in kVPos && token.value in kVPos))
              return 
"";
            
bgPosition += " " token.value;
          }
          else {
            
this.ungetToken();
            
bgPosition += " center";
          }
        }

        else if (!
bgRepeat &&
                 (
token.isIdent("repeat")
                  || 
token.isIdent("repeat-x")
                  || 
token.isIdent("repeat-y")
                  || 
token.isIdent("no-repeat"))) {
          
bgRepeat token.value;
        }

        else if (!
bgImage &&
                 (
token.isFunction("url(")
                  || 
token.isIdent("none"))) {
          
bgImage token.value;
          if (
token.isFunction("url(")) {
            
token this.getToken(truetrue);
            var 
url this.parseURL(token); // TODO
            
if (url)
              
bgImage += url;
            else
              return 
"";
          }
        }

        else if (!
bgImage &&
                 (
token.isFunction("-moz-linear-gradient(")
                  || 
token.isFunction("-moz-radial-gradient(")
                  || 
token.isFunction("-moz-repeating-linear-gradient(")
                  || 
token.isFunction("-moz-repeating-radial-gradient("))) {
          var 
gradient CssInspector.parseGradient(thistoken);
          if (
gradient)
            
bgImage CssInspector.serializeGradient(gradient);
          else
            return 
"";
        }

        else {
          var 
color this.parseColor(token);
          if (!
bgColor && color)
            
bgColor color;
          else
            return 
"";
        }

      }

      
token this.getToken(truetrue);
    }

    
// create the declarations
    
this.forgetState();
    
bgColor bgColor bgColor "transparent";
    
bgImage bgImage bgImage "none";
    
bgRepeat bgRepeat bgRepeat "repeat";
    
bgAttachment bgAttachment bgAttachment "scroll";
    
bgPosition bgPosition bgPosition "top left";

    
aDecl.push(this._createJscsspDeclarationFromValue("background-color"bgColor));
    
aDecl.push(this._createJscsspDeclarationFromValue("background-image"bgImage));
    
aDecl.push(this._createJscsspDeclarationFromValue("background-repeat"bgRepeat));
    
aDecl.push(this._createJscsspDeclarationFromValue("background-attachment"bgAttachment));
    
aDecl.push(this._createJscsspDeclarationFromValue("background-position"bgPosition));
    return 
bgColor " " bgImage " " bgRepeat " " bgAttachment " " bgPosition;
  },

  
parseListStyleShorthand: function(tokenaDeclaAcceptPriority)
  {
    var 
kPosition = { "inside"true"outside"true };

    var 
lType null;
    var 
lPosition null;
    var 
lImage null;

    while (
true) {

      if (!
token.isNotNull())
        break;

      if (
token.isSymbol(";")
          || (
aAcceptPriority && token.isSymbol("!"))
          || 
token.isSymbol("}")) {
        if (
token.isSymbol("}"))
          
this.ungetToken();
        break;
      }

      else if (!
lType && !lPosition && ! lImage
               
&& token.isIdent(this.kINHERIT)) {
        
lType this.kINHERIT;
        
lPosition this.kINHERIT;
        
lImage this.kINHERIT;
      }

      else if (!
lType &&
               (
token.isIdent() && token.value in this.kLIST_STYLE_TYPE_NAMES)) {
        
lType token.value;
      }

      else if (!
lPosition &&
               (
token.isIdent() && token.value in kPosition)) {
        
lPosition token.value;
      }

      else if (!
lImage && token.isFunction("url")) {
        
token this.getToken(truetrue);
        var 
urlContent this.parseURL(token);
        if (
urlContent) {
          
lImage "url(" urlContent;
        }
        else
          return 
"";
      }
      else if (!
token.isIdent("none"))
        return 
"";

      
token this.getToken(truetrue);
    }

    
// create the declarations
    
this.forgetState();
    
lType lType lType "none";
    
lImage lImage lImage "none";
    
lPosition lPosition lPosition "outside";

    
aDecl.push(this._createJscsspDeclarationFromValue("list-style-type"lType));
    
aDecl.push(this._createJscsspDeclarationFromValue("list-style-position"lPosition));
    
aDecl.push(this._createJscsspDeclarationFromValue("list-style-image"lImage));
    return 
lType " " lPosition " " lImage;
  },

  
parseFontShorthand: function(tokenaDeclaAcceptPriority)
  {
    var 
kStyle = {"italic"true"oblique"true };
    var 
kVariant = {"small-caps"true };
    var 
kWeight = { "bold"true"bolder"true"lighter"true,
                      
"100"true"200"true"300"true"400"true,
                      
"500"true"600"true"700"true"800"true,
                      
"900"true };
    var 
kSize = { "xx-small"true"x-small"true"small"true"medium"true,
                    
"large"true"x-large"true"xx-large"true,
                    
"larger"true"smaller"true };
    var 
kValues = { "caption"true"icon"true"menu"true"message-box"true"small-caption"true"status-bar"true };
    var 
kFamily = { "serif"true"sans-serif"true"cursive"true"fantasy"true"monospace"true };

    var 
fStyle null;
    var 
fVariant null;
    var 
fWeight null;
    var 
fSize null;
    var 
fLineHeight null;
    var 
fFamily "";
    var 
fSystem null;
    var 
fFamilyValues = [];

    var 
normalCount 0;
    while (
true) {

      if (!
token.isNotNull())
        break;

      if (
token.isSymbol(";")
          || (
aAcceptPriority && token.isSymbol("!"))
          || 
token.isSymbol("}")) {
        if (
token.isSymbol("}"))
          
this.ungetToken();
        break;
      }

      else if (!
fStyle && !fVariant && !fWeight
               
&& !fSize && !fLineHeight && !fFamily
               
&& !fSystem
               
&& token.isIdent(this.kINHERIT)) {
        
fStyle this.kINHERIT;
        
fVariant this.kINHERIT;
        
fWeight this.kINHERIT;
        
fSize this.kINHERIT;
        
fLineHeight this.kINHERIT;
        
fFamily this.kINHERIT;
        
fSystem this.kINHERIT;
      }

      else {
        if (!
fSystem && (token.isIdent() && token.value in kValues)) {
          
fSystem token.value;
          break;
        }

        else {
          if (!
fStyle
                   
&& token.isIdent()
                   && (
token.value in kStyle)) {
            
fStyle token.value;
          }
  
          else if (!
fVariant
                   
&& token.isIdent()
                   && (
token.value in kVariant)) {
            
fVariant token.value;
          }
  
          else if (!
fWeight
                   
&& (token.isIdent() || token.isNumber())
                   && (
token.value in kWeight)) {
            
fWeight token.value;
          }
  
          else if (!
fSize
                   
&& ((token.isIdent() && (token.value in kSize))
                       || 
token.isDimension()
                       || 
token.isPercentage())) {
            
fSize token.value;
            var 
token this.getToken(falsefalse);
            if (
token.isSymbol("/")) {
              
token this.getToken(falsefalse);
              if (!
fLineHeight &&
                  (
token.isDimension() || token.isNumber() || token.isPercentage())) {
                
fLineHeight token.value;
              }
              else
                return 
"";
            }
            else
              
this.ungetToken();
          }

          else if (
token.isIdent("normal")) {
            
normalCount++;
            if (
normalCount 3)
              return 
"";
          }

          else if (!
fFamily && // *MUST* be last to be tested here
                   
(token.isString()
                    || 
token.isIdent())) {
            var 
lastWasComma false;
            while (
true) {
              if (!
token.isNotNull())
                break;
              else if (
token.isSymbol(";")
                  || (
aAcceptPriority && token.isSymbol("!"))
                  || 
token.isSymbol("}")) {
                
this.ungetToken();
                break;
              }
              else if (
token.isIdent() && token.value in kFamily) {
                var 
value = new jscsspVariable(kJscsspPRIMITIVE_VALUEnull);
                
value.value token.value;
                
fFamilyValues.push(value);
                
fFamily += token.value;
                break;
              }
              else if (
token.isString() || token.isIdent()) {
                var 
value = new jscsspVariable(kJscsspPRIMITIVE_VALUEnull);
                
value.value token.value;
                
fFamilyValues.push(value);
                
fFamily += token.value;
                
lastWasComma false;
              }
              else if (!
lastWasComma && token.isSymbol(",")) {
                
fFamily += ", ";
                
lastWasComma true;
              }
              else
                return 
"";
              
token this.getToken(truetrue);
            }
          }

          else {
            return 
"";
          }
        }

      }

      
token this.getToken(truetrue);
    }

    
// create the declarations
    
this.forgetState();
    if (
fSystem) {
      
aDecl.push(this._createJscsspDeclarationFromValue("font"fSystem));
      return 
fSystem;
    }
    
fStyle fStyle fStyle "normal";
    
fVariant fVariant fVariant "normal";
    
fWeight fWeight fWeight "normal";
    
fSize fSize fSize "medium";
    
fLineHeight fLineHeight fLineHeight "normal";
    
fFamily fFamily fFamily "-moz-initial";

    
aDecl.push(this._createJscsspDeclarationFromValue("font-style"fStyle));
    
aDecl.push(this._createJscsspDeclarationFromValue("font-variant"fVariant));
    
aDecl.push(this._createJscsspDeclarationFromValue("font-weight"fWeight));
    
aDecl.push(this._createJscsspDeclarationFromValue("font-size"fSize));
    
aDecl.push(this._createJscsspDeclarationFromValue("line-height"fLineHeight));
    
aDecl.push(this._createJscsspDeclarationFromValuesArray("font-family"fFamilyValuesfFamily));
    return 
fStyle " " fVariant " " fWeight " " fSize "/" fLineHeight " " fFamily;
  },

  
_createJscsspDeclaration: function(propertyvalue)
  {
    var 
decl = new jscsspDeclaration();
    
decl.property property;
    
decl.value this.trim11(value);
    
decl.parsedCssText property ": " value ";";
    return 
decl;
  },

  
_createJscsspDeclarationFromValue: function(propertyvalueText)
  {
    var 
decl = new jscsspDeclaration();
    
decl.property property;
    var 
value = new jscsspVariable(kJscsspPRIMITIVE_VALUEnull);
    
value.value valueText;
    
decl.values = [value];
    
decl.valueText valueText;
    
decl.parsedCssText property ": " valueText ";";
    return 
decl;
  },

  
_createJscsspDeclarationFromValuesArray: function(propertyvaluesvalueText)
  {
    var 
decl = new jscsspDeclaration();
    
decl.property property;
    
decl.values values;
    
decl.valueText valueText;
    
decl.parsedCssText property ": " valueText ";";
    return 
decl;
  },

  
parseURL: function(token)
  {
    var 
value "";
    if (
token.isString())
    {
      
value += token.value;
      
token this.getToken(truetrue);
    }
    else
      while (
true)
      {
        if (!
token.isNotNull()) {
          
this.reportError(kURL_EOF);
          return 
"";
        }
        if (
token.isWhiteSpace()) {
          
nextToken this.lookAhead(truetrue);
          
// if next token is not a closing parenthesis, that's an error
          
if (!nextToken.isSymbol(")")) {
            
this.reportError(kURL_WS_INSIDE);
            
token this.currentToken();
            break;
          }
        }
        if (
token.isSymbol(")")) {
          break;
        }
        
value += token.value;
        
token this.getToken(falsefalse);
      }

    if (
token.isSymbol(")")) {
      return 
value ")";
    }
    return 
"";
  },

  
parseFunctionArgument: function(token)
  {
    var 
value "";
    if (
token.isString())
    {
      
value += token.value;
      
token this.getToken(truetrue);
    }
    else {
      var 
parenthesis 1;
      while (
true)
      {
        if (!
token.isNotNull())
          return 
"";
        if (
token.isFunction() || token.isSymbol("("))
          
parenthesis++;
        if (
token.isSymbol(")")) {
          
parenthesis--;
          if (!
parenthesis)
            break;
        }
        
value += token.value;
        
token this.getToken(falsefalse);
      }
    }

    if (
token.isSymbol(")"))
      return 
value ")";
    return 
"";
  },

  
parseColor: function(token)
  {
    var 
color "";
    if (
token.isFunction("rgb(")
        || 
token.isFunction("rgba(")) {
      
color token.value;
      var 
isRgba token.isFunction("rgba(")
      
token this.getToken(truetrue);
      if (!
token.isNumber() && !token.isPercentage())
        return 
"";
      
color += token.value;
      
token this.getToken(truetrue);
      if (!
token.isSymbol(","))
        return 
"";
      
color += ", ";
  
      
token this.getToken(truetrue);
      if (!
token.isNumber() && !token.isPercentage())
        return 
"";
      
color += token.value;
      
token this.getToken(truetrue);
      if (!
token.isSymbol(","))
        return 
"";
      
color += ", ";
  
      
token this.getToken(truetrue);
      if (!
token.isNumber() && !token.isPercentage())
        return 
"";
      
color += token.value;
  
      if (
isRgba) {
        
token this.getToken(truetrue);
        if (!
token.isSymbol(","))
          return 
"";
        
color += ", ";
  
        
token this.getToken(truetrue);
        if (!
token.isNumber())
          return 
"";
        
color += token.value;
      }
  
      
token this.getToken(truetrue);
      if (!
token.isSymbol(")"))
        return 
"";
      
color += token.value;
    }
  
    else if (
token.isFunction("hsl(")
             || 
token.isFunction("hsla(")) {
      
color token.value;
      var 
isHsla token.isFunction("hsla(")
      
token this.getToken(truetrue);
      if (!
token.isNumber())
        return 
"";
      
color += token.value;
      
token this.getToken(truetrue);
      if (!
token.isSymbol(","))
        return 
"";
      
color += ", ";
  
      
token this.getToken(truetrue);
      if (!
token.isPercentage())
        return 
"";
      
color += token.value;
      
token this.getToken(truetrue);
      if (!
token.isSymbol(","))
        return 
"";
      
color += ", ";
  
      
token this.getToken(truetrue);
      if (!
token.isPercentage())
        return 
"";
      
color += token.value;
  
      if (
isHsla) {
        
token this.getToken(truetrue);
        if (!
token.isSymbol(","))
          return 
"";
        
color += ", ";
  
        
token this.getToken(truetrue);
        if (!
token.isNumber())
          return 
"";
        
color += token.value;
      }
  
      
token this.getToken(truetrue);
      if (!
token.isSymbol(")"))
        return 
"";
      
color += token.value;
    }

    else if (
token.isIdent()
             && (
token.value in this.kCOLOR_NAMES))
      
color token.value;

    else if (
token.isSymbol("#")) {
      
token this.getHexValue();
      if (!
token.isHex())
        return 
"";
      var 
length token.value.length;
      if (
length != && length != 6)
        return 
"";
      if (
token.value.match( /[a-fA-F0-9]/).length != length)
        return 
"";
      
color "#" token.value;
    }
    return 
color;
  },

  
parseDeclaration: function(aTokenaDeclaAcceptPriorityaExpandShorthandsaSheet) {
    
this.preserveState();
    var 
blocks = [];
    if (
aToken.isIdent()) {
      var 
descriptor aToken.value.toLowerCase();
      var 
token this.getToken(truetrue);
      if (
token.isSymbol(":")) {
        var 
token this.getToken(truetrue);

        var 
value "";
        var 
declarations = [];
        if (
aExpandShorthands)
          switch (
descriptor) {
            case 
"background":
              
value this.parseBackgroundShorthand(tokendeclarationsaAcceptPriority);
              break;
            case 
"margin":
            case 
"padding":
              
value this.parseMarginOrPaddingShorthand(tokendeclarationsaAcceptPrioritydescriptor);
              break;
            case 
"border-color":
              
value this.parseBorderColorShorthand(tokendeclarationsaAcceptPriority);
              break;
            case 
"border-style":
              
value this.parseBorderStyleShorthand(tokendeclarationsaAcceptPriority);
              break;
            case 
"border-width":
              
value this.parseBorderWidthShorthand(tokendeclarationsaAcceptPriority);
              break;
            case 
"border-top":
            case 
"border-right":
            case 
"border-bottom":
            case 
"border-left":
            case 
"border":
            case 
"outline":
              
value this.parseBorderEdgeOrOutlineShorthand(tokendeclarationsaAcceptPrioritydescriptor);
              break;
            case 
"cue":
              
value this.parseCueShorthand(tokendeclarationsaAcceptPriority);
              break;
            case 
"pause":
              
value this.parsePauseShorthand(tokendeclarationsaAcceptPriority);
              break;
            case 
"font":
              
value this.parseFontShorthand(tokendeclarationsaAcceptPriority);
              break;
            case 
"list-style":
              
value this.parseListStyleShorthand(tokendeclarationsaAcceptPriority);
              break;
            default:
              
value this.parseDefaultPropertyValue(tokendeclarationsaAcceptPrioritydescriptoraSheet);
              break;
          }
        else
          
value this.parseDefaultPropertyValue(tokendeclarationsaAcceptPrioritydescriptoraSheet);
        
token this.currentToken();
        if (
value// no error above
        
{
          var 
priority false;
          if (
token.isSymbol("!")) {
            
token this.getToken(truetrue);
            if (
token.isIdent("important")) {
              
priority true;
              
token this.getToken(truetrue);
              if (
token.isSymbol(";") || token.isSymbol("}")) {
                if (
token.isSymbol("}"))
                  
this.ungetToken();
              }
              else return 
"";
            }
            else return 
"";
          }
          else if  (
token.isNotNull() && !token.isSymbol(";") && !token.isSymbol("}"))
            return 
"";
          for (var 
0declarations.lengthi++) {
            
declarations[i].priority priority;
            
aDecl.push(declarations[i]);
          }
          return 
descriptor ": " value ";";
        }
      }
    }
    else if (
aToken.isComment()) {
      if (
this.mPreserveComments) {
        
this.forgetState();
        var 
comment = new jscsspComment();
        
comment.parsedCssText aToken.value;
        
aDecl.push(comment);
      }
      return 
aToken.value;
    }

    
// we have an error here, let's skip it
    
this.restoreState();
    var 
aToken.value;
    
blocks = [];
    var 
token this.getToken(falsefalse);
    while (
token.isNotNull()) {
      
+= token.value;
      if ((
token.isSymbol(";") || token.isSymbol("}")) && !blocks.length) {
        if (
token.isSymbol("}"))
          
this.ungetToken();
        break;
      } else if (
token.isSymbol("{")
                 || 
token.isSymbol("(")
                 || 
token.isSymbol("[")
                 || 
token.isFunction()) {
        
blocks.push(token.isFunction() ? "(" token.value);
      } else if (
token.isSymbol("}")
                 || 
token.isSymbol(")")
                 || 
token.isSymbol("]")) {
        if (
blocks.length) {
          var 
ontop blocks[blocks.length 1];
          if ((
token.isSymbol("}") && ontop == "{")
              || (
token.isSymbol(")") && ontop == "(")
              || (
token.isSymbol("]") && ontop == "[")) {
            
blocks.pop();
          }
        }
      }
      
token this.getToken(falsefalse);
    }
    return 
"";
  },

  
parseKeyframesRule: function(aTokenaSheet) {
    var 
currentLine CountLF(this.mScanner.getAlreadyScanned());
    var 
aToken.value;
    var 
valid false;
    var 
keyframesRule = new jscsspKeyframesRule();
    
keyframesRule.currentLine currentLine;
    
this.preserveState();
    var 
token this.getToken(truetrue);
    var 
foundName false;
    while (
token.isNotNull()) {
      if (
token.isIdent()) {
        
// should be the keyframes' name
        
foundName true;
        
+= " " token.value;
        
keyframesRule.name token.value;
        
token this.getToken(truetrue);
        if (
token.isSymbol("{"))
          
this.ungetToken();
        else {
          
// error...
          
token.type jscsspToken.NULL_TYPE;
          break;
        }
      }
      else if (
token.isSymbol("{")) {
        if (!
foundName) {
          
token.type jscsspToken.NULL_TYPE;
          
// not a valid keyframes at-rule
        
}
        break;
      }
      else {
        
token.type jscsspToken.NULL_TYPE;
        
// not a valid keyframes at-rule
        
break;
      }
      
token this.getToken(truetrue);
    }

    if (
token.isSymbol("{") && keyframesRule.name) {
      
// ok let's parse keyframe rules now...
      
+= " { ";
      
token this.getToken(truefalse);
      while (
token.isNotNull()) {
        if (
token.isComment() && this.mPreserveComments) {
          
+= " " token.value;
          var 
comment = new jscsspComment();
          
comment.parsedCssText token.value;
          
keyframesRule.cssRules.push(comment);
        } else if (
token.isSymbol("}")) {
          
valid true;
          break;
        } else {
          var 
this.parseKeyframeRule(tokenkeyframesRuletrue);
          if (
r)
            
+= r;
        }
        
token this.getToken(truefalse);
      }
    }
    if (
valid) {
      
this.forgetState();
      
keyframesRule.currentLine currentLine;
      
keyframesRule.parsedCssText s;
      
aSheet.cssRules.push(keyframesRule);
      return 
true;
    }
    
this.restoreState();
    return 
false;
  },

  
parseKeyframeRule: function(aTokenaOwner) {
    var 
currentLine CountLF(this.mScanner.getAlreadyScanned());
    
this.preserveState();
    var 
token aToken;

    
// find the keyframe keys
    
var key "";
    while (
token.isNotNull()) {
      if (
token.isIdent() || token.isPercentage()) {
        if (
token.isIdent()
            && !
token.isIdent("from")
            && !
token.isIdent("to")) {
          
key "";
          break;
        }
        
key += token.value;
        
token this.getToken(truetrue);
        if (
token.isSymbol("{")) {
          
this.ungetToken();
          break;
        }
        else 
          if (
token.isSymbol(",")) {
            
key += ", ";
          }
          else {
            
key "";
            break;
          }
      }
      else {
        
key "";
        break;
      }
      
token this.getToken(truetrue);
    }

    var 
valid false;
    var 
declarations = [];
    if (
key) {
      var 
key;
      
token this.getToken(truetrue);
      if (
token.isSymbol("{")) {
        
+= " { ";
        
token this.getToken(truefalse);
        while (
true) {
          if (!
token.isNotNull()) {
            
valid true;
            break;
          }
          if (
token.isSymbol("}")) {
            
+= "}";
            
valid true;
            break;
          } else {
            var 
this.parseDeclaration(tokendeclarationstruetrueaOwner);
            
+= ((&& declarations.length) ? " " "") + d;
          }
          
token this.getToken(truefalse);
        }
      }
    }
    else {
      
// key is invalid so the whole rule is invalid with it
    
}

    if (
valid) {
      var 
rule = new jscsspKeyframeRule();
      
rule.currentLine currentLine;
      
rule.parsedCssText s;
      
rule.declarations declarations;
      
rule.keyText key;
      
rule.parentRule aOwner;
      
aOwner.cssRules.push(rule);
      return 
s;
    }
    
this.restoreState();
    
this.currentToken().value;
    
this.addUnknownAtRule(aOwners);
    return 
"";
  },

  
parseMediaRule: function(aTokenaSheet) {
    
this.mScanner.mMediaQueryMode true;
    var 
currentLine CountLF(this.mScanner.getAlreadyScanned());
    var 
aToken.value;
    var 
valid false;
    var 
mediaRule = new jscsspMediaRule();
    
mediaRule.currentLine currentLine;
    
this.preserveState();
    var 
token this.getToken(truetrue);
    var 
foundMedia false;
    while (
token.isNotNull()) {
      if (
token.isIdent()) {
        
foundMedia true;
        
+= " " token.value;
          
mediaRule.media.push(token.value);
        
token this.getToken(truetrue);
        if (
token.isSymbol(",")) {
          
+= ",";
        } else {
          if (
token.isSymbol("{"))
            
this.ungetToken();
          else {
            
// error...
            
token.type jscsspToken.NULL_TYPE;
            break;
          }
        }
      }
      else if (
token.isSymbol("{"))
        break;
      else if (
foundMedia) {
        
token.type jscsspToken.NULL_TYPE;
        
// not a media list
        
break;
      }
      
token this.getToken(truetrue);
    }
    if (
token.isSymbol("{") && mediaRule.media.length) {
      
// ok let's parse style rules now...
      
+= " { ";
      
token this.getToken(truefalse);
      while (
token.isNotNull()) {
        if (
token.isComment() && this.mPreserveComments) {
          
+= " " token.value;
          var 
comment = new jscsspComment();
          
comment.parsedCssText token.value;
          
mediaRule.cssRules.push(comment);
        } else if (
token.isSymbol("}")) {
          
valid true;
          break;
        } else {
          var 
this.parseStyleRule(tokenmediaRuletrue);
          if (
r)
            
+= r;
        }
        
token this.getToken(truefalse);
      }
    }
    if (
valid) {
      
this.forgetState();
      
mediaRule.parsedCssText s;
      
aSheet.cssRules.push(mediaRule);
      return 
true;
    }
    
this.restoreState();
    return 
false;
  },


  
trim11: function(str) {
    
str str.replace(/^s+/, '');
    for (var 
str.length 1>= 0i--) {
      if (/
S/.teststr.charAt(i) )) { // XXX charat
        
str str.substring(01);
        break;
      }
    }
    return 
str;
  },

  
parseStyleRule: function(aTokenaOwneraIsInsideMediaRule)
  {
    var 
currentLine CountLF(this.mScanner.getAlreadyScanned());
    
this.preserveState();
    
// first let's see if we have a selector here...
    
var selector this.parseSelector(aTokenfalse);
    var 
valid false;
    var 
declarations = [];
    if (
selector) {
      
selector this.trim11(selector.selector);
      var 
selector;
      var 
token this.getToken(truetrue);
      if (
token.isSymbol("{")) {
        
+= " { ";
        var 
token this.getToken(truefalse);
        while (
true) {
          if (!
token.isNotNull()) {
            
valid true;
            break;
          }
          if (
token.isSymbol("}")) {
            
+= "}";
            
valid true;
            break;
          } else {
            var 
this.parseDeclaration(tokendeclarationstruetrueaOwner);
            
+= ((&& declarations.length) ? " " "") + d;
          }
          
token this.getToken(truefalse);
        }
      }
    }
    else {
      
// selector is invalid so the whole rule is invalid with it
    
}

    if (
valid) {
      var 
rule = new jscsspStyleRule();
      
rule.currentLine currentLine;
      
rule.parsedCssText s;
      
rule.declarations declarations;
      
rule.mSelectorText selector;
      if (
aIsInsideMediaRule)
        
rule.parentRule aOwner;
      else
        
rule.parentStyleSheet aOwner;
      
aOwner.cssRules.push(rule);
      return 
s;
    }
    
this.restoreState();
    
this.currentToken().value;
    
this.addUnknownAtRule(aOwners);
    return 
"";
  },

  
parseSelector: function(aTokenaParseSelectorOnly) {
    var 
"";
    var 
specificity = {a0b0c0d0}; // CSS 2.1 section 6.4.3
    
var isFirstInChain true;
    var 
token aToken;
    var 
valid false;
    var 
combinatorFound false;
    while (
true) {
      if (!
token.isNotNull()) {
        if (
aParseSelectorOnly)
          return {
selectorsspecificityspecificity };
        return 
"";
      }

      if (!
aParseSelectorOnly && token.isSymbol("{")) {
        
// end of selector
        
valid = !combinatorFound;
    if (
validthis.ungetToken();
        break;
      }

      if (
token.isSymbol(",")) { // group of selectors
        
+= token.value;
        
isFirstInChain true;
        
combinatorFound false;
        
token this.getToken(falsetrue);
        continue;
      }
      
// now combinators and grouping...
      
else if (!combinatorFound
           
&& (token.isWhiteSpace()
            || 
token.isSymbol(">")
                    || 
token.isSymbol("+")
                    || 
token.isSymbol("~"))) {
    if (
token.isWhiteSpace()) {
          
+= " ";
      var 
nextToken this.lookAhead(truetrue);
      if (!
nextToken.isNotNull()) {
            if (
aParseSelectorOnly)
              return {
selectorsspecificityspecificity };
        return 
"";
      }
      if (
nextToken.isSymbol(">")
          || 
nextToken.isSymbol("+")
          || 
nextToken.isSymbol("~")) {
            
token this.getToken(truetrue);
        
+= token.value " ";
        
combinatorFound true;
      }
    }
        else {
          
+= token.value;
      
combinatorFound true;
    }
    
isFirstInChain true;
        
token this.getToken(truetrue);
        continue;
      }
      else {
        var 
simpleSelector this.parseSimpleSelector(tokenisFirstInChaintrue);
        if (!
simpleSelector)
          break; 
// error
        
+= simpleSelector.selector;
        
specificity.+= simpleSelector.specificity.b;
        
specificity.+= simpleSelector.specificity.c;
        
specificity.+= simpleSelector.specificity.d;
    
isFirstInChain false;
    
combinatorFound false;
      }

      
token this.getToken(falsetrue);
    }

    if (
valid) {
      return {
selectorsspecificityspecificity };
    }
    return 
"";
  },

  
isPseudoElement: function(aIdent)
  {
    switch (
aIdent) {
      case 
"first-letter":
      case 
"first-line":
      case 
"before":
      case 
"after":
      case 
"marker":
        return 
true;
        break;
      default: return 
false;
        break;
    }
  },

  
parseSimpleSelector: function(tokenisFirstInChaincanNegate)
  {
    var 
"";
    var 
specificity = {a0b0c0d0}; // CSS 2.1 section 6.4.3
    
    
if (isFirstInChain
        
&& (token.isSymbol("*") || token.isSymbol("|") || token.isIdent())) {
      
// type or universal selector
      
if (token.isSymbol("*") || token.isIdent()) {
        
// we don't know yet if it's a prefix or a universal
        // selector
        
+= token.value;
        var 
isIdent token.isIdent();
        
token this.getToken(falsetrue);
        if (
token.isSymbol("|")) {
          
// it's a prefix
          
+= token.value;
          
token this.getToken(falsetrue);
          if (
token.isIdent() || token.isSymbol("*")) {
            
// ok we now have a type element or universal
            // selector
            
+= token.value;
            if (
token.isIdent())
              
specificity.d++;
          } else
            
// oops that's an error...
            
return null;
        } else {
          
this.ungetToken();
          if (
isIdent)
            
specificity.d++;
        }
      } else if (
token.isSymbol("|")) {
        
+= token.value;
        
token this.getToken(falsetrue);
        if (
token.isIdent() || token.isSymbol("*")) {
          
+= token.value;
          if (
token.isIdent())
            
specificity.d++;
        } else
          
// oops that's an error
          
return null;
      }
    }
  
    else if (
token.isSymbol(".") || token.isSymbol("#")) {
      var 
isClass token.isSymbol(".");
      
+= token.value;
      
token this.getToken(falsetrue);
      if (
token.isIdent()) {
        
+= token.value;
        if (
isClass)
          
specificity.c++;
        else
          
specificity.b++;
      }
      else
        return 
null;
    }

    else if (
token.isSymbol(":")) {
      
+= token.value;
      
token this.getToken(falsetrue);
      if (
token.isSymbol(":")) {
        
+= token.value;
        
token this.getToken(falsetrue);
      }
      if (
token.isIdent()) {
        
+= token.value;
        if (
this.isPseudoElement(token.value))
          
specificity.d++;
        else
          
specificity.c++;
      }
      else if (
token.isFunction()) {
        
+= token.value;
        if (
token.isFunction(":not(")) {
          if (!
canNegate)
            return 
null;
          
token this.getToken(truetrue);
          var 
simpleSelector this.parseSimpleSelector(tokenisFirstInChainfalse);
          if (!
simpleSelector)
            return 
null;
          else {
            
+= simpleSelector.selector;
            
token this.getToken(truetrue);
            if (
token.isSymbol(")"))
              
+= ")";
            else
              return 
null;
          }
          
specificity.c++;
        }
        else {
          while (
true) {
            
token this.getToken(falsetrue);
            if (
token.isSymbol(")")) {
              
+= ")";
              break;
            } else
              
+= token.value;
          }
          
specificity.c++;
        }
      } else
        return 
null;
  
    } else if (
token.isSymbol("[")) {
      
+= "[";
      
token this.getToken(truetrue);
      if (
token.isIdent() || token.isSymbol("*")) {
        
+= token.value;
        var 
nextToken this.getToken(truetrue);
        if (
token.isSymbol("|")) {
          
+= "|";
          
token this.getToken(truetrue);
          if (
token.isIdent())
            
+= token.value;
          else
            return 
null;
        } else
          
this.ungetToken();
      } else if (
token.isSymbol("|")) {
        
+= "|";
        
token this.getToken(truetrue);
        if (
token.isIdent())
          
+= token.value;
        else
          return 
null;
      }
      else
        return 
null;
  
      
// nothing, =, *=, $=, ^=, |=
      
token this.getToken(truetrue);
      if (
token.isIncludes()
          || 
token.isDashmatch()
          || 
token.isBeginsmatch()
          || 
token.isEndsmatch()
          || 
token.isContainsmatch()
          || 
token.isSymbol("=")) {
        
+= token.value;
        
token this.getToken(truetrue);
        if (
token.isString() || token.isIdent()) {
          
+= token.value;
          
token this.getToken(truetrue);
        }
        else
          return 
null;
    
        if (
token.isSymbol("]")) {
          
+= token.value;
          
specificity.c++;
        }
        else
          return 
null;
      }
      else if (
token.isSymbol("]")) {
        
+= token.value;
        
specificity.c++;
      }
      else
        return 
null;
        
    }
    else if (
token.isWhiteSpace()) {
      var 
this.lookAhead(truetrue);
      if (
t.isSymbol('{'))
        return 
""
    
}
    if (
s)
      return {
selectorsspecificityspecificity };
    return 
null;
  },

  
preserveState: function() {
    
this.mPreservedTokens.push(this.currentToken());
    
this.mScanner.preserveState();
  },

  
restoreState: function() {
    if (
this.mPreservedTokens.length) {
      
this.mScanner.restoreState();
      
this.mToken this.mPreservedTokens.pop();
    }
  },

  
forgetState: function() {
    if (
this.mPreservedTokens.length) {
      
this.mScanner.forgetState();
      
this.mPreservedTokens.pop();
    }
  },

  
parse: function(aStringaTryToPreserveWhitespacesaTryToPreserveComments) {
    if (!
aString)
      return 
null// early way out if we can

    
this.mPreserveWS       aTryToPreserveWhitespaces;
    
this.mPreserveComments aTryToPreserveComments;
    
this.mPreservedTokens = [];
    
this.mScanner.init(aString);
    var 
sheet = new jscsspStylesheet();

    
// @charset can only appear at first char of the stylesheet
    
var token this.getToken(falsefalse);
    if (!
token.isNotNull())
      return;
    if (
token.isAtRule("@charset")) {
      
this.parseCharsetRule(tokensheet);
      
token this.getToken(falsefalse);
    }

    var 
foundStyleRules false;
    var 
foundImportRules false;
    var 
foundNameSpaceRules false;
    while (
true) {
      if (!
token.isNotNull())
        break;
      if (
token.isWhiteSpace())
      {
        if (
aTryToPreserveWhitespaces)
          
this.addWhitespace(sheettoken.value);
      }

      else if (
token.isComment())
      {
        if (
this.mPreserveComments)
          
this.addComment(sheettoken.value);
      }

      else if (
token.isAtRule()) {
        if (
token.isAtRule("@variables")) {
          if (!
foundImportRules && !foundStyleRules)
            
this.parseVariablesRule(tokensheet);
          else {
            
this.reportError(kVARIABLES_RULE_POSITION);
            
this.addUnknownAtRule(sheettoken.value);
          }
        }
        else if (
token.isAtRule("@import")) {
          
// @import rules MUST occur before all style and namespace
          // rules
          
if (!foundStyleRules && !foundNameSpaceRules)
            
foundImportRules this.parseImportRule(tokensheet);
          else {
            
this.reportError(kIMPORT_RULE_POSITION);
            
this.addUnknownAtRule(sheettoken.value);
          }
        }
        else if (
token.isAtRule("@namespace")) {
          
// @namespace rules MUST occur before all style rule and
          // after all @import rules
          
if (!foundStyleRules)
            
foundNameSpaceRules this.parseNamespaceRule(tokensheet);
          else {
            
this.reportError(kNAMESPACE_RULE_POSITION);
            
this.addUnknownAtRule(sheettoken.value);
          }
        }
        else if (
token.isAtRule("@font-face")) {
          if (
this.parseFontFaceRule(tokensheet))
            
foundStyleRules true;
          else
            
this.addUnknownAtRule(sheettoken.value);
        }
        else if (
token.isAtRule("@page")) {
          if (
this.parsePageRule(tokensheet))
            
foundStyleRules true;
          else
            
this.addUnknownAtRule(sheettoken.value);
        }
        else if (
token.isAtRule("@media")) {
          if (
this.parseMediaRule(tokensheet))
            
foundStyleRules true;
          else
            
this.addUnknownAtRule(sheettoken.value);
        }
        else if (
token.isAtRule("@keyframes")) {
          if (!
this.parseKeyframesRule(tokensheet))
            
this.addUnknownAtRule(sheettoken.value);
        }
        else if (
token.isAtRule("@charset")) {
          
this.reportError(kCHARSET_RULE_CHARSET_SOF);
          
this.addUnknownAtRule(sheettoken.value);
        }
        else {
          
this.reportError(kUNKNOWN_AT_RULE);
          
this.addUnknownAtRule(sheettoken.value);
        }
      }

      else 
// plain style rules
      
{
        var 
ruleText this.parseStyleRule(tokensheetfalse);
        if (
ruleText)
          
foundStyleRules true;
      }
      
token this.getToken(false);
    }

    return 
sheet;
  }

};


function 
jscsspToken(aTypeaValueaUnit)
{
  
this.type aType;
  
this.value aValue;
  
this.unit aUnit;
}

jscsspToken.NULL_TYPE 0;

jscsspToken.WHITESPACE_TYPE 1;
jscsspToken.STRING_TYPE 2;
jscsspToken.COMMENT_TYPE 3;
jscsspToken.NUMBER_TYPE 4;
jscsspToken.IDENT_TYPE 5;
jscsspToken.FUNCTION_TYPE 6;
jscsspToken.ATRULE_TYPE 7;
jscsspToken.INCLUDES_TYPE 8;
jscsspToken.DASHMATCH_TYPE 9;
jscsspToken.BEGINSMATCH_TYPE 10;
jscsspToken.ENDSMATCH_TYPE 11;
jscsspToken.CONTAINSMATCH_TYPE 12;
jscsspToken.SYMBOL_TYPE 13;
jscsspToken.DIMENSION_TYPE 14;
jscsspToken.PERCENTAGE_TYPE 15;
jscsspToken.HEX_TYPE 16;

jscsspToken.prototype = {

  
isNotNull: function ()
  {
    return 
this.type;
  },

  
_isOfType: function (aTypeaValue)
  {
    return (
this.type == aType && (!aValue || this.value.toLowerCase() == aValue));
  },

  
isWhiteSpace: function(w)
  {
    return 
this._isOfType(jscsspToken.WHITESPACE_TYPEw);
  },

  
isString: function()
  {
    return 
this._isOfType(jscsspToken.STRING_TYPE);
  },

  
isComment: function()
  {
    return 
this._isOfType(jscsspToken.COMMENT_TYPE);
  },

  
isNumber: function(n)
  {
    return 
this._isOfType(jscsspToken.NUMBER_TYPEn);
  },

  
isSymbol: function(c)
  {
    return 
this._isOfType(jscsspToken.SYMBOL_TYPEc);
  },

  
isIdent: function(i)
  {
    return 
this._isOfType(jscsspToken.IDENT_TYPEi);
  },

  
isFunction: function(f)
  {
    return 
this._isOfType(jscsspToken.FUNCTION_TYPEf);
  },

  
isAtRule: function(a)
  {
    return 
this._isOfType(jscsspToken.ATRULE_TYPEa);
  },

  
isIncludes: function()
  {
    return 
this._isOfType(jscsspToken.INCLUDES_TYPE);
  },

  
isDashmatch: function()
  {
    return 
this._isOfType(jscsspToken.DASHMATCH_TYPE);
  },

  
isBeginsmatch: function()
  {
    return 
this._isOfType(jscsspToken.BEGINSMATCH_TYPE);
  },

  
isEndsmatch: function()
  {
    return 
this._isOfType(jscsspToken.ENDSMATCH_TYPE);
  },

  
isContainsmatch: function()
  {
    return 
this._isOfType(jscsspToken.CONTAINSMATCH_TYPE);
  },

  
isSymbol: function(c)
  {
    return 
this._isOfType(jscsspToken.SYMBOL_TYPEc);
  },

  
isDimension: function()
  {
    return 
this._isOfType(jscsspToken.DIMENSION_TYPE);
  },

  
isPercentage: function()
  {
    return 
this._isOfType(jscsspToken.PERCENTAGE_TYPE);
  },

  
isHex: function()
  {
    return 
this._isOfType(jscsspToken.HEX_TYPE);
  },

  
isDimensionOfUnit: function(aUnit)
  {
    return (
this.isDimension() && this.unit == aUnit);
  },

  
isLength: function()
  {
    return (
this.isPercentage() ||
            
this.isDimensionOfUnit("cm") ||
            
this.isDimensionOfUnit("mm") ||
            
this.isDimensionOfUnit("in") ||
            
this.isDimensionOfUnit("pc") ||
            
this.isDimensionOfUnit("px") ||
            
this.isDimensionOfUnit("em") ||
            
this.isDimensionOfUnit("ex") ||
            
this.isDimensionOfUnit("pt"));
  },

  
isAngle: function()
  {
    return (
this.isDimensionOfUnit("deg") ||
            
this.isDimensionOfUnit("rad") ||
            
this.isDimensionOfUnit("grad"));
  }
}

var 
kJscsspUNKNOWN_RULE   0;
var 
kJscsspSTYLE_RULE     1
var kJscsspCHARSET_RULE   2;
var 
kJscsspIMPORT_RULE    3;
var 
kJscsspMEDIA_RULE     4;
var 
kJscsspFONT_FACE_RULE 5;
var 
kJscsspPAGE_RULE      6;

var 
kJscsspKEYFRAMES_RULE 7;
var 
kJscsspKEYFRAME_RULE  8;

var 
kJscsspNAMESPACE_RULE 100;
var 
kJscsspCOMMENT        101;
var 
kJscsspWHITE_SPACE    102;

var 
kJscsspVARIABLES_RULE 200;

var 
kJscsspSTYLE_DECLARATION 1000;

var 
gTABS "";

function 
jscsspStylesheet()
{
  
this.cssRules = [];
  
this.variables = {};
}

jscsspStylesheet.prototype = {
  
insertRule: function(aRuleaIndex) {
    try {
     
this.cssRules.splice(aIndex1aRule);
    }
    catch(
e) {
    }
  },

  
deleteRule: function(aIndex) {
    try {
      
this.cssRules.splice(aIndex);
    }
    catch(
e) {
    }
  },

  
cssText: function() {
    var 
rv "";
    for (var 
0this.cssRules.lengthi++)
      
rv += this.cssRules[i].cssText() + "n";
    return 
rv;
  },

  
resolveVariables: function(aMedium) {

    function 
ItemFoundInArray(aArrayaItem) {
      for (var 
0aArray.lengthi++)
        if (
aItem == aArray[i])
          return 
true;
      return 
false;
    }
    
    for (var 
0this.cssRules.lengthi++)
    {
      var 
rule this.cssRules[i];
      if (
rule.type == kJscsspSTYLE_RULE || rule.type == kJscsspIMPORT_RULE)
        break;
      else if (
rule.type == kJscsspVARIABLES_RULE &&
               (!
rule.media.length || ItemFoundInArray(rule.mediaaMedium))) {
        
        for (var 
0rule.declarations.lengthj++) {
          var 
valueText "";
          for (var 
0rule.declarations[j].values.lengthk++)
            
valueText += (" " "") + rule.declarations[j].values[k].value;
          
this.variables[rule.declarations[j].property] = valueText;
        }
      }
    }
  }
};

/* kJscsspCHARSET_RULE */

function jscsspCharsetRule()
{
  
this.type kJscsspCHARSET_RULE;
  
this.encoding null;
  
this.parsedCssText null;
  
this.parentStyleSheet null;
  
this.parentRule null;
}

jscsspCharsetRule.prototype = {

  
cssText: function() {
    return 
"@charset " this.encoding ";";
  },

  
setCssText: function(val) {
    var 
sheet = {cssRules: []};
    var 
parser = new CSSParser(val);
    var 
token parser.getToken(falsefalse);
    if (
token.isAtRule("@charset")) {
      if (
parser.parseCharsetRule(tokensheet)) {
        var 
newRule sheet.cssRules[0];
        
this.encoding newRule.encoding;
        
this.parsedCssText newRule.parsedCssText;
        return;
      }
    }
    throw 
DOMException.SYNTAX_ERR;
  }
};

/* kJscsspUNKNOWN_RULE */

function jscsspErrorRule(aErrorMsg)
{
  
this.error aErrorMsg aErrorMsg "INVALID"
  
this.type kJscsspUNKNOWN_RULE;
  
this.parsedCssText null;
  
this.parentStyleSheet null;
  
this.parentRule null;
}

jscsspErrorRule.prototype = {
  
cssText: function() {
    return 
this.parsedCssText;
  }
};

/* kJscsspCOMMENT */

function jscsspComment()
{
  
this.type kJscsspCOMMENT;
  
this.parsedCssText null;
  
this.parentStyleSheet null;
  
this.parentRule null;
}

jscsspComment.prototype = {
  
cssText: function() {
    return 
this.parsedCssText;
  },

  
setCssText: function(val) {
    var 
parser = new CSSParser(val);
    var 
token parser.getToken(truefalse);
    if (
token.isComment())
      
this.parsedCssText token.value;
    else
      throw 
DOMException.SYNTAX_ERR;
  }
};

/* kJscsspWHITE_SPACE */

function jscsspWhitespace()
{
  
this.type kJscsspWHITE_SPACE;
  
this.parsedCssText null;
  
this.parentStyleSheet null;
  
this.parentRule null;
}

jscsspWhitespace.prototype = {
  
cssText: function() {
    return 
this.parsedCssText;
  }
};

/* kJscsspIMPORT_RULE */

function jscsspImportRule()
{
  
this.type kJscsspIMPORT_RULE;
  
this.parsedCssText null;
  
this.href null;
  
this.media = []; 
  
this.parentStyleSheet null;
  
this.parentRule null;
}

jscsspImportRule.prototype = {
  
cssText: function() {
    var 
mediaString this.media.join(", ");
    return 
"@import " this.href
                      
+ ((mediaString && mediaString != "all") ? mediaString " " "")
                      + 
";";
  },

  
setCssText: function(val) {
    var 
sheet = {cssRules: []};
    var 
parser = new CSSParser(val);
    var 
token parser.getToken(truetrue);
    if (
token.isAtRule("@import")) {
      if (
parser.parseImportRule(tokensheet)) {
        var 
newRule sheet.cssRules[0];
        
this.href newRule.href;
        
this.media newRule.media;
        
this.parsedCssText newRule.parsedCssText;
        return;
      }
    }
    throw 
DOMException.SYNTAX_ERR;
  }
};

/* kJscsspNAMESPACE_RULE */

function jscsspNamespaceRule()
{
  
this.type kJscsspNAMESPACE_RULE;
  
this.parsedCssText null;
  
this.prefix null;
  
this.url null;
  
this.parentStyleSheet null;
  
this.parentRule null;
}

jscsspNamespaceRule.prototype = {
  
cssText: function() {
    return 
"@namespace " + (this.prefix this.prefix " """)
                        + 
this.url
                        
";";
  },

  
setCssText: function(val) {
    var 
sheet = {cssRules: []};
    var 
parser = new CSSParser(val);
    var 
token parser.getToken(truetrue);
    if (
token.isAtRule("@namespace")) {
      if (
parser.parseNamespaceRule(tokensheet)) {
        var 
newRule sheet.cssRules[0];
        
this.url newRule.url;
        
this.prefix newRule.prefix;
        
this.parsedCssText newRule.parsedCssText;
        return;
      }
    }
    throw 
DOMException.SYNTAX_ERR;
  }
};

/* kJscsspSTYLE_DECLARATION */

function jscsspDeclaration()
{
  
this.type kJscsspSTYLE_DECLARATION;
  
this.property null;
  
this.values = [];
  
this.valueText null;
  
this.priority null;
  
this.parsedCssText null;
  
this.parentStyleSheet null;
  
this.parentRule null;
}

jscsspDeclaration.prototype = {
  
kCOMMA_SEPARATED: {
    
"cursor"true,
    
"font-family"true,
    
"voice-family"true,
    
"background-image"true
  
},

  
kUNMODIFIED_COMMA_SEPARATED_PROPERTIES: {
    
"text-shadow"true,
    
"box-shadow"true,
    
"-moz-transition"true,
    
"-moz-transition-property"true,
    
"-moz-transition-duration"true,
    
"-moz-transition-timing-function"true,
    
"-moz-transition-delay"true
  
},

  
cssText: function() {
    var 
prefixes CssInspector.prefixesForProperty(this.property);

    if (
this.property in this.kUNMODIFIED_COMMA_SEPARATED_PROPERTIES) {
      if (
prefixes) {
        var 
rv "";
        for (var 
propertyIndex 0propertyIndex prefixes.lengthpropertyIndex++) {
          var 
property prefixes[propertyIndex];
          
rv += (propertyIndex gTABS "") + property ": ";
          
rv += this.valueText + (this.priority " !important" "") + ";";
          
rv += ((prefixes.length && propertyIndex != prefixes.length -1) ? "n" "");
        }
        return 
rv;
      }
      return 
this.property ": " this.valueText +
             (
this.priority " !important" "") + ";"
    
}

    if (
prefixes) {
      var 
rv "";
      for (var 
propertyIndex 0propertyIndex prefixes.lengthpropertyIndex++) {
        var 
property prefixes[propertyIndex];
        
rv += (propertyIndex gTABS "") + property ": ";
        var 
separator = (property in this.kCOMMA_SEPARATED) ? ", " " ";
        for (var 
0this.values.lengthi++)
          if (
this.values[i].cssText() != null)
            
rv += (separator "") + this.values[i].cssText();
          else
            return 
null;
        
rv += (this.priority " !important" "") + ";" +
              ((
prefixes.length && propertyIndex != prefixes.length -1) ? "n" "");
      }
      return 
rv;
    }

    var 
rv this.property ": ";
    var 
separator = (this.property in this.kCOMMA_SEPARATED) ? ", " " ";
    var 
extras = {"webkit"false"presto"false"trident"false"generic"false }
    for (var 
0this.values.lengthi++) {
      var 
this.values[i].cssText();
      if (
!= null) {
        var 
paren v.indexOf("(");
        var 
kwd v;
        if (
paren != -1)
          
kwd v.substr(0paren);
        if (
kwd in kCSS_VENDOR_VALUES) {
          for (var 
j in kCSS_VENDOR_VALUES[kwd]) {
            
extras[j] = extras[j] || (kCSS_VENDOR_VALUES[kwd][j] != "");
          }
        }
        
rv += (separator "") + v;
      }
      else
        return 
null;
    }
    
rv += (this.priority " !important" "") + ";";

    for (var 
j in extras) {
      if (
extras[j]) {
        var 
str "n" gTABS +  this.property ": ";
        for (var 
0this.values.lengthi++) {
          var 
this.values[i].cssText();
          if (
!= null) {
            var 
paren v.indexOf("(");
            var 
kwd v;
            if (
paren != -1)
              
kwd v.substr(0paren);
            if (
kwd in kCSS_VENDOR_VALUES) {
              
functor kCSS_VENDOR_VALUES[kwd][j];
              if (
functor) {
                
= (typeof functor == "string") ? functor functor(vj);
                if (!
v) {
                  
str null;
                  break;
                }
              }
            }
            
str += (separator "") + v;
          }
          else
            return 
null;
        }
        if (
str)
          
rv += str ";"
        
else
          
rv += "n" gTABS "/* Impossible to translate property " this.property " for " " */";
      }
    }
    return 
rv;
  },

  
setCssText: function(val) {
    var 
declarations = [];
    var 
parser = new CSSParser(val);
    var 
token parser.getToken(truetrue);
    if (
parser.parseDeclaration(tokendeclarationstruetruenull)
        && 
declarations.length
        
&& declarations[0].type == kJscsspSTYLE_DECLARATION) {
      var 
newDecl declarations.cssRules[0];
      
this.property newDecl.property;
      
this.value newDecl.value;
      
this.priority newDecl.priority;
      
this.parsedCssText newRule.parsedCssText;
      return;
    }
    throw 
DOMException.SYNTAX_ERR;
  }
};

/* kJscsspFONT_FACE_RULE */

function jscsspFontFaceRule()
{
  
this.type kJscsspFONT_FACE_RULE;
  
this.parsedCssText null;
  
this.descriptors = [];
  
this.parentStyleSheet null;
  
this.parentRule null;
}

jscsspFontFaceRule.prototype = {
  
cssText: function() {
    var 
rv gTABS "@font-face {n";
    var 
preservedGTABS gTABS;
    
gTABS += "  ";
    for (var 
0this.descriptors.lengthi++)
      
rv += gTABS this.descriptors[i].cssText() + "n";
    
gTABS preservedGTABS;
    return 
rv gTABS "}";
  },

  
setCssText: function(val) {
    var 
sheet = {cssRules: []};
    var 
parser = new CSSParser(val);
    var 
token parser.getToken(truetrue);
    if (
token.isAtRule("@font-face")) {
      if (
parser.parseFontFaceRule(tokensheet)) {
        var 
newRule sheet.cssRules[0];
        
this.descriptors newRule.descriptors;
        
this.parsedCssText newRule.parsedCssText;
        return;
      }
    }
    throw 
DOMException.SYNTAX_ERR;
  }
};

/* kJscsspKEYFRAMES_RULE */
function jscsspKeyframesRule()
{
  
this.type kJscsspKEYFRAMES_RULE;
  
this.parsedCssText null;
  
this.cssRules = [];
  
this.name null;
  
this.parentStyleSheet null;
  
this.parentRule null;
}

jscsspKeyframesRule.prototype = {
  
cssText: function() {
    var 
rv gTABS
               
"@keyframes "
               
this.name " {n";
    var 
preservedGTABS gTABS;
    
gTABS += "  ";
    for (var 
0this.cssRules.lengthi++)
      
rv += gTABS this.cssRules[i].cssText() + "n";
    
gTABS preservedGTABS;
    
rv += gTABS "}n";
    return 
rv;
  },

  
setCssText: function(val) {
    var 
sheet = {cssRules: []};
    var 
parser = new CSSParser(val);
    var 
token parser.getToken(truetrue);
    if (
token.isAtRule("@keyframes")) {
      if (
parser.parseKeyframesRule(tokensheet)) {
        var 
newRule sheet.cssRules[0];
        
this.cssRules newRule.cssRules;
        
this.name newRule.name;
        
this.parsedCssText newRule.parsedCssText;
        return;
      }
    }
    throw 
DOMException.SYNTAX_ERR;
  }
};

/* kJscsspKEYFRAME_RULE */
function jscsspKeyframeRule()
{
  
this.type kJscsspKEYFRAME_RULE;
  
this.parsedCssText null;
  
this.declarations = []
  
this.keyText null;
  
this.parentStyleSheet null;
  
this.parentRule null;
}

jscsspKeyframeRule.prototype = {
  
cssText: function() {
    var 
rv this.keyText " {n";
    var 
preservedGTABS gTABS;
    
gTABS += "  ";
    for (var 
0this.declarations.lengthi++) {
      var 
declText this.declarations[i].cssText();
      if (
declText)
        
rv += gTABS this.declarations[i].cssText() + "n";
    }
    
gTABS preservedGTABS;
    return 
rv gTABS "}";
  },

  
setCssText: function(val) {
    var 
sheet = {cssRules: []};
    var 
parser = new CSSParser(val);
    var 
token parser.getToken(truetrue);
    if (!
token.isNotNull()) {
      if (
parser.parseKeyframeRule(tokensheetfalse)) {
        var 
newRule sheet.cssRules[0];
        
this.keyText newRule.keyText;
        
this.declarations newRule.declarations;
        
this.parsedCssText newRule.parsedCssText;
        return;
      }
    }
    throw 
DOMException.SYNTAX_ERR;
  }
};

/* kJscsspMEDIA_RULE */

function jscsspMediaRule()
{
  
this.type kJscsspMEDIA_RULE;
  
this.parsedCssText null;
  
this.cssRules = [];
  
this.media = [];
  
this.parentStyleSheet null;
  
this.parentRule null;
}

jscsspMediaRule.prototype = {
  
cssText: function() {
    var 
rv gTABS "@media " this.media.join(", ") + " {n";
    var 
preservedGTABS gTABS;
    
gTABS += "  ";
    for (var 
0this.cssRules.lengthi++)
      
rv += gTABS this.cssRules[i].cssText() + "n";
    
gTABS preservedGTABS;
    return 
rv gTABS "}";
  },

  
setCssText: function(val) {
    var 
sheet = {cssRules: []};
    var 
parser = new CSSParser(val);
    var 
token parser.getToken(truetrue);
    if (
token.isAtRule("@media")) {
      if (
parser.parseMediaRule(tokensheet)) {
        var 
newRule sheet.cssRules[0];
        
this.cssRules newRule.cssRules;
        
this.media newRule.media;
        
this.parsedCssText newRule.parsedCssText;
        return;
      }
    }
    throw 
DOMException.SYNTAX_ERR;
  }
};

/* kJscsspSTYLE_RULE */

function jscsspStyleRule()
{
  
this.type kJscsspSTYLE_RULE;
  
this.parsedCssText null;
  
this.declarations = []
  
this.mSelectorText null;
  
this.parentStyleSheet null;
  
this.parentRule null;
}

jscsspStyleRule.prototype = {
  
cssText: function() {
    var 
rv this.mSelectorText " {n";
    var 
preservedGTABS gTABS;
    
gTABS += "  ";
    for (var 
0this.declarations.lengthi++) {
      var 
declText this.declarations[i].cssText();
      if (
declText)
        
rv += gTABS this.declarations[i].cssText() + "n";
    }
    
gTABS preservedGTABS;
    return 
rv gTABS "}";
  },

  
setCssText: function(val) {
    var 
sheet = {cssRules: []};
    var 
parser = new CSSParser(val);
    var 
token parser.getToken(truetrue);
    if (!
token.isNotNull()) {
      if (
parser.parseStyleRule(tokensheetfalse)) {
        var 
newRule sheet.cssRules[0];
        
this.mSelectorText newRule.mSelectorText;
        
this.declarations newRule.declarations;
        
this.parsedCssText newRule.parsedCssText;
        return;
      }
    }
    throw 
DOMException.SYNTAX_ERR;
  },

  
selectorText: function() {
    return 
this.mSelectorText;
  },

  
setSelectorText: function(val) {
    var 
parser = new CSSParser(val);
    var 
token parser.getToken(truetrue);
    if (!
token.isNotNull()) {
      var 
parser.parseSelector(tokentrue);
      if (
s) {
        
this.mSelectorText s.selector;
        return;
      }
    }
    throw 
DOMException.SYNTAX_ERR;
  }
};

/* kJscsspPAGE_RULE */

function jscsspPageRule()
{
  
this.type kJscsspPAGE_RULE;
  
this.parsedCssText null;
  
this.pageSelector null;
  
this.declarations = [];
  
this.parentStyleSheet null;
  
this.parentRule null;
}

jscsspPageRule.prototype = {
  
cssText: function() {
    var 
rv gTABS "@page "
                   
+ (this.pageSelector this.pageSelector " """)
                   + 
"{n";
    var 
preservedGTABS gTABS;
    
gTABS += "  ";
    for (var 
0this.declarations.lengthi++)
      
rv += gTABS this.declarations[i].cssText() + "n";
    
gTABS preservedGTABS;
    return 
rv gTABS "}";
  },

  
setCssText: function(val) {
    var 
sheet = {cssRules: []};
    var 
parser = new CSSParser(val);
    var 
token parser.getToken(truetrue);
    if (
token.isAtRule("@page")) {
      if (
parser.parsePageRule(tokensheet)) {
        var 
newRule sheet.cssRules[0];
        
this.pageSelector newRule.pageSelector;
        
this.declarations newRule.declarations;
        
this.parsedCssText newRule.parsedCssText;
        return;
      }
    }
    throw 
DOMException.SYNTAX_ERR;
  }
};

/* kJscsspVARIABLES_RULE */

function jscsspVariablesRule()
{
  
this.type kJscsspVARIABLES_RULE;
  
this.parsedCssText null;
  
this.declarations = [];
  
this.parentStyleSheet null;
  
this.parentRule null;
  
this.media null;
}

jscsspVariablesRule.prototype = {
  
cssText: function() {
    var 
rv gTABS "@variables " +
                     (
this.media.length this.media.join(", ") + " " "") +
                     
"{n";
    var 
preservedGTABS gTABS;
    
gTABS += "  ";
    for (var 
0this.declarations.lengthi++)
      
rv += gTABS this.declarations[i].cssText() + "n";
    
gTABS preservedGTABS;
    return 
rv gTABS "}";
  },

  
setCssText: function(val) {
    var 
sheet = {cssRules: []};
    var 
parser = new CSSParser(val);
    var 
token parser.getToken(truetrue);
    if (
token.isAtRule("@variables")) {
      if (
parser.parseVariablesRule(tokensheet)) {
        var 
newRule sheet.cssRules[0];
        
this.declarations newRule.declarations;
        
this.parsedCssText newRule.parsedCssText;
        return;
      }
    }
    throw 
DOMException.SYNTAX_ERR;
  }
};

var 
kJscsspINHERIT_VALUE 0;
var 
kJscsspPRIMITIVE_VALUE 1;
var 
kJscsspVARIABLE_VALUE 4;

function 
jscsspVariable(aTypeaSheet)
{
  
this.value "";
  
this.type aType;
  
this.name  null;
  
this.parentRule null;
  
this.parentStyleSheet aSheet;
}

jscsspVariable.prototype = {
  
cssText: function() {
    if (
this.type == kJscsspVARIABLE_VALUE)
      return 
this.resolveVariable(this.namethis.parentRulethis.parentStyleSheet);
    else
      return 
this.value;
  },

  
setCssText: function(val) {
    if (
this.type == kJscsspVARIABLE_VALUE)
      throw 
DOMException.SYNTAX_ERR;
    else
      
this.value val;
  },

  
resolveVariable: function(aNameaRuleaSheet)
  {
    if (
aName.toLowerCase() in aSheet.variables)
      return 
aSheet.variables[aName.toLowerCase()];
    return 
null;
  }
};

function 
ParseURL(buffer) {
  var 
result = { };
  
result.protocol "";
  
result.user "";
  
result.password "";
  
result.host "";
  
result.port "";
  
result.path "";
  
result.query "";

  var 
section "PROTOCOL";
  var 
start 0;
  var 
wasSlash false;

  while(
start buffer.length) {
    if(
section == "PROTOCOL") {
      if(
buffer.charAt(start) == ':') {
        
section "AFTER_PROTOCOL";
        
start++;
      } else if(
buffer.charAt(start) == '/' && result.protocol.length() == 0) { 
        
section PATH;
      } else {
        
result.protocol += buffer.charAt(start++);
      }
    } else if(
section == "AFTER_PROTOCOL") {
      if(
buffer.charAt(start) == '/') {
    if(!
wasSlash) {
          
wasSlash true;
    } else {
          
wasSlash false;
          
section "USER";
    }
        
start ++;
      } else {
        throw new 
ParseException("Protocol shell be separated with 2 slashes");
      }       
    } else if(
section == "USER") {
      if(
buffer.charAt(start) == '/') {
        
result.host result.user;
        
result.user "";
        
section "PATH";
      } else if(
buffer.charAt(start) == '?') {
        
result.host result.user;
        
result.user "";
        
section "QUERY";
        
start++;
      } else if(
buffer.charAt(start) == ':') {
        
section "PASSWORD";
        
start++;
      } else if(
buffer.charAt(start) == '@') {
        
section "HOST";
        
start++;
      } else {
        
result.user += buffer.charAt(start++);
      }
    } else if(
section == "PASSWORD") {
      if(
buffer.charAt(start) == '/') {
        
result.host result.user;
        
result.port result.password;
        
result.user "";
        
result.password "";
        
section "PATH";
      } else if(
buffer.charAt(start) == '?') {
        
result.host result.user;
        
result.port result.password;
        
result.user "";
        
result.password "";
        
section "QUERY";
        
start ++;
      } else if(
buffer.charAt(start) == '@') {
        
section "HOST";
        
start++;
      } else {
        
result.password += buffer.charAt(start++);
      }
    } else if(
section == "HOST") {
      if(
buffer.charAt(start) == '/') {
        
section "PATH";
      } else if(
buffer.charAt(start) == ':') {
        
section "PORT";
        
start++;
      } else if(
buffer.charAt(start) == '?') {
        
section "QUERY";
        
start++;
      } else {
        
result.host += buffer.charAt(start++);
      }
    } else if(
section == "PORT") {
      if(
buffer.charAt(start) == '/') {
        
section "PATH";
      } else if(
buffer.charAt(start) == '?') {
        
section "QUERY";
        
start++;
      } else {
        
result.port += buffer.charAt(start++);
      }
    } else if(
section == "PATH") {
      if(
buffer.charAt(start) == '?') {
    
section "QUERY";
    
start ++;
      } else {
    
result.path += buffer.charAt(start++);
      }
    } else if(
section == "QUERY") {
      
result.query += buffer.charAt(start++);
    }
  }

  if(
section == "PROTOCOL") {
    
result.host result.protocol;
    
result.protocol "http";
  } else if(
section == "AFTER_PROTOCOL") {
    throw new 
ParseException("Invalid url");
  } else if(
section == "USER") {
    
result.host result.user;
    
result.user "";
  } else if(
section == "PASSWORD") {
    
result.host result.user;
    
result.port result.password;
    
result.user "";
    
result.password "";
  }

  return 
result;
}

function 
ParseException(description) {
    
this.description description;
}

function 
CountLF(s)
{
  var 
nCR s.match( /n/);
  return 
nCR nCR.length 1;
}


function 
FilterLinearGradientForOutput(aValueaEngine)
{
  if (
aEngine == "generic")
    return 
aValue.substr(5);

  if (
aEngine == "webkit")
    return 
aValue.replace( /-moz-/"-webkit-")

  if (
aEngine != "webkit20110101")
    return 
"";

  var 
CssInspector.parseBackgroundImages(aValue)[0];

  var 
cancelled false;
  var 
str "-webkit-gradient(linear, ";
  var 
position = ("position" in g.value) ? g.value.position.toLowerCase() : "";
  var 
angle    = ("angle" in g.value) ? g.value.angle.toLowerCase() : "";
  
// normalize angle
  
if (angle) {
    var 
match angle.match(/^([0-9-.\+]+)([a-z]*)/);
    var 
angle parseFloat(match[1]);
    var 
unit  match[2];
    switch (
unit) {
      case 
"grad"angle angle 90 100; break;
      case 
"rad":  angle angle 180 Math.PI; break;
      default: break;
    }
    while (
angle 0)
      
angle += 360;
    while (
angle >= 360)
      
angle -= 360;
  }
  
// get startpoint w/o keywords
  
var startpoint = [];
  var 
endpoint = [];
  if (
position != "") {
    if (
position == "center")
      
position "center center";
    
startpoint position.split(" ");
    if (
angle == "" && angle != 0) {
      
// no angle, then we just turn the point 180 degrees around center
      
switch (startpoint[0]) {
        case 
"left":   endpoint.push("right"); break;
        case 
"center"endpoint.push("center"); break;
        case 
"right":  endpoint.push("left"); break;
        default: {
            var 
match startpoint[0].match(/^([0-9-.\+]+)([a-z]*)/);
            var 
v     parseFloat(match[0]);
            var 
unit  match[1];
            if (
unit == "%") {
              
endpoint.push((100-v) + "%");
            }
            else
              
cancelled true;
          }
          break;
      }
      if (!
cancelled)
        switch (
startpoint[1]) {
          case 
"top":    endpoint.push("bottom"); break;
          case 
"center"endpoint.push("center"); break;
          case 
"bottom"endpoint.push("top"); break;
          default: {
              var 
match startpoint[1].match(/^([0-9-.\+]+)([a-z]*)/);
              var 
v     parseFloat(match[0]);
              var 
unit  match[1];
              if (
unit == "%") {
                
endpoint.push((100-v) + "%");
              }
              else
                
cancelled true;
            }
            break;
        }
    }
    else {
      switch (
angle) {
        case 
0:    endpoint.push("right"); endpoint.push(startpoint[1]); break;
        case 
90:   endpoint.push(startpoint[0]); endpoint.push("top"); break;
        case 
180:  endpoint.push("left"); endpoint.push(startpoint[1]); break;
        case 
270:  endpoint.push(startpoint[0]); endpoint.push("bottom"); break;
        default:     
cancelled true; break;
      }
    }
  }
  else {
    
// no position defined, we accept only vertical and horizontal
    
if (angle == "")
      
angle 270;
    switch (
angle) {
      case 
0:    startpoint= ["left""center"];   endpoint = ["right""center"]; break;
      case 
90:   startpoint= ["center""bottom"]; endpoint = ["center""top"]; break;
      case 
180:  startpoint= ["right""center"];  endpoint = ["left""center"]; break;
      case 
270:  startpoint= ["center""top"];    endpoint = ["center""bottom"]; break;
      default:     
cancelled true; break;
    }
  }

  if (
cancelled)
    return 
"";

  
str += startpoint.join(" ") + ", " endpoint.join(" ");
  if (!
g.value.stops[0].position)
    
g.value.stops[0].position "0%";
  if (!
g.value.stops[g.value.stops.length-1].position)
    
g.value.stops[g.value.stops.length-1].position "100%";
  var 
current 0;
  for (var 
0g.value.stops.length && !cancelledi++) {
    var 
g.value.stops[i];
    if (
s.position) {
      if (
s.position.indexOf("%") == -1) {
        
cancelled true;
        break;
      }
    }
    else {
      var 
1;
      while (
g.value.stops.length && !g.value.stops[j].position)
        
j++;
      var 
inc parseFloat(g.value.stops[j].position) - current;
      for (var 
ijk++) {
        
g.value.stops[k].position = (current inc * (1) / (1)) + "%";
      }
    }
    
current parseFloat(s.position);
    
str += ", color-stop(" + (parseFloat(current) / 100) + ", " s.color ")";
  }

  if (
cancelled)
    return 
"";
  return 
str ")";
}

function 
FilterRadialGradientForOutput(aValueaEngine)
{
  if (
aEngine == "generic")
    return 
aValue.substr(5);

  else if (
aEngine == "webkit")
    return 
aValue.replace( /-moz-/"-webkit-")

  else if (
aEngine != "webkit20110101")
    return 
"";

  var 
CssInspector.parseBackgroundImages(aValue)[0];

  var 
shape = ("shape" in g.value) ? g.value.shape "";
  var 
size  = ("size"  in g.value) ? g.value.size "";
  if (
shape != "circle"
      
|| (size != "farthest-corner" && size != "cover"))
    return 
"";

  if (
g.value.stops.length 2
      
|| !("position" in g.value.stops[0])
      || !
g.value.stops[g.value.stops.length 1].position
      
|| !("position" in g.value.stops[0])
      || !
g.value.stops[g.value.stops.length 1].position)
    return 
"";

  for (var 
0g.value.stops.lengthi++) {
    var 
g.value.stops[i];
    if ((
"position" in s) && s.position && s.position.indexOf("px") == -1)
      return 
"";
  }

  var 
str "-webkit-gradient(radial, ";
  var 
position  = ("position"  in g.value) ? g.value.position "center center";
  
str += position ", " +  parseFloat(g.value.stops[0].position) + ", ";
  
str += position ", " +  parseFloat(g.value.stops[g.value.stops.length 1].position);

  
// at this point we're sure to deal with pixels
  
var current parseFloat(g.value.stops[0].position);
  for (var 
0g.value.stops.lengthi++) {
    var 
g.value.stops[i];
    if (!(
"position" in s) || !s.position) {
      var 
1;
      while (
g.value.stops.length && !g.value.stops[j].position)
        
j++;
      var 
inc parseFloat(g.value.stops[j].position) - current;
      for (var 
ijk++) {
        
g.value.stops[k].position = (current inc * (1) / (1)) + "px";
      }
    }
    
current parseFloat(s.position);
    var 
= (current parseFloat(g.value.stops[0].position)) /
            (
parseFloat(g.value.stops[g.value.stops.length 1].position) - parseFloat(g.value.stops[0].position));
    
str += ", color-stop(" ", " s.color ")";
  }
  
str += ")"
  
return str;
}

function 
FilterRepeatingGradientForOutput(aValueaEngine)
{
  if (
aEngine == "generic")
    return 
aValue.substr(5);

  else if (
aEngine == "webkit")
    return 
aValue.replace( /-moz-/"-webkit-")

  return 
"";
}
?>
Онлайн: 1
Реклама