You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
library_manage_system/WebContent/public/js/cssParser.js

5450 lines
169 KiB

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/* ***** 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_PREFIXES: null,
kEXPORTS_FOR_GECKO: true,
kEXPORTS_FOR_WEBKIT: true,
kEXPORTS_FOR_PRESTO: true,
kEXPORTS_FOR_TRIDENT: true,
cleanPrefixes: function()
{
this.mVENDOR_PREFIXES = null;
},
prefixesForProperty: function(aProperty)
{
if (!this.mVENDOR_PREFIXES) {
this.mVENDOR_PREFIXES = {};
for (var i = 0; i < kCSS_VENDOR_PREFIXES.properties.length; i++) {
var p = kCSS_VENDOR_PREFIXES.properties[i];
if (p.gecko && (p.webkit || p.presto || p.trident)) {
var o = {};
if (this.kEXPORTS_FOR_GECKO) o[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.trident) o[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(parser, token)
{
var color = parser.parseColor(token);
var position = "";
if (!color)
return null;
token = parser.getToken(true, true);
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(true, true);
}
return { color: color, position: position }
},
parseGradient: function (parser, token)
{
var isRadial = false;
var gradient = { isRepeating: false };
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(true, true);
var haveGradientLine = false;
var foundHorizPosition = false;
var haveAngle = false;
if (token.isAngle()) {
gradient.angle = token.value;
haveGradientLine = true;
haveAngle = true;
token = parser.getToken(true, true);
}
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(true, true);
}
if (haveGradientLine) {
if (!haveAngle && token.isAngle()) { // we have an angle here
gradient.angle = token.value;
haveAngle = true;
token = parser.getToken(true, true);
}
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(true, true);
}
if (!haveAngle && token.isAngle()) { // we have an angle here
gradient.angle = token.value;
haveAngle = true;
token = parser.getToken(true, true);
}
// we must find a comma here
if (!token.isSymbol(","))
return null;
token = parser.getToken(true, true);
}
// 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(true, true);
}
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(true, true);
}
if (!("shape" in gradient) &&
(token.isIdent("circle") ||
token.isIdent("ellipse"))) {
// we can still have the second value...
gradient.shape = token.value;
token = parser.getToken(true, true);
}
if ((("shape" in gradient) || ("size" in gradient)) && !token.isSymbol(","))
return null;
else if (("shape" in gradient) || ("size" in gradient))
token = parser.getToken(true, true);
}
// now color stops...
var stop1 = this.parseColorStop(parser, token);
if (!stop1)
return null;
token = parser.currentToken();
if (!token.isSymbol(","))
return null;
token = parser.getToken(true, true);
var stop2 = this.parseColorStop(parser, token);
if (!stop2)
return null;
token = parser.currentToken();
if (token.isSymbol(",")) {
token = parser.getToken(true, true);
}
// ok we have at least two color stops
gradient.stops = [stop1, stop2];
while (!token.isSymbol(")")) {
var colorstop = this.parseColorStop(parser, token);
if (!colorstop)
return null;
token = parser.currentToken();
if (!token.isSymbol(")") && !token.isSymbol(","))
return null;
if (token.isSymbol(","))
token = parser.getToken(true, true);
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(true, true);
var color = "", blurRadius = "0px", offsetX = "0px", offsetY = "0px", spreadRadius = "0px";
var inset = false;
while (token.isNotNull()) {
if (token.isIdent("none")) {
shadows.push( { none: true } );
token = parser.getToken(true, true);
}
else {
if (token.isIdent('inset')) {
inset = true;
token = parser.getToken(true, true);
}
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(true, true);
}
else
return [];
if (!inset && token.isIdent('inset')) {
inset = true;
token = parser.getToken(true, true);
}
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(true, true);
}
else
return [];
if (!inset && token.isIdent('inset')) {
inset = true;
token = parser.getToken(true, true);
}
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(true, true);
}
if (!inset && token.isIdent('inset')) {
inset = true;
token = parser.getToken(true, true);
}
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(true, true);
}
if (!inset && token.isIdent('inset')) {
inset = true;
token = parser.getToken(true, true);
}
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(true, true);
}
if (!inset && token.isIdent('inset')) {
inset = true;
token = parser.getToken(true, true);
}
shadows.push( { none: false,
color: color,
offsetX: offsetX, offsetY: offsetY,
blurRadius: blurRadius,
spreadRadius: spreadRadius } );
if (token.isSymbol(",")) {
inset = false;
color = "";
blurRadius = "0px";
spreadRadius = "0px"
offsetX = "0px";
offsetY = "0px";
token = parser.getToken(true, true);
}
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(true, true);
var color = "", blurRadius = "0px", offsetX = "0px", offsetY = "0px";
while (token.isNotNull()) {
if (token.isIdent("none")) {
shadows.push( { none: true } );
token = parser.getToken(true, true);
}
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(true, true);
}
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(true, true);
}
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(true, true);
}
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(true, true);
}
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(true, true);
}
shadows.push( { none: false,
color: color,
offsetX: offsetX, offsetY: offsetY,
blurRadius: blurRadius } );
if (token.isSymbol(",")) {
color = "";
blurRadius = "0px";
offsetX = "0px";
offsetY = "0px";
token = parser.getToken(true, true);
}
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(true, true);
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(true, true);
var urlContent = parser.parseURL(token);
backgrounds.push( { type: "image", value: "url(" + urlContent });
token = parser.getToken(true, true);
}
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(parser, token);
backgrounds.push( { type: gradient.isRadial ? "radial-gradient" : "linear-gradient", value: gradient });
token = parser.getToken(true, true);
}
else
return null;
if (token.isSymbol(",")) {
token = parser.getToken(true, true);
if (!token.isNotNull())
return null;
}
}
return backgrounds;
},
serializeGradient: function(gradient)
{
var s = 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)
s += (gradient.angle ? gradient.angle + " ": "") +
(gradient.position ? gradient.position : "") +
", ";
if (gradient.isRadial && (gradient.shape || gradient.size))
s += (gradient.shape ? gradient.shape : "") +
" " +
(gradient.size ? gradient.size : "") +
", ";
for (var i = 0; i < gradient.stops.length; i++) {
var colorstop = gradient.stops[i];
s += colorstop.color + (colorstop.position ? " " + colorstop.position : "");
if (i != gradient.stops.length -1)
s += ", ";
}
s += ")";
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(true, true);
if (token.isFunction("url(")) {
token = parser.getToken(true, true);
var urlContent = parser.parseURL(token);
if (urlContent) {
borderImage.url = urlContent.substr(0, urlContent.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(1, borderImage.url.length - 2);
}
else
return null;
}
else
return null;
token = parser.getToken(true, true);
if (token.isNumber() || token.isPercentage())
borderImage.offsets.push(token.value);
else
return null;
var i;
for (i= 0; i < 3; i++) {
token = parser.getToken(true, true);
if (token.isNumber() || token.isPercentage())
borderImage.offsets.push(token.value);
else
break;
}
if (i == 3)
token = parser.getToken(true, true);
if (token.isSymbol("/")) {
token = parser.getToken(true, true);
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 i = 0; i < 3; i++) {
token = parser.getToken(true, true);
if (token.isDimension()
|| token.isNumber("0")
|| (token.isIdent() && token.value in parser.kBORDER_WIDTH_NAMES))
borderImage.widths.push(token.value);
else
break;
}
if (i == 3)
token = parser.getToken(true, true);
}
for (var i = 0; i < 2; i++) {
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(true, true);
}
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 m = {amplifier: "", medium: "", constraints: []};
var token = parser.getToken(true, true);
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(true, true);
}
else if (token.isIdent("not") || token.isIdent("only")) {
m.amplifier = token.value;
token = parser.getToken(true, true);
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(true, true);
}
else
return null;
}
if (m.medium) {
if (!token.isNotNull())
return m;
if (token.isIdent("and")) {
token = parser.getToken(true, true);
}
else
return null;
}
while (token.isSymbol("(")) {
token = parser.getToken(true, true);
if (token.isIdent() && (token.value in kCONSTRAINTS)) {
var constraint = token.value;
token = parser.getToken(true, true);
if (token.isSymbol(":")) {
token = parser.getToken(true, true);
var values = [];
while (!token.isSymbol(")")) {
values.push(token.value);
token = parser.getToken(true, true);
}
if (token.isSymbol(")")) {
m.constraints.push({constraint: constraint, value: values});
token = parser.getToken(true, true);
if (token.isNotNull()) {
if (token.isIdent("and")) {
token = parser.getToken(true, true);
}
else
return null;
}
else
return m;
}
else
return null;
}
else if (token.isSymbol(")")) {
m.constraints.push({constraint: constraint, value: null});
token = parser.getToken(true, true);
if (token.isNotNull()) {
if (token.isIdent("and")) {
token = parser.getToken(true, true);
}
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 : ; < = > ?
XI, XI, XI, XI, XI, XI, XI, XI, XI, XI, 0, 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,SI, SI, SI, SI, SI, SI, SI, SI, SI,
// P Q R S T U V W X Y Z [ \ ] ^ _
SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, 0, 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,SI, SI, SI, SI, SI, SI, SI, SI, SI,
// p q r s t u v w x y z { | } ~
SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, 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,
// ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬ ­ ® ¯
0, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI,
// ° ± ² ³ ´ µ ¶ · ¸ ¹ º » ¼ ½ ¾ ¿
SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI,
// À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï
SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI,
// Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß
SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI,
// à á â ã ä å æ ç è é ê ë ì í î ï
SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI,
// ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ
SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI, SI
],
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(0, this.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(aFirstChar, aSecondChar) {
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 c = this.read();
if (c == -1 || !this.isHexDigit(c))
return new jscsspToken(jscsspToken.NULL_TYPE, null);
var s = c;
c = this.read();
while (c != -1 && this.isHexDigit(c)) {
s += c;
c = this.read();
}
if (c != -1)
this.pushback();
return new jscsspToken(jscsspToken.HEX_TYPE, s);
},
gatherEscape: function() {
var c = this.peek();
if (c == -1)
return "";
if (this.isHexDigit(c)) {
var code = 0;
for (var i = 0; i < 6; i++) {
c = 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 (i == 6) {
c = this.peek();
if (this.isWhiteSpace(c))
this.read();
}
return String.fromCharCode(code);
}
c = this.read();
if (c != "\n")
return c;
return "";
},
gatherIdent: function(c) {
var s = "";
if (c == CSS_ESCAPE)
s += this.gatherEscape();
else
s += c;
c = this.read();
if(!this.mMediaQueryMode){
while (c != -1
&& (this.isIdent(c) || c == CSS_ESCAPE)) {
if (c == CSS_ESCAPE)
s += this.gatherEscape();
else
s += c;
c = this.read();
}
}
else {
while (c != -1
&& c != '{'
&& c != ',') {
s += c;
c = this.read();
}
}
if (c != -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_TYPE, value);
}
return new jscsspToken(jscsspToken.IDENT_TYPE, value);
},
isDigit: function(c) {
return (c >= '0') && (c <= '9');
},
parseComment: function(c) {
var s = c;
while ((c = this.read()) != -1) {
s += c;
if (c == "*") {
c = this.read();
if (c == -1)
break;
if (c == "/") {
s += c;
break;
}
this.pushback();
}
}
return new jscsspToken(jscsspToken.COMMENT_TYPE, s);
},
parseNumber: function(c) {
var s = c;
var foundDot = false;
while ((c = this.read()) != -1) {
if (c == ".") {
if (foundDot)
break;
else {
s += c;
foundDot = true;
}
} else if (this.isDigit(c))
s += c;
else
break;
}
if (c != -1 && this.startsWithIdent(c, this.peek())) { // DIMENSION
var unit = this.gatherIdent(c);
s += unit;
return new jscsspToken(jscsspToken.DIMENSION_TYPE, s, unit);
}
else if (c == "%") {
s += "%";
return new jscsspToken(jscsspToken.PERCENTAGE_TYPE, s);
}
else if (c != -1)
this.pushback();
return new jscsspToken(jscsspToken.NUMBER_TYPE, s);
},
parseString: function(aStop) {
var s = aStop;
var previousChar = aStop;
var c;
while ((c = this.read()) != -1) {
if (c == aStop && previousChar != CSS_ESCAPE) {
s += c;
break;
}
else if (c == CSS_ESCAPE) {
c = this.peek();
if (c == -1)
break;
else if (c == "\n" || c == "\r" || c == "\f") {
d = c;
c = this.read();
// special for Opera that preserves \r\n...
if (d == "\r") {
c = this.peek();
if (c == "\n")
c = this.read();
}
}
else {
s += this.gatherEscape();
c = this.peek();
}
}
else if (c == "\n" || c == "\r" || c == "\f") {
break;
}
else
s += c;
previousChar = c;
}
return new jscsspToken(jscsspToken.STRING_TYPE, s);
},
isWhiteSpace: function(c) {
var code = c.charCodeAt(0);
return code < 256 && (this.kLexTable[code] & IS_WHITESPACE) != 0;
},
eatWhiteSpace: function(c) {
var s = c;
while ((c = this.read()) != -1) {
if (!this.isWhiteSpace(c))
break;
s += c;
}
if (c != -1)
this.pushback();
return s;
},
parseAtKeyword: function(c) {
return new jscsspToken(jscsspToken.ATRULE_TYPE, this.gatherIdent(c));
},
nextToken: function() {
var c = this.read();
if (c == -1)
return new jscsspToken(jscsspToken.NULL_TYPE, null);
if (this.startsWithIdent(c, this.peek()))
return this.parseIdent(c);
if (c == '@') {
var nextChar = this.read();
if (nextChar != -1) {
var followingChar = this.peek();
this.pushback();
if (this.startsWithIdent(nextChar, followingChar))
return this.parseAtKeyword(c);
}
}
if (c == "." || c == "+" || c == "-") {
var nextChar = this.peek();
if (this.isDigit(nextChar))
return this.parseNumber(c);
else if (nextChar == "." && c != ".") {
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 (c == "'" || c == '"')
return this.parseString(c);
if (this.isWhiteSpace(c)) {
var s = this.eatWhiteSpace(c);
return new jscsspToken(jscsspToken.WHITESPACE_TYPE, s);
}
if (c == "|" || c == "~" || c == "^" || c == "$" || c == "*") {
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 (c == "/" && this.peek() == "*")
return this.parseComment(c);
return new jscsspToken(jscsspToken.SYMBOL_TYPE, c);
}
};
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 e = this.mError;
this.mError = null;
return e;
},
currentToken: function() {
return this.mToken;
},
getHexValue: function() {
this.mToken = this.mScanner.nextHexValue();
return this.mToken;
},
getToken: function(aSkipWS, aSkipComment) {
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(aSkipWS, aSkipComment) {
var preservedToken = this.mToken;
this.mScanner.preserveState();
var token = this.getToken(aSkipWS, aSkipComment);
this.mScanner.restoreState();
this.mToken = preservedToken;
return token;
},
ungetToken: function() {
this.mLookAhead = this.mToken;
},
addUnknownAtRule: function(aSheet, aString) {
var currentLine = CountLF(this.mScanner.getAlreadyScanned());
var blocks = [];
var token = this.getToken(false, false);
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(false, false);
}
this.addUnknownRule(aSheet, aString, currentLine);
},
addUnknownRule: function(aSheet, aString, aCurrentLine) {
var errorMsg = this.consumeError();
var rule = new jscsspErrorRule(errorMsg);
rule.currentLine = aCurrentLine;
rule.parsedCssText = aString;
rule.parentStyleSheet = aSheet;
aSheet.cssRules.push(rule);
},
addWhitespace: function(aSheet, aString) {
var rule = new jscsspWhitespace();
rule.parsedCssText = aString;
rule.parentStyleSheet = aSheet;
aSheet.cssRules.push(rule);
},
addComment: function(aSheet, aString) {
var rule = new jscsspComment();
rule.parsedCssText = aString;
rule.parentStyleSheet = aSheet;
aSheet.cssRules.push(rule);
},
parseCharsetRule: function(aToken, aSheet) {
var s = aToken.value;
var token = this.getToken(false, false);
s += token.value;
if (token.isWhiteSpace(" ")) {
token = this.getToken(false, false);
s += token.value;
if (token.isString()) {
var encoding = token.value;
token = this.getToken(false, false);
s += 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(aSheet, s);
return false;
},
parseImportRule: function(aToken, aSheet) {
var currentLine = CountLF(this.mScanner.getAlreadyScanned());
var s = aToken.value;
this.preserveState();
var token = this.getToken(true, true);
var media = [];
var href = "";
if (token.isString()) {
href = token.value;
s += " " + href;
}
else if (token.isFunction("url(")) {
token = this.getToken(true, true);
var urlContent = this.parseURL(token);
if (urlContent) {
href = "url(" + urlContent;
s += " " + href;
}
}
else
this.reportError(kIMPORT_RULE_MISSING_URL);
if (href) {
token = this.getToken(true, true);
while (token.isIdent()) {
s += " " + token.value;
media.push(token.value);
token = this.getToken(true, true);
if (!token)
break;
if (token.isSymbol(",")) {
s += ",";
} else if (token.isSymbol(";")) {
break;
} else
break;
token = this.getToken(true, true);
}
if (!media.length) {
media.push("all");
}
if (token.isSymbol(";")) {
s += ";"
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(token, aSheet) {
var currentLine = CountLF(this.mScanner.getAlreadyScanned());
var s = token.value;
var declarations = [];
var valid = false;
this.preserveState();
token = this.getToken(true, true);
var media = [];
var foundMedia = false;
while (token.isNotNull()) {
if (token.isIdent()) {
foundMedia = true;
s += " " + token.value;
media.push(token.value);
token = this.getToken(true, true);
if (token.isSymbol(",")) {
s += ",";
} 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(true, true);
}
if (token.isSymbol("{")) {
s += " {";
token = this.getToken(true, true);
while (true) {
if (!token.isNotNull()) {
valid = true;
break;
}
if (token.isSymbol("}")) {
s += "}";
valid = true;
break;
} else {
var d = this.parseDeclaration(token, declarations, true, false, aSheet);
s += ((d && declarations.length) ? " " : "") + d;
}
token = this.getToken(true, false);
}
}
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(aToken, aSheet) {
var currentLine = CountLF(this.mScanner.getAlreadyScanned());
var s = aToken.value;
var valid = false;
this.preserveState();
var token = this.getToken(true, true);
if (token.isNotNull()) {
var prefix = "";
var url = "";
if (token.isIdent()) {
prefix = token.value;
s += " " + prefix;
token = this.getToken(true, true);
}
if (token) {
var foundURL = false;
if (token.isString()) {
foundURL = true;
url = token.value;
s += " " + url;
} else if (token.isFunction("url(")) {
// get a url here...
token = this.getToken(true, true);
var urlContent = this.parseURL(token);
if (urlContent) {
url += "url(" + urlContent;
foundURL = true;
s += " " + urlContent;
}
}
}
if (foundURL) {
token = this.getToken(true, true);
if (token.isSymbol(";")) {
s += ";";
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(aToken, aSheet) {
var currentLine = CountLF(this.mScanner.getAlreadyScanned());
var s = aToken.value;
var valid = false;
var descriptors = [];
this.preserveState();
var token = this.getToken(true, true);
if (token.isNotNull()) {
// expecting block start
if (token.isSymbol("{")) {
s += " " + token.value;
var token = this.getToken(true, false);
while (true) {
if (token.isSymbol("}")) {
s += "}";
valid = true;
break;
} else {
var d = this.parseDeclaration(token, descriptors, false, false, aSheet);
s += ((d && descriptors.length) ? " " : "") + d;
}
token = this.getToken(true, false);
}
}
}
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(aToken, aSheet) {
var currentLine = CountLF(this.mScanner.getAlreadyScanned());
var s = aToken.value;
var valid = false;
var declarations = [];
this.preserveState();
var token = this.getToken(true, true);
var pageSelector = "";
if (token.isSymbol(":") || token.isIdent()) {
if (token.isSymbol(":")) {
pageSelector = ":";
token = this.getToken(false, false);
}
if (token.isIdent()) {
pageSelector += token.value;
s += " " + pageSelector;
token = this.getToken(true, true);
}
}
if (token.isNotNull()) {
// expecting block start
if (token.isSymbol("{")) {
s += " " + token.value;
var token = this.getToken(true, false);
while (true) {
if (token.isSymbol("}")) {
s += "}";
valid = true;
break;
} else {
var d = this.parseDeclaration(token, declarations, true, true, aSheet);
s += ((d && declarations.length) ? " " : "") + d;
}
token = this.getToken(true, false);
}
}
}
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(token, aDecl, aAcceptPriority, descriptor, aSheet) {
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_VALUE, aSheet);
values.push(value);
token = this.getToken(true, true);
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(true, true);
if (token.isIdent()) {
var name = token.value;
token = this.getToken(true, true);
if (token.isSymbol(")")) {
var value = new jscsspVariable(kJscsspVARIABLE_VALUE, aSheet);
valueText += "var(" + name + ")";
value.name = name;
values.push(value);
}
else
return "";
}
else
return "";
}
else {
var fn = token.value;
token = this.getToken(false, true);
var arg = this.parseFunctionArgument(token);
if (arg) {
valueText += fn + arg;
var value = new jscsspVariable(kJscsspPRIMITIVE_VALUE, aSheet);
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_VALUE, aSheet);
value.value = color;
values.push(value);
}
else
return "";
}
else if (!token.isWhiteSpace() && !token.isSymbol(",")) {
var value = new jscsspVariable(kJscsspPRIMITIVE_VALUE, aSheet);
value.value = token.value;
values.push(value);
valueText += token.value;
}
else
valueText += token.value;
token = this.getToken(false, true);
}
if (values.length && valueText) {
this.forgetState();
aDecl.push(this._createJscsspDeclarationFromValuesArray(descriptor, values, valueText));
return valueText;
}
return "";
},
parseMarginOrPaddingShorthand: function(token, aDecl, aAcceptPriority, aProperty)
{
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(true, true);
break;
}
else if (token.isDimension()
|| token.isNumber("0")
|| token.isPercentage()
|| token.isIdent("auto")) {
values.push(token.value);
}
else
return "";
token = this.getToken(true, true);
}
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(token, aDecl, aAcceptPriority)
{
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(true, true);
break;
}
else {
var color = this.parseColor(token);
if (color)
values.push(color);
else
return "";
}
token = this.getToken(true, true);
}
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(token, declarations, aAcceptPriority)
{
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(true, true);
var urlContent = this.parseURL(token);
if (urlContent)
values.push("url(" + urlContent);
else
return "";
}
else
return "";
token = this.getToken(true, true);
}
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(token, declarations, aAcceptPriority)
{
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(true, true);
}
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(token, aDecl, aAcceptPriority)
{
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(true, true);
}
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(token, aDecl, aAcceptPriority)
{
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(true, true);
}
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(token, aDecl, aAcceptPriority, aProperty)
{
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(true, true);
}
// create the declarations
this.forgetState();
bWidth = bWidth ? bWidth : "medium";
bStyle = bStyle ? bStyle : "none";
bColor = bColor ? bColor : "-moz-initial";
function addPropertyToDecl(aSelf, aDecl, property, w, s, c) {
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(this, aDecl, "border-top", bWidth, bStyle, bColor);
addPropertyToDecl(this, aDecl, "border-right", bWidth, bStyle, bColor);
addPropertyToDecl(this, aDecl, "border-bottom", bWidth, bStyle, bColor);
addPropertyToDecl(this, aDecl, "border-left", bWidth, bStyle, bColor);
}
else
addPropertyToDecl(this, aDecl, aProperty, bWidth, bStyle, bColor);
return bWidth + " " + bStyle + " " + bColor;
},
parseBackgroundShorthand: function(token, aDecl, aAcceptPriority)
{
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(true, true);
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(true, true);
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(this, token);
if (gradient)
bgImage = CssInspector.serializeGradient(gradient);
else
return "";
}
else {
var color = this.parseColor(token);
if (!bgColor && color)
bgColor = color;
else
return "";
}
}
token = this.getToken(true, true);
}
// 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(token, aDecl, aAcceptPriority)
{
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(true, true);
var urlContent = this.parseURL(token);
if (urlContent) {
lImage = "url(" + urlContent;
}
else
return "";
}
else if (!token.isIdent("none"))
return "";
token = this.getToken(true, true);
}
// 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(token, aDecl, aAcceptPriority)
{
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(false, false);
if (token.isSymbol("/")) {
token = this.getToken(false, false);
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_VALUE, null);
value.value = token.value;
fFamilyValues.push(value);
fFamily += token.value;
break;
}
else if (token.isString() || token.isIdent()) {
var value = new jscsspVariable(kJscsspPRIMITIVE_VALUE, null);
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(true, true);
}
}
else {
return "";
}
}
}
token = this.getToken(true, true);
}
// 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", fFamilyValues, fFamily));
return fStyle + " " + fVariant + " " + fWeight + " " + fSize + "/" + fLineHeight + " " + fFamily;
},
_createJscsspDeclaration: function(property, value)
{
var decl = new jscsspDeclaration();
decl.property = property;
decl.value = this.trim11(value);
decl.parsedCssText = property + ": " + value + ";";
return decl;
},
_createJscsspDeclarationFromValue: function(property, valueText)
{
var decl = new jscsspDeclaration();
decl.property = property;
var value = new jscsspVariable(kJscsspPRIMITIVE_VALUE, null);
value.value = valueText;
decl.values = [value];
decl.valueText = valueText;
decl.parsedCssText = property + ": " + valueText + ";";
return decl;
},
_createJscsspDeclarationFromValuesArray: function(property, values, valueText)
{
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(true, true);
}
else
while (true)
{
if (!token.isNotNull()) {
this.reportError(kURL_EOF);
return "";
}
if (token.isWhiteSpace()) {
nextToken = this.lookAhead(true, true);
// 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(false, false);
}
if (token.isSymbol(")")) {
return value + ")";
}
return "";
},
parseFunctionArgument: function(token)
{
var value = "";
if (token.isString())
{
value += token.value;
token = this.getToken(true, true);
}
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(false, false);
}
}
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(true, true);
if (!token.isNumber() && !token.isPercentage())
return "";
color += token.value;
token = this.getToken(true, true);
if (!token.isSymbol(","))
return "";
color += ", ";
token = this.getToken(true, true);
if (!token.isNumber() && !token.isPercentage())
return "";
color += token.value;
token = this.getToken(true, true);
if (!token.isSymbol(","))
return "";
color += ", ";
token = this.getToken(true, true);
if (!token.isNumber() && !token.isPercentage())
return "";
color += token.value;
if (isRgba) {
token = this.getToken(true, true);
if (!token.isSymbol(","))
return "";
color += ", ";
token = this.getToken(true, true);
if (!token.isNumber())
return "";
color += token.value;
}
token = this.getToken(true, true);
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(true, true);
if (!token.isNumber())
return "";
color += token.value;
token = this.getToken(true, true);
if (!token.isSymbol(","))
return "";
color += ", ";
token = this.getToken(true, true);
if (!token.isPercentage())
return "";
color += token.value;
token = this.getToken(true, true);
if (!token.isSymbol(","))
return "";
color += ", ";
token = this.getToken(true, true);
if (!token.isPercentage())
return "";
color += token.value;
if (isHsla) {
token = this.getToken(true, true);
if (!token.isSymbol(","))
return "";
color += ", ";
token = this.getToken(true, true);
if (!token.isNumber())
return "";
color += token.value;
}
token = this.getToken(true, true);
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 != 3 && length != 6)
return "";
if (token.value.match( /[a-fA-F0-9]/g ).length != length)
return "";
color = "#" + token.value;
}
return color;
},
parseDeclaration: function(aToken, aDecl, aAcceptPriority, aExpandShorthands, aSheet) {
this.preserveState();
var blocks = [];
if (aToken.isIdent()) {
var descriptor = aToken.value.toLowerCase();
var token = this.getToken(true, true);
if (token.isSymbol(":")) {
var token = this.getToken(true, true);
var value = "";
var declarations = [];
if (aExpandShorthands)
switch (descriptor) {
case "background":
value = this.parseBackgroundShorthand(token, declarations, aAcceptPriority);
break;
case "margin":
case "padding":
value = this.parseMarginOrPaddingShorthand(token, declarations, aAcceptPriority, descriptor);
break;
case "border-color":
value = this.parseBorderColorShorthand(token, declarations, aAcceptPriority);
break;
case "border-style":
value = this.parseBorderStyleShorthand(token, declarations, aAcceptPriority);
break;
case "border-width":
value = this.parseBorderWidthShorthand(token, declarations, aAcceptPriority);
break;
case "border-top":
case "border-right":
case "border-bottom":
case "border-left":
case "border":
case "outline":
value = this.parseBorderEdgeOrOutlineShorthand(token, declarations, aAcceptPriority, descriptor);
break;
case "cue":
value = this.parseCueShorthand(token, declarations, aAcceptPriority);
break;
case "pause":
value = this.parsePauseShorthand(token, declarations, aAcceptPriority);
break;
case "font":
value = this.parseFontShorthand(token, declarations, aAcceptPriority);
break;
case "list-style":
value = this.parseListStyleShorthand(token, declarations, aAcceptPriority);
break;
default:
value = this.parseDefaultPropertyValue(token, declarations, aAcceptPriority, descriptor, aSheet);
break;
}
else
value = this.parseDefaultPropertyValue(token, declarations, aAcceptPriority, descriptor, aSheet);
token = this.currentToken();
if (value) // no error above
{
var priority = false;
if (token.isSymbol("!")) {
token = this.getToken(true, true);
if (token.isIdent("important")) {
priority = true;
token = this.getToken(true, true);
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 i = 0; i < declarations.length; i++) {
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 s = aToken.value;
blocks = [];
var token = this.getToken(false, false);
while (token.isNotNull()) {
s += 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(false, false);
}
return "";
},
parseKeyframesRule: function(aToken, aSheet) {
var currentLine = CountLF(this.mScanner.getAlreadyScanned());
var s = aToken.value;
var valid = false;
var keyframesRule = new jscsspKeyframesRule();
keyframesRule.currentLine = currentLine;
this.preserveState();
var token = this.getToken(true, true);
var foundName = false;
while (token.isNotNull()) {
if (token.isIdent()) {
// should be the keyframes' name
foundName = true;
s += " " + token.value;
keyframesRule.name = token.value;
token = this.getToken(true, true);
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(true, true);
}
if (token.isSymbol("{") && keyframesRule.name) {
// ok let's parse keyframe rules now...
s += " { ";
token = this.getToken(true, false);
while (token.isNotNull()) {
if (token.isComment() && this.mPreserveComments) {
s += " " + token.value;
var comment = new jscsspComment();
comment.parsedCssText = token.value;
keyframesRule.cssRules.push(comment);
} else if (token.isSymbol("}")) {
valid = true;
break;
} else {
var r = this.parseKeyframeRule(token, keyframesRule, true);
if (r)
s += r;
}
token = this.getToken(true, false);
}
}
if (valid) {
this.forgetState();
keyframesRule.currentLine = currentLine;
keyframesRule.parsedCssText = s;
aSheet.cssRules.push(keyframesRule);
return true;
}
this.restoreState();
return false;
},
parseKeyframeRule: function(aToken, aOwner) {
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(true, true);
if (token.isSymbol("{")) {
this.ungetToken();
break;
}
else
if (token.isSymbol(",")) {
key += ", ";
}
else {
key = "";
break;
}
}
else {
key = "";
break;
}
token = this.getToken(true, true);
}
var valid = false;
var declarations = [];
if (key) {
var s = key;
token = this.getToken(true, true);
if (token.isSymbol("{")) {
s += " { ";
token = this.getToken(true, false);
while (true) {
if (!token.isNotNull()) {
valid = true;
break;
}
if (token.isSymbol("}")) {
s += "}";
valid = true;
break;
} else {
var d = this.parseDeclaration(token, declarations, true, true, aOwner);
s += ((d && declarations.length) ? " " : "") + d;
}
token = this.getToken(true, false);
}
}
}
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();
s = this.currentToken().value;
this.addUnknownAtRule(aOwner, s);
return "";
},
parseMediaRule: function(aToken, aSheet) {
this.mScanner.mMediaQueryMode = true;
var currentLine = CountLF(this.mScanner.getAlreadyScanned());
var s = aToken.value;
var valid = false;
var mediaRule = new jscsspMediaRule();
mediaRule.currentLine = currentLine;
this.preserveState();
var token = this.getToken(true, true);
var foundMedia = false;
while (token.isNotNull()) {
if (token.isIdent()) {
foundMedia = true;
s += " " + token.value;
mediaRule.media.push(token.value);
token = this.getToken(true, true);
if (token.isSymbol(",")) {
s += ",";
} 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(true, true);
}
if (token.isSymbol("{") && mediaRule.media.length) {
// ok let's parse style rules now...
s += " { ";
token = this.getToken(true, false);
while (token.isNotNull()) {
if (token.isComment() && this.mPreserveComments) {
s += " " + token.value;
var comment = new jscsspComment();
comment.parsedCssText = token.value;
mediaRule.cssRules.push(comment);
} else if (token.isSymbol("}")) {
valid = true;
break;
} else {
var r = this.parseStyleRule(token, mediaRule, true);
if (r)
s += r;
}
token = this.getToken(true, false);
}
}
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 i = str.length - 1; i >= 0; i--) {
if (/\S/.test( str.charAt(i) )) { // XXX charat
str = str.substring(0, i + 1);
break;
}
}
return str;
},
parseStyleRule: function(aToken, aOwner, aIsInsideMediaRule)
{
var currentLine = CountLF(this.mScanner.getAlreadyScanned());
this.preserveState();
// first let's see if we have a selector here...
var selector = this.parseSelector(aToken, false);
var valid = false;
var declarations = [];
if (selector) {
selector = this.trim11(selector.selector);
var s = selector;
var token = this.getToken(true, true);
if (token.isSymbol("{")) {
s += " { ";
var token = this.getToken(true, false);
while (true) {
if (!token.isNotNull()) {
valid = true;
break;
}
if (token.isSymbol("}")) {
s += "}";
valid = true;
break;
} else {
var d = this.parseDeclaration(token, declarations, true, true, aOwner);
s += ((d && declarations.length) ? " " : "") + d;
}
token = this.getToken(true, false);
}
}
}
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();
s = this.currentToken().value;
this.addUnknownAtRule(aOwner, s);
return "";
},
parseSelector: function(aToken, aParseSelectorOnly) {
var s = "";
var specificity = {a: 0, b: 0, c: 0, d: 0}; // 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 {selector: s, specificity: specificity };
return "";
}
if (!aParseSelectorOnly && token.isSymbol("{")) {
// end of selector
valid = !combinatorFound;
if (valid) this.ungetToken();
break;
}
if (token.isSymbol(",")) { // group of selectors
s += token.value;
isFirstInChain = true;
combinatorFound = false;
token = this.getToken(false, true);
continue;
}
// now combinators and grouping...
else if (!combinatorFound
&& (token.isWhiteSpace()
|| token.isSymbol(">")
|| token.isSymbol("+")
|| token.isSymbol("~"))) {
if (token.isWhiteSpace()) {
s += " ";
var nextToken = this.lookAhead(true, true);
if (!nextToken.isNotNull()) {
if (aParseSelectorOnly)
return {selector: s, specificity: specificity };
return "";
}
if (nextToken.isSymbol(">")
|| nextToken.isSymbol("+")
|| nextToken.isSymbol("~")) {
token = this.getToken(true, true);
s += token.value + " ";
combinatorFound = true;
}
}
else {
s += token.value;
combinatorFound = true;
}
isFirstInChain = true;
token = this.getToken(true, true);
continue;
}
else {
var simpleSelector = this.parseSimpleSelector(token, isFirstInChain, true);
if (!simpleSelector)
break; // error
s += simpleSelector.selector;
specificity.b += simpleSelector.specificity.b;
specificity.c += simpleSelector.specificity.c;
specificity.d += simpleSelector.specificity.d;
isFirstInChain = false;
combinatorFound = false;
}
token = this.getToken(false, true);
}
if (valid) {
return {selector: s, specificity: specificity };
}
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(token, isFirstInChain, canNegate)
{
var s = "";
var specificity = {a: 0, b: 0, c: 0, d: 0}; // 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
s += token.value;
var isIdent = token.isIdent();
token = this.getToken(false, true);
if (token.isSymbol("|")) {
// it's a prefix
s += token.value;
token = this.getToken(false, true);
if (token.isIdent() || token.isSymbol("*")) {
// ok we now have a type element or universal
// selector
s += 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("|")) {
s += token.value;
token = this.getToken(false, true);
if (token.isIdent() || token.isSymbol("*")) {
s += 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(".");
s += token.value;
token = this.getToken(false, true);
if (token.isIdent()) {
s += token.value;
if (isClass)
specificity.c++;
else
specificity.b++;
}
else
return null;
}
else if (token.isSymbol(":")) {
s += token.value;
token = this.getToken(false, true);
if (token.isSymbol(":")) {
s += token.value;
token = this.getToken(false, true);
}
if (token.isIdent()) {
s += token.value;
if (this.isPseudoElement(token.value))
specificity.d++;
else
specificity.c++;
}
else if (token.isFunction()) {
s += token.value;
if (token.isFunction(":not(")) {
if (!canNegate)
return null;
token = this.getToken(true, true);
var simpleSelector = this.parseSimpleSelector(token, isFirstInChain, false);
if (!simpleSelector)
return null;
else {
s += simpleSelector.selector;
token = this.getToken(true, true);
if (token.isSymbol(")"))
s += ")";
else
return null;
}
specificity.c++;
}
else {
while (true) {
token = this.getToken(false, true);
if (token.isSymbol(")")) {
s += ")";
break;
} else
s += token.value;
}
specificity.c++;
}
} else
return null;
} else if (token.isSymbol("[")) {
s += "[";
token = this.getToken(true, true);
if (token.isIdent() || token.isSymbol("*")) {
s += token.value;
var nextToken = this.getToken(true, true);
if (token.isSymbol("|")) {
s += "|";
token = this.getToken(true, true);
if (token.isIdent())
s += token.value;
else
return null;
} else
this.ungetToken();
} else if (token.isSymbol("|")) {
s += "|";
token = this.getToken(true, true);
if (token.isIdent())
s += token.value;
else
return null;
}
else
return null;
// nothing, =, *=, $=, ^=, |=
token = this.getToken(true, true);
if (token.isIncludes()
|| token.isDashmatch()
|| token.isBeginsmatch()
|| token.isEndsmatch()
|| token.isContainsmatch()
|| token.isSymbol("=")) {
s += token.value;
token = this.getToken(true, true);
if (token.isString() || token.isIdent()) {
s += token.value;
token = this.getToken(true, true);
}
else
return null;
if (token.isSymbol("]")) {
s += token.value;
specificity.c++;
}
else
return null;
}
else if (token.isSymbol("]")) {
s += token.value;
specificity.c++;
}
else
return null;
}
else if (token.isWhiteSpace()) {
var t = this.lookAhead(true, true);
if (t.isSymbol('{'))
return ""
}
if (s)
return {selector: s, specificity: specificity };
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(aString, aTryToPreserveWhitespaces, aTryToPreserveComments) {
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(false, false);
if (!token.isNotNull())
return;
if (token.isAtRule("@charset")) {
this.parseCharsetRule(token, sheet);
token = this.getToken(false, false);
}
var foundStyleRules = false;
var foundImportRules = false;
var foundNameSpaceRules = false;
while (true) {
if (!token.isNotNull())
break;
if (token.isWhiteSpace())
{
if (aTryToPreserveWhitespaces)
this.addWhitespace(sheet, token.value);
}
else if (token.isComment())
{
if (this.mPreserveComments)
this.addComment(sheet, token.value);
}
else if (token.isAtRule()) {
if (token.isAtRule("@variables")) {
if (!foundImportRules && !foundStyleRules)
this.parseVariablesRule(token, sheet);
else {
this.reportError(kVARIABLES_RULE_POSITION);
this.addUnknownAtRule(sheet, token.value);
}
}
else if (token.isAtRule("@import")) {
// @import rules MUST occur before all style and namespace
// rules
if (!foundStyleRules && !foundNameSpaceRules)
foundImportRules = this.parseImportRule(token, sheet);
else {
this.reportError(kIMPORT_RULE_POSITION);
this.addUnknownAtRule(sheet, token.value);
}
}
else if (token.isAtRule("@namespace")) {
// @namespace rules MUST occur before all style rule and
// after all @import rules
if (!foundStyleRules)
foundNameSpaceRules = this.parseNamespaceRule(token, sheet);
else {
this.reportError(kNAMESPACE_RULE_POSITION);
this.addUnknownAtRule(sheet, token.value);
}
}
else if (token.isAtRule("@font-face")) {
if (this.parseFontFaceRule(token, sheet))
foundStyleRules = true;
else
this.addUnknownAtRule(sheet, token.value);
}
else if (token.isAtRule("@page")) {
if (this.parsePageRule(token, sheet))
foundStyleRules = true;
else
this.addUnknownAtRule(sheet, token.value);
}
else if (token.isAtRule("@media")) {
if (this.parseMediaRule(token, sheet))
foundStyleRules = true;
else
this.addUnknownAtRule(sheet, token.value);
}
else if (token.isAtRule("@keyframes")) {
if (!this.parseKeyframesRule(token, sheet))
this.addUnknownAtRule(sheet, token.value);
}
else if (token.isAtRule("@charset")) {
this.reportError(kCHARSET_RULE_CHARSET_SOF);
this.addUnknownAtRule(sheet, token.value);
}
else {
this.reportError(kUNKNOWN_AT_RULE);
this.addUnknownAtRule(sheet, token.value);
}
}
else // plain style rules
{
var ruleText = this.parseStyleRule(token, sheet, false);
if (ruleText)
foundStyleRules = true;
}
token = this.getToken(false);
}
return sheet;
}
};
function jscsspToken(aType, aValue, aUnit)
{
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 (aType, aValue)
{
return (this.type == aType && (!aValue || this.value.toLowerCase() == aValue));
},
isWhiteSpace: function(w)
{
return this._isOfType(jscsspToken.WHITESPACE_TYPE, w);
},
isString: function()
{
return this._isOfType(jscsspToken.STRING_TYPE);
},
isComment: function()
{
return this._isOfType(jscsspToken.COMMENT_TYPE);
},
isNumber: function(n)
{
return this._isOfType(jscsspToken.NUMBER_TYPE, n);
},
isSymbol: function(c)
{
return this._isOfType(jscsspToken.SYMBOL_TYPE, c);
},
isIdent: function(i)
{
return this._isOfType(jscsspToken.IDENT_TYPE, i);
},
isFunction: function(f)
{
return this._isOfType(jscsspToken.FUNCTION_TYPE, f);
},
isAtRule: function(a)
{
return this._isOfType(jscsspToken.ATRULE_TYPE, a);
},
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_TYPE, c);
},
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(aRule, aIndex) {
try {
this.cssRules.splice(aIndex, 1, aRule);
}
catch(e) {
}
},
deleteRule: function(aIndex) {
try {
this.cssRules.splice(aIndex);
}
catch(e) {
}
},
cssText: function() {
var rv = "";
for (var i = 0; i < this.cssRules.length; i++)
rv += this.cssRules[i].cssText() + "\n";
return rv;
},
resolveVariables: function(aMedium) {
function ItemFoundInArray(aArray, aItem) {
for (var i = 0; i < aArray.length; i++)
if (aItem == aArray[i])
return true;
return false;
}
for (var i = 0; i < this.cssRules.length; i++)
{
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.media, aMedium))) {
for (var j = 0; j < rule.declarations.length; j++) {
var valueText = "";
for (var k = 0; k < rule.declarations[j].values.length; k++)
valueText += (k ? " " : "") + 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(false, false);
if (token.isAtRule("@charset")) {
if (parser.parseCharsetRule(token, sheet)) {
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(true, false);
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(true, true);
if (token.isAtRule("@import")) {
if (parser.parseImportRule(token, sheet)) {
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(true, true);
if (token.isAtRule("@namespace")) {
if (parser.parseNamespaceRule(token, sheet)) {
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 = 0; propertyIndex < prefixes.length; propertyIndex++) {
var property = prefixes[propertyIndex];
rv += (propertyIndex ? gTABS : "") + property + ": ";
rv += this.valueText + (this.priority ? " !important" : "") + ";";
rv += ((prefixes.length > 1 && propertyIndex != prefixes.length -1) ? "\n" : "");
}
return rv;
}
return this.property + ": " + this.valueText +
(this.priority ? " !important" : "") + ";"
}
if (prefixes) {
var rv = "";
for (var propertyIndex = 0; propertyIndex < prefixes.length; propertyIndex++) {
var property = prefixes[propertyIndex];
rv += (propertyIndex ? gTABS : "") + property + ": ";
var separator = (property in this.kCOMMA_SEPARATED) ? ", " : " ";
for (var i = 0; i < this.values.length; i++)
if (this.values[i].cssText() != null)
rv += (i ? separator : "") + this.values[i].cssText();
else
return null;
rv += (this.priority ? " !important" : "") + ";" +
((prefixes.length > 1 && 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 i = 0; i < this.values.length; i++) {
var v = this.values[i].cssText();
if (v != null) {
var paren = v.indexOf("(");
var kwd = v;
if (paren != -1)
kwd = v.substr(0, paren);
if (kwd in kCSS_VENDOR_VALUES) {
for (var j in kCSS_VENDOR_VALUES[kwd]) {
extras[j] = extras[j] || (kCSS_VENDOR_VALUES[kwd][j] != "");
}
}
rv += (i ? 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 i = 0; i < this.values.length; i++) {
var v = this.values[i].cssText();
if (v != null) {
var paren = v.indexOf("(");
var kwd = v;
if (paren != -1)
kwd = v.substr(0, paren);
if (kwd in kCSS_VENDOR_VALUES) {
functor = kCSS_VENDOR_VALUES[kwd][j];
if (functor) {
v = (typeof functor == "string") ? functor : functor(v, j);
if (!v) {
str = null;
break;
}
}
}
str += (i ? separator : "") + v;
}
else
return null;
}
if (str)
rv += str + ";"
else
rv += "\n" + gTABS + "/* Impossible to translate property " + this.property + " for " + j + " */";
}
}
return rv;
},
setCssText: function(val) {
var declarations = [];
var parser = new CSSParser(val);
var token = parser.getToken(true, true);
if (parser.parseDeclaration(token, declarations, true, true, null)
&& 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 i = 0; i < this.descriptors.length; i++)
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(true, true);
if (token.isAtRule("@font-face")) {
if (parser.parseFontFaceRule(token, sheet)) {
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 i = 0; i < this.cssRules.length; i++)
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(true, true);
if (token.isAtRule("@keyframes")) {
if (parser.parseKeyframesRule(token, sheet)) {
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 i = 0; i < this.declarations.length; i++) {
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(true, true);
if (!token.isNotNull()) {
if (parser.parseKeyframeRule(token, sheet, false)) {
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 i = 0; i < this.cssRules.length; i++)
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(true, true);
if (token.isAtRule("@media")) {
if (parser.parseMediaRule(token, sheet)) {
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 i = 0; i < this.declarations.length; i++) {
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(true, true);
if (!token.isNotNull()) {
if (parser.parseStyleRule(token, sheet, false)) {
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(true, true);
if (!token.isNotNull()) {
var s = parser.parseSelector(token, true);
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 i = 0; i < this.declarations.length; i++)
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(true, true);
if (token.isAtRule("@page")) {
if (parser.parsePageRule(token, sheet)) {
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 i = 0; i < this.declarations.length; i++)
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(true, true);
if (token.isAtRule("@variables")) {
if (parser.parseVariablesRule(token, sheet)) {
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(aType, aSheet)
{
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.name, this.parentRule, this.parentStyleSheet);
else
return this.value;
},
setCssText: function(val) {
if (this.type == kJscsspVARIABLE_VALUE)
throw DOMException.SYNTAX_ERR;
else
this.value = val;
},
resolveVariable: function(aName, aRule, aSheet)
{
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/g );
return nCR ? nCR.length + 1 : 1;
}
function FilterLinearGradientForOutput(aValue, aEngine)
{
if (aEngine == "generic")
return aValue.substr(5);
if (aEngine == "webkit")
return aValue.replace( /\-moz\-/g , "-webkit-")
if (aEngine != "webkit20110101")
return "";
var g = 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 i = 0; i < g.value.stops.length && !cancelled; i++) {
var s = g.value.stops[i];
if (s.position) {
if (s.position.indexOf("%") == -1) {
cancelled = true;
break;
}
}
else {
var j = i + 1;
while (j < g.value.stops.length && !g.value.stops[j].position)
j++;
var inc = parseFloat(g.value.stops[j].position) - current;
for (var k = i; k < j; k++) {
g.value.stops[k].position = (current + inc * (k - i + 1) / (j - i + 1)) + "%";
}
}
current = parseFloat(s.position);
str += ", color-stop(" + (parseFloat(current) / 100) + ", " + s.color + ")";
}
if (cancelled)
return "";
return str + ")";
}
function FilterRadialGradientForOutput(aValue, aEngine)
{
if (aEngine == "generic")
return aValue.substr(5);
else if (aEngine == "webkit")
return aValue.replace( /\-moz\-/g , "-webkit-")
else if (aEngine != "webkit20110101")
return "";
var g = 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 i = 0; i < g.value.stops.length; i++) {
var s = 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 i = 0; i < g.value.stops.length; i++) {
var s = g.value.stops[i];
if (!("position" in s) || !s.position) {
var j = i + 1;
while (j < g.value.stops.length && !g.value.stops[j].position)
j++;
var inc = parseFloat(g.value.stops[j].position) - current;
for (var k = i; k < j; k++) {
g.value.stops[k].position = (current + inc * (k - i + 1) / (j - i + 1)) + "px";
}
}
current = parseFloat(s.position);
var c = (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(" + c + ", " + s.color + ")";
}
str += ")"
return str;
}
function FilterRepeatingGradientForOutput(aValue, aEngine)
{
if (aEngine == "generic")
return aValue.substr(5);
else if (aEngine == "webkit")
return aValue.replace( /\-moz\-/g , "-webkit-")
return "";
}