UNPKG

@openui5/sap.ui.core

Version:

OpenUI5 Core Library sap.ui.core

1,437 lines (1,397 loc) 123 kB
(function() { /* Copyright Google Inc. * Licensed under the Apache Licence Version 2.0 * Autogenerated at Tue May 22 10:18:21 PDT 2012 * \@overrides window * \@provides cssSchema, CSS_PROP_BIT_QUANTITY, CSS_PROP_BIT_HASH_VALUE, CSS_PROP_BIT_NEGATIVE_QUANTITY, CSS_PROP_BIT_QSTRING_CONTENT, CSS_PROP_BIT_QSTRING_URL, CSS_PROP_BIT_HISTORY_INSENSITIVE, CSS_PROP_BIT_Z_INDEX, CSS_PROP_BIT_ALLOWED_IN_LINK */ /** * @const * @type {number} */ var CSS_PROP_BIT_QUANTITY = 1; /** * @const * @type {number} */ var CSS_PROP_BIT_HASH_VALUE = 2; /** * @const * @type {number} */ var CSS_PROP_BIT_NEGATIVE_QUANTITY = 4; /** * @const * @type {number} */ var CSS_PROP_BIT_QSTRING_CONTENT = 8; /** * @const * @type {number} */ var CSS_PROP_BIT_QSTRING_URL = 16; /** * @const * @type {number} */ var CSS_PROP_BIT_HISTORY_INSENSITIVE = 32; /** * @const * @type {number} */ var CSS_PROP_BIT_Z_INDEX = 64; /** * @const * @type {number} */ var CSS_PROP_BIT_ALLOWED_IN_LINK = 128; var cssSchema = (function () { var s = [ 'rgb(?:\\(\\s*(?:\\d+|0|\\d+(?:\\.\\d+)?%)\\s*,\\s*(?:\\d+|0|\\d+(?:\\.\\d+)?%)\\s*,\\s*(?:\\d+|0|\\d+(?:\\.\\d+)?%)|a\\(\\s*(?:\\d+|0|\\d+(?:\\.\\d+)?%)\\s*,\\s*(?:\\d+|0|\\d+(?:\\.\\d+)?%)\\s*,\\s*(?:\\d+|0|\\d+(?:\\.\\d+)?%)\\s*,\\s*(?:\\d+|0(?:\\.\\d+)?|\\.\\d+|1(?:\\.0+)?|0|\\d+(?:\\.\\d+)?%)) *\\)' ], c = [ /^ *$/i, RegExp('^ *(?:\\s*' + s[ 0 ] + '|(?:\\s*' + s[ 0 ] + ')?)+ *$', 'i'), RegExp('^ *\\s*' + s[ 0 ] + ' *$', 'i'), RegExp('^ *\\s*' + s[ 0 ] + '\\s*' + s[ 0 ] + ' *$', 'i') ], L = [ [ 'aliceblue', 'antiquewhite', 'aqua', 'aquamarine', 'azure', 'beige', 'bisque', 'black', 'blanchedalmond', 'blue', 'blueviolet', 'brown', 'burlywood', 'cadetblue', 'chartreuse', 'chocolate', 'coral', 'cornflowerblue', 'cornsilk', 'crimson', 'cyan', 'darkblue', 'darkcyan', 'darkgoldenrod', 'darkgray', 'darkgreen', 'darkkhaki', 'darkmagenta', 'darkolivegreen', 'darkorange', 'darkorchid', 'darkred', 'darksalmon', 'darkseagreen', 'darkslateblue', 'darkslategray', 'darkturquoise', 'darkviolet', 'deeppink', 'deepskyblue', 'dimgray', 'dodgerblue', 'firebrick', 'floralwhite', 'forestgreen', 'fuchsia', 'gainsboro', 'ghostwhite', 'gold', 'goldenrod', 'gray', 'green', 'greenyellow', 'honeydew', 'hotpink', 'indianred', 'indigo', 'ivory', 'khaki', 'lavender', 'lavenderblush', 'lawngreen', 'lemonchiffon', 'lightblue', 'lightcoral', 'lightcyan', 'lightgoldenrodyellow', 'lightgreen', 'lightgrey', 'lightpink', 'lightsalmon', 'lightseagreen', 'lightskyblue', 'lightslategray', 'lightsteelblue', 'lightyellow', 'lime', 'limegreen', 'linen', 'magenta', 'maroon', 'mediumaquamarine', 'mediumblue', 'mediumorchid', 'mediumpurple', 'mediumseagreen', 'mediumslateblue', 'mediumspringgreen', 'mediumturquoise', 'mediumvioletred', 'midnightblue', 'mintcream', 'mistyrose', 'moccasin', 'navajowhite', 'navy', 'oldlace', 'olive', 'olivedrab', 'orange', 'orangered', 'orchid', 'palegoldenrod', 'palegreen', 'paleturquoise', 'palevioletred', 'papayawhip', 'peachpuff', 'peru', 'pink', 'plum', 'powderblue', 'purple', 'red', 'rosybrown', 'royalblue', 'saddlebrown', 'salmon', 'sandybrown', 'seagreen', 'seashell', 'sienna', 'silver', 'skyblue', 'slateblue', 'slategray', 'snow', 'springgreen', 'steelblue', 'tan', 'teal', 'thistle', 'tomato', 'turquoise', 'violet', 'wheat', 'white', 'whitesmoke', 'yellow', 'yellowgreen' ], [ 'all-scroll', 'col-resize', 'crosshair', 'default', 'e-resize', 'hand', 'help', 'move', 'n-resize', 'ne-resize', 'no-drop', 'not-allowed', 'nw-resize', 'pointer', 'progress', 'row-resize', 's-resize', 'se-resize', 'sw-resize', 'text', 'vertical-text', 'w-resize', 'wait' ], [ '-moz-inline-box', '-moz-inline-stack', 'block', 'inline', 'inline-block', 'inline-table', 'list-item', 'run-in', 'table', 'table-caption', 'table-cell', 'table-column', 'table-column-group', 'table-footer-group', 'table-header-group', 'table-row', 'table-row-group' ], [ 'armenian', 'circle', 'decimal', 'decimal-leading-zero', 'disc', 'georgian', 'lower-alpha', 'lower-greek', 'lower-latin', 'lower-roman', 'square', 'upper-alpha', 'upper-latin', 'upper-roman' ], [ '100', '200', '300', '400', '500', '600', '700', '800', '900', 'bold', 'bolder', 'lighter' ], [ 'condensed', 'expanded', 'extra-condensed', 'extra-expanded', 'narrower', 'semi-condensed', 'semi-expanded', 'ultra-condensed', 'ultra-expanded', 'wider' ], [ 'behind', 'center-left', 'center-right', 'far-left', 'far-right', 'left-side', 'leftwards', 'right-side', 'rightwards' ], [ 'large', 'larger', 'small', 'smaller', 'x-large', 'x-small', 'xx-large', 'xx-small' ], [ '-moz-pre-wrap', '-o-pre-wrap', '-pre-wrap', 'nowrap', 'pre', 'pre-line', 'pre-wrap' ], [ 'dashed', 'dotted', 'double', 'groove', 'outset', 'ridge', 'solid' ], [ 'baseline', 'middle', 'sub', 'super', 'text-bottom', 'text-top' ], [ 'caption', 'icon', 'menu', 'message-box', 'small-caption', 'status-bar' ], [ 'fast', 'faster', 'slow', 'slower', 'x-fast', 'x-slow' ], [ 'above', 'below', 'higher', 'level', 'lower' ], [ 'border-box', 'contain', 'content-box', 'cover', 'padding-box' ], [ 'cursive', 'fantasy', 'monospace', 'sans-serif', 'serif' ], [ 'loud', 'silent', 'soft', 'x-loud', 'x-soft' ], [ 'no-repeat', 'repeat-x', 'repeat-y', 'round', 'space' ], [ 'blink', 'line-through', 'overline', 'underline' ], [ 'high', 'low', 'x-high', 'x-low' ], [ 'absolute', 'relative', 'static' ], [ 'capitalize', 'lowercase', 'uppercase' ], [ 'child', 'female', 'male' ], [ 'bidi-override', 'embed' ], [ 'bottom', 'top' ], [ 'clip', 'ellipsis' ], [ 'continuous', 'digits' ], [ 'hide', 'show' ], [ 'inside', 'outside' ], [ 'italic', 'oblique' ], [ 'left', 'right' ], [ 'ltr', 'rtl' ], [ 'no-content', 'no-display' ], [ 'suppress', 'unrestricted' ], [ 'thick', 'thin' ], [ ',' ], [ '/' ], [ 'always' ], [ 'auto' ], [ 'avoid' ], [ 'both' ], [ 'break-word' ], [ 'center' ], [ 'code' ], [ 'collapse' ], [ 'fixed' ], [ 'hidden' ], [ 'inherit' ], [ 'inset' ], [ 'invert' ], [ 'justify' ], [ 'local' ], [ 'medium' ], [ 'mix' ], [ 'none' ], [ 'normal' ], [ 'once' ], [ 'repeat' ], [ 'scroll' ], [ 'separate' ], [ 'small-caps' ], [ 'spell-out' ], [ 'transparent' ], [ 'visible' ] ]; return { '-moz-border-radius': { 'cssExtra': c[ 0 ], 'cssPropBits': 5, 'cssLitGroup': [ L[ 36 ] ] }, '-moz-border-radius-bottomleft': { 'cssExtra': c[ 0 ], 'cssPropBits': 5 }, '-moz-border-radius-bottomright': { 'cssExtra': c[ 0 ], 'cssPropBits': 5 }, '-moz-border-radius-topleft': { 'cssExtra': c[ 0 ], 'cssPropBits': 5 }, '-moz-border-radius-topright': { 'cssExtra': c[ 0 ], 'cssPropBits': 5 }, '-moz-box-shadow': { 'cssExtra': c[ 1 ], 'cssAlternates': [ 'boxShadow' ], 'cssPropBits': 7, 'cssLitGroup': [ L[ 0 ], L[ 35 ], L[ 48 ], L[ 54 ] ] }, '-moz-opacity': { 'cssPropBits': 1, 'cssLitGroup': [ L[ 47 ] ] }, '-moz-outline': { 'cssExtra': c[ 3 ], 'cssPropBits': 7, 'cssLitGroup': [ L[ 0 ], L[ 9 ], L[ 34 ], L[ 46 ], L[ 47 ], L[ 48 ], L[ 49 ], L[ 52 ], L[ 54 ] ] }, '-moz-outline-color': { 'cssExtra': c[ 2 ], 'cssPropBits': 2, 'cssLitGroup': [ L[ 0 ], L[ 47 ], L[ 49 ] ] }, '-moz-outline-style': { 'cssPropBits': 0, 'cssLitGroup': [ L[ 9 ], L[ 46 ], L[ 47 ], L[ 48 ], L[ 54 ] ] }, '-moz-outline-width': { 'cssPropBits': 5, 'cssLitGroup': [ L[ 34 ], L[ 47 ], L[ 52 ] ] }, '-o-text-overflow': { 'cssPropBits': 0, 'cssLitGroup': [ L[ 25 ] ] }, '-webkit-border-bottom-left-radius': { 'cssExtra': c[ 0 ], 'cssPropBits': 5 }, '-webkit-border-bottom-right-radius': { 'cssExtra': c[ 0 ], 'cssPropBits': 5 }, '-webkit-border-radius': { 'cssExtra': c[ 0 ], 'cssPropBits': 5, 'cssLitGroup': [ L[ 36 ] ] }, '-webkit-border-radius-bottom-left': { 'cssExtra': c[ 0 ], 'cssPropBits': 5 }, '-webkit-border-radius-bottom-right': { 'cssExtra': c[ 0 ], 'cssPropBits': 5 }, '-webkit-border-radius-top-left': { 'cssExtra': c[ 0 ], 'cssPropBits': 5 }, '-webkit-border-radius-top-right': { 'cssExtra': c[ 0 ], 'cssPropBits': 5 }, '-webkit-border-top-left-radius': { 'cssExtra': c[ 0 ], 'cssPropBits': 5 }, '-webkit-border-top-right-radius': { 'cssExtra': c[ 0 ], 'cssPropBits': 5 }, '-webkit-box-shadow': { 'cssExtra': c[ 1 ], 'cssAlternates': [ 'boxShadow' ], 'cssPropBits': 7, 'cssLitGroup': [ L[ 0 ], L[ 35 ], L[ 48 ], L[ 54 ] ] }, 'azimuth': { 'cssPropBits': 5, 'cssLitGroup': [ L[ 6 ], L[ 30 ], L[ 42 ], L[ 47 ] ] }, 'background': { 'cssExtra': RegExp('^ *(?:\\s*' + s[ 0 ] + '){0,2} *$', 'i'), 'cssPropBits': 23, 'cssLitGroup': [ L[ 0 ], L[ 14 ], L[ 17 ], L[ 24 ], L[ 30 ], L[ 35 ], L[ 36 ], L[ 38 ], L[ 42 ], L[ 45 ], L[ 47 ], L[ 51 ], L[ 54 ], L[ 57 ], L[ 58 ], L[ 62 ] ] }, 'background-attachment': { 'cssExtra': c[ 0 ], 'cssPropBits': 0, 'cssLitGroup': [ L[ 35 ], L[ 45 ], L[ 51 ], L[ 58 ] ] }, 'background-color': { 'cssExtra': c[ 2 ], 'cssPropBits': 130, 'cssLitGroup': [ L[ 0 ], L[ 47 ], L[ 62 ] ] }, 'background-image': { 'cssExtra': c[ 0 ], 'cssPropBits': 16, 'cssLitGroup': [ L[ 35 ], L[ 54 ] ] }, 'background-position': { 'cssExtra': c[ 0 ], 'cssPropBits': 5, 'cssLitGroup': [ L[ 24 ], L[ 30 ], L[ 35 ], L[ 42 ] ] }, 'background-repeat': { 'cssExtra': c[ 0 ], 'cssPropBits': 0, 'cssLitGroup': [ L[ 17 ], L[ 35 ], L[ 57 ] ] }, 'border': { 'cssExtra': c[ 3 ], 'cssPropBits': 7, 'cssLitGroup': [ L[ 0 ], L[ 9 ], L[ 34 ], L[ 46 ], L[ 47 ], L[ 48 ], L[ 52 ], L[ 54 ], L[ 62 ] ] }, 'border-bottom': { 'cssExtra': c[ 3 ], 'cssPropBits': 7, 'cssLitGroup': [ L[ 0 ], L[ 9 ], L[ 34 ], L[ 46 ], L[ 47 ], L[ 48 ], L[ 52 ], L[ 54 ], L[ 62 ] ] }, 'border-bottom-color': { 'cssExtra': c[ 2 ], 'cssPropBits': 2, 'cssLitGroup': [ L[ 0 ], L[ 47 ], L[ 62 ] ] }, 'border-bottom-left-radius': { 'cssExtra': c[ 0 ], 'cssPropBits': 5 }, 'border-bottom-right-radius': { 'cssExtra': c[ 0 ], 'cssPropBits': 5 }, 'border-bottom-style': { 'cssPropBits': 0, 'cssLitGroup': [ L[ 9 ], L[ 46 ], L[ 47 ], L[ 48 ], L[ 54 ] ] }, 'border-bottom-width': { 'cssPropBits': 5, 'cssLitGroup': [ L[ 34 ], L[ 47 ], L[ 52 ] ] }, 'border-collapse': { 'cssPropBits': 0, 'cssLitGroup': [ L[ 44 ], L[ 47 ], L[ 59 ] ] }, 'border-color': { 'cssExtra': RegExp('^ *(?:\\s*' + s[ 0 ] + '){1,4} *$', 'i'), 'cssPropBits': 2, 'cssLitGroup': [ L[ 0 ], L[ 47 ], L[ 62 ] ] }, 'border-left': { 'cssExtra': c[ 3 ], 'cssPropBits': 7, 'cssLitGroup': [ L[ 0 ], L[ 9 ], L[ 34 ], L[ 46 ], L[ 47 ], L[ 48 ], L[ 52 ], L[ 54 ], L[ 62 ] ] }, 'border-left-color': { 'cssExtra': c[ 2 ], 'cssPropBits': 2, 'cssLitGroup': [ L[ 0 ], L[ 47 ], L[ 62 ] ] }, 'border-left-style': { 'cssPropBits': 0, 'cssLitGroup': [ L[ 9 ], L[ 46 ], L[ 47 ], L[ 48 ], L[ 54 ] ] }, 'border-left-width': { 'cssPropBits': 5, 'cssLitGroup': [ L[ 34 ], L[ 47 ], L[ 52 ] ] }, 'border-radius': { 'cssExtra': c[ 0 ], 'cssPropBits': 5, 'cssLitGroup': [ L[ 36 ] ] }, 'border-right': { 'cssExtra': c[ 3 ], 'cssPropBits': 7, 'cssLitGroup': [ L[ 0 ], L[ 9 ], L[ 34 ], L[ 46 ], L[ 47 ], L[ 48 ], L[ 52 ], L[ 54 ], L[ 62 ] ] }, 'border-right-color': { 'cssExtra': c[ 2 ], 'cssPropBits': 2, 'cssLitGroup': [ L[ 0 ], L[ 47 ], L[ 62 ] ] }, 'border-right-style': { 'cssPropBits': 0, 'cssLitGroup': [ L[ 9 ], L[ 46 ], L[ 47 ], L[ 48 ], L[ 54 ] ] }, 'border-right-width': { 'cssPropBits': 5, 'cssLitGroup': [ L[ 34 ], L[ 47 ], L[ 52 ] ] }, 'border-spacing': { 'cssExtra': c[ 0 ], 'cssPropBits': 5, 'cssLitGroup': [ L[ 47 ] ] }, 'border-style': { 'cssPropBits': 0, 'cssLitGroup': [ L[ 9 ], L[ 46 ], L[ 47 ], L[ 48 ], L[ 54 ] ] }, 'border-top': { 'cssExtra': c[ 3 ], 'cssPropBits': 7, 'cssLitGroup': [ L[ 0 ], L[ 9 ], L[ 34 ], L[ 46 ], L[ 47 ], L[ 48 ], L[ 52 ], L[ 54 ], L[ 62 ] ] }, 'border-top-color': { 'cssExtra': c[ 2 ], 'cssPropBits': 2, 'cssLitGroup': [ L[ 0 ], L[ 47 ], L[ 62 ] ] }, 'border-top-left-radius': { 'cssExtra': c[ 0 ], 'cssPropBits': 5 }, 'border-top-right-radius': { 'cssExtra': c[ 0 ], 'cssPropBits': 5 }, 'border-top-style': { 'cssPropBits': 0, 'cssLitGroup': [ L[ 9 ], L[ 46 ], L[ 47 ], L[ 48 ], L[ 54 ] ] }, 'border-top-width': { 'cssPropBits': 5, 'cssLitGroup': [ L[ 34 ], L[ 47 ], L[ 52 ] ] }, 'border-width': { 'cssPropBits': 5, 'cssLitGroup': [ L[ 34 ], L[ 47 ], L[ 52 ] ] }, 'bottom': { 'cssPropBits': 5, 'cssLitGroup': [ L[ 38 ], L[ 47 ] ] }, 'box-shadow': { 'cssExtra': c[ 1 ], 'cssPropBits': 7, 'cssLitGroup': [ L[ 0 ], L[ 35 ], L[ 48 ], L[ 54 ] ] }, 'caption-side': { 'cssPropBits': 0, 'cssLitGroup': [ L[ 24 ], L[ 47 ] ] }, 'clear': { 'cssPropBits': 0, 'cssLitGroup': [ L[ 30 ], L[ 40 ], L[ 47 ], L[ 54 ] ] }, 'clip': { 'cssExtra': /^ *\s*rect\(\s*(?:0|[+\-]?\d+(?:\.\d+)?(?:[cem]m|ex|in|p[ctx])|auto)\s*,\s*(?:0|[+\-]?\d+(?:\.\d+)?(?:[cem]m|ex|in|p[ctx])|auto)\s*,\s*(?:0|[+\-]?\d+(?:\.\d+)?(?:[cem]m|ex|in|p[ctx])|auto)\s*,\s*(?:0|[+\-]?\d+(?:\.\d+)?(?:[cem]m|ex|in|p[ctx])|auto) *\) *$/i, 'cssPropBits': 0, 'cssLitGroup': [ L[ 38 ], L[ 47 ] ] }, 'color': { 'cssExtra': c[ 2 ], 'cssPropBits': 130, 'cssLitGroup': [ L[ 0 ], L[ 47 ] ] }, 'content': { 'cssPropBits': 0 }, 'counter-increment': { 'cssExtra': c[ 0 ], 'cssPropBits': 5, 'cssLitGroup': [ L[ 47 ], L[ 54 ] ] }, 'counter-reset': { 'cssExtra': c[ 0 ], 'cssPropBits': 5, 'cssLitGroup': [ L[ 47 ], L[ 54 ] ] }, 'cue': { 'cssPropBits': 16, 'cssLitGroup': [ L[ 47 ], L[ 54 ] ] }, 'cue-after': { 'cssPropBits': 16, 'cssLitGroup': [ L[ 47 ], L[ 54 ] ] }, 'cue-before': { 'cssPropBits': 16, 'cssLitGroup': [ L[ 47 ], L[ 54 ] ] }, 'cursor': { 'cssExtra': c[ 0 ], 'cssPropBits': 144, 'cssLitGroup': [ L[ 1 ], L[ 35 ], L[ 38 ], L[ 47 ] ] }, 'direction': { 'cssPropBits': 0, 'cssLitGroup': [ L[ 31 ], L[ 47 ] ] }, 'display': { 'cssPropBits': 32, 'cssLitGroup': [ L[ 2 ], L[ 47 ], L[ 54 ] ] }, 'elevation': { 'cssPropBits': 5, 'cssLitGroup': [ L[ 13 ], L[ 47 ] ] }, 'empty-cells': { 'cssPropBits': 0, 'cssLitGroup': [ L[ 27 ], L[ 47 ] ] }, 'filter': { 'cssExtra': /^ *(?:\s*alpha\(\s*opacity\s*=\s*(?:0|\d+(?:\.\d+)?%|[+\-]?\d+(?:\.\d+)?) *\))+ *$/i, 'cssPropBits': 32 }, 'float': { 'cssAlternates': [ 'cssFloat', 'styleFloat' ], 'cssPropBits': 32, 'cssLitGroup': [ L[ 30 ], L[ 47 ], L[ 54 ] ] }, 'font': { 'cssExtra': c[ 0 ], 'cssPropBits': 9, 'cssLitGroup': [ L[ 4 ], L[ 7 ], L[ 11 ], L[ 15 ], L[ 29 ], L[ 35 ], L[ 36 ], L[ 47 ], L[ 52 ], L[ 55 ], L[ 60 ] ] }, 'font-family': { 'cssExtra': c[ 0 ], 'cssPropBits': 8, 'cssLitGroup': [ L[ 15 ], L[ 35 ], L[ 47 ] ] }, 'font-size': { 'cssPropBits': 1, 'cssLitGroup': [ L[ 7 ], L[ 47 ], L[ 52 ] ] }, 'font-stretch': { 'cssPropBits': 0, 'cssLitGroup': [ L[ 5 ], L[ 55 ] ] }, 'font-style': { 'cssPropBits': 0, 'cssLitGroup': [ L[ 29 ], L[ 47 ], L[ 55 ] ] }, 'font-variant': { 'cssPropBits': 0, 'cssLitGroup': [ L[ 47 ], L[ 55 ], L[ 60 ] ] }, 'font-weight': { 'cssPropBits': 0, 'cssLitGroup': [ L[ 4 ], L[ 47 ], L[ 55 ] ] }, 'height': { 'cssPropBits': 37, 'cssLitGroup': [ L[ 38 ], L[ 47 ] ] }, 'left': { 'cssPropBits': 37, 'cssLitGroup': [ L[ 38 ], L[ 47 ] ] }, 'letter-spacing': { 'cssPropBits': 5, 'cssLitGroup': [ L[ 47 ], L[ 55 ] ] }, 'line-height': { 'cssPropBits': 1, 'cssLitGroup': [ L[ 47 ], L[ 55 ] ] }, 'list-style': { 'cssPropBits': 16, 'cssLitGroup': [ L[ 3 ], L[ 28 ], L[ 47 ], L[ 54 ] ] }, 'list-style-image': { 'cssPropBits': 16, 'cssLitGroup': [ L[ 47 ], L[ 54 ] ] }, 'list-style-position': { 'cssPropBits': 0, 'cssLitGroup': [ L[ 28 ], L[ 47 ] ] }, 'list-style-type': { 'cssPropBits': 0, 'cssLitGroup': [ L[ 3 ], L[ 47 ], L[ 54 ] ] }, 'margin': { 'cssPropBits': 5, 'cssLitGroup': [ L[ 38 ], L[ 47 ] ] }, 'margin-bottom': { 'cssPropBits': 5, 'cssLitGroup': [ L[ 38 ], L[ 47 ] ] }, 'margin-left': { 'cssPropBits': 5, 'cssLitGroup': [ L[ 38 ], L[ 47 ] ] }, 'margin-right': { 'cssPropBits': 5, 'cssLitGroup': [ L[ 38 ], L[ 47 ] ] }, 'margin-top': { 'cssPropBits': 5, 'cssLitGroup': [ L[ 38 ], L[ 47 ] ] }, 'max-height': { 'cssPropBits': 1, 'cssLitGroup': [ L[ 38 ], L[ 47 ], L[ 54 ] ] }, 'max-width': { 'cssPropBits': 1, 'cssLitGroup': [ L[ 38 ], L[ 47 ], L[ 54 ] ] }, 'min-height': { 'cssPropBits': 1, 'cssLitGroup': [ L[ 38 ], L[ 47 ] ] }, 'min-width': { 'cssPropBits': 1, 'cssLitGroup': [ L[ 38 ], L[ 47 ] ] }, 'opacity': { 'cssPropBits': 33, 'cssLitGroup': [ L[ 47 ] ] }, 'outline': { 'cssExtra': c[ 3 ], 'cssPropBits': 7, 'cssLitGroup': [ L[ 0 ], L[ 9 ], L[ 34 ], L[ 46 ], L[ 47 ], L[ 48 ], L[ 49 ], L[ 52 ], L[ 54 ] ] }, 'outline-color': { 'cssExtra': c[ 2 ], 'cssPropBits': 2, 'cssLitGroup': [ L[ 0 ], L[ 47 ], L[ 49 ] ] }, 'outline-style': { 'cssPropBits': 0, 'cssLitGroup': [ L[ 9 ], L[ 46 ], L[ 47 ], L[ 48 ], L[ 54 ] ] }, 'outline-width': { 'cssPropBits': 5, 'cssLitGroup': [ L[ 34 ], L[ 47 ], L[ 52 ] ] }, 'overflow': { 'cssPropBits': 32, 'cssLitGroup': [ L[ 38 ], L[ 46 ], L[ 47 ], L[ 58 ], L[ 63 ] ] }, 'overflow-x': { 'cssPropBits': 0, 'cssLitGroup': [ L[ 32 ], L[ 38 ], L[ 46 ], L[ 58 ], L[ 63 ] ] }, 'overflow-y': { 'cssPropBits': 0, 'cssLitGroup': [ L[ 32 ], L[ 38 ], L[ 46 ], L[ 58 ], L[ 63 ] ] }, 'padding': { 'cssPropBits': 1, 'cssLitGroup': [ L[ 47 ] ] }, 'padding-bottom': { 'cssPropBits': 33, 'cssLitGroup': [ L[ 47 ] ] }, 'padding-left': { 'cssPropBits': 33, 'cssLitGroup': [ L[ 47 ] ] }, 'padding-right': { 'cssPropBits': 33, 'cssLitGroup': [ L[ 47 ] ] }, 'padding-top': { 'cssPropBits': 33, 'cssLitGroup': [ L[ 47 ] ] }, 'page-break-after': { 'cssPropBits': 0, 'cssLitGroup': [ L[ 30 ], L[ 37 ], L[ 38 ], L[ 39 ], L[ 47 ] ] }, 'page-break-before': { 'cssPropBits': 0, 'cssLitGroup': [ L[ 30 ], L[ 37 ], L[ 38 ], L[ 39 ], L[ 47 ] ] }, 'page-break-inside': { 'cssPropBits': 0, 'cssLitGroup': [ L[ 38 ], L[ 39 ], L[ 47 ] ] }, 'pause': { 'cssPropBits': 5, 'cssLitGroup': [ L[ 47 ] ] }, 'pause-after': { 'cssPropBits': 5, 'cssLitGroup': [ L[ 47 ] ] }, 'pause-before': { 'cssPropBits': 5, 'cssLitGroup': [ L[ 47 ] ] }, 'pitch': { 'cssPropBits': 5, 'cssLitGroup': [ L[ 19 ], L[ 47 ], L[ 52 ] ] }, 'pitch-range': { 'cssPropBits': 5, 'cssLitGroup': [ L[ 47 ] ] }, 'play-during': { 'cssExtra': c[ 0 ], 'cssPropBits': 16, 'cssLitGroup': [ L[ 38 ], L[ 47 ], L[ 53 ], L[ 54 ], L[ 57 ] ] }, 'position': { 'cssPropBits': 32, 'cssLitGroup': [ L[ 20 ], L[ 47 ] ] }, 'quotes': { 'cssExtra': c[ 0 ], 'cssPropBits': 0, 'cssLitGroup': [ L[ 47 ], L[ 54 ] ] }, 'richness': { 'cssPropBits': 5, 'cssLitGroup': [ L[ 47 ] ] }, 'right': { 'cssPropBits': 37, 'cssLitGroup': [ L[ 38 ], L[ 47 ] ] }, 'speak': { 'cssPropBits': 0, 'cssLitGroup': [ L[ 47 ], L[ 54 ], L[ 55 ], L[ 61 ] ] }, 'speak-header': { 'cssPropBits': 0, 'cssLitGroup': [ L[ 37 ], L[ 47 ], L[ 56 ] ] }, 'speak-numeral': { 'cssPropBits': 0, 'cssLitGroup': [ L[ 26 ], L[ 47 ] ] }, 'speak-punctuation': { 'cssPropBits': 0, 'cssLitGroup': [ L[ 43 ], L[ 47 ], L[ 54 ] ] }, 'speech-rate': { 'cssPropBits': 5, 'cssLitGroup': [ L[ 12 ], L[ 47 ], L[ 52 ] ] }, 'stress': { 'cssPropBits': 5, 'cssLitGroup': [ L[ 47 ] ] }, 'table-layout': { 'cssPropBits': 0, 'cssLitGroup': [ L[ 38 ], L[ 45 ], L[ 47 ] ] }, 'text-align': { 'cssPropBits': 0, 'cssLitGroup': [ L[ 30 ], L[ 42 ], L[ 47 ], L[ 50 ] ] }, 'text-decoration': { 'cssPropBits': 0, 'cssLitGroup': [ L[ 18 ], L[ 47 ], L[ 54 ] ] }, 'text-indent': { 'cssPropBits': 5, 'cssLitGroup': [ L[ 47 ] ] }, 'text-overflow': { 'cssPropBits': 0, 'cssLitGroup': [ L[ 25 ] ] }, 'text-shadow': { 'cssExtra': c[ 1 ], 'cssPropBits': 7, 'cssLitGroup': [ L[ 0 ], L[ 35 ], L[ 48 ], L[ 54 ] ] }, 'text-transform': { 'cssPropBits': 0, 'cssLitGroup': [ L[ 21 ], L[ 47 ], L[ 54 ] ] }, 'text-wrap': { 'cssPropBits': 0, 'cssLitGroup': [ L[ 33 ], L[ 54 ], L[ 55 ] ] }, 'top': { 'cssPropBits': 37, 'cssLitGroup': [ L[ 38 ], L[ 47 ] ] }, 'unicode-bidi': { 'cssPropBits': 0, 'cssLitGroup': [ L[ 23 ], L[ 47 ], L[ 55 ] ] }, 'vertical-align': { 'cssPropBits': 5, 'cssLitGroup': [ L[ 10 ], L[ 24 ], L[ 47 ] ] }, 'visibility': { 'cssPropBits': 32, 'cssLitGroup': [ L[ 44 ], L[ 46 ], L[ 47 ], L[ 63 ] ] }, 'voice-family': { 'cssExtra': c[ 0 ], 'cssPropBits': 8, 'cssLitGroup': [ L[ 22 ], L[ 35 ], L[ 47 ] ] }, 'volume': { 'cssPropBits': 1, 'cssLitGroup': [ L[ 16 ], L[ 47 ], L[ 52 ] ] }, 'white-space': { 'cssPropBits': 0, 'cssLitGroup': [ L[ 8 ], L[ 47 ], L[ 55 ] ] }, 'width': { 'cssPropBits': 33, 'cssLitGroup': [ L[ 38 ], L[ 47 ] ] }, 'word-spacing': { 'cssPropBits': 5, 'cssLitGroup': [ L[ 47 ], L[ 55 ] ] }, 'word-wrap': { 'cssPropBits': 0, 'cssLitGroup': [ L[ 41 ], L[ 55 ] ] }, 'z-index': { 'cssPropBits': 69, 'cssLitGroup': [ L[ 38 ], L[ 47 ] ] }, 'zoom': { 'cssPropBits': 1, 'cssLitGroup': [ L[ 55 ] ] } }; })(); if (typeof window !== 'undefined') { window['cssSchema'] = cssSchema; } // Copyright (C) 2011 Google Inc. // // Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. /** * A lexical scannar for CSS3 as defined at http://www.w3.org/TR/css3-syntax . * * @author Mike Samuel <mikesamuel@gmail.com> * \@provides lexCss, decodeCss * \@overrides window */ var lexCss; var decodeCss; (function () { /** * Decodes an escape sequence as specified in CSS3 section 4.1. * http://www.w3.org/TR/css3-syntax/#characters * @private */ function decodeCssEscape(s) { var i = parseInt(s.substring(1), 16); // If parseInt didn't find a hex diigt, it returns NaN so return the // escaped character. // Otherwise, parseInt will stop at the first non-hex digit so there's no // need to worry about trailing whitespace. if (i > 0xffff) { // A supplemental codepoint. return i -= 0x10000, String.fromCharCode( 0xd800 + (i >> 10), 0xdc00 + (i & 0x3FF)); } else if (i == i) { return String.fromCharCode(i); } else if (s[1] < ' ') { // "a backslash followed by a newline is ignored". return ''; } else { return s[1]; } } /** * Returns an equivalent CSS string literal given plain text: foo -> "foo". * @private */ function escapeCssString(s, replacer) { return '"' + s.replace(/[\u0000-\u001f\\\"<>]/g, replacer) + '"'; } /** * Maps chars to CSS escaped equivalents: "\n" -> "\\a ". * @private */ function escapeCssStrChar(ch) { return cssStrChars[ch] || (cssStrChars[ch] = '\\' + ch.charCodeAt(0).toString(16) + ' '); } /** * Maps chars to URI escaped equivalents: "\n" -> "%0a". * @private */ function escapeCssUrlChar(ch) { return cssUrlChars[ch] || (cssUrlChars[ch] = (ch < '\x10' ? '%0' : '%') + ch.charCodeAt(0).toString(16)); } /** * Mapping of CSS special characters to escaped equivalents. * @private */ var cssStrChars = { '\\': '\\\\' }; /** * Mapping of CSS special characters to URL-escaped equivalents. * @private */ var cssUrlChars = { '\\': '%5c' }; // The comments below are copied from the CSS3 module syntax at // http://www.w3.org/TR/css3-syntax . // These string constants minify out when this is run-through closure // compiler. // Rules that have been adapted have comments prefixed with "Diff:", and // where rules have been combined to avoid back-tracking in the regex engine // or to work around limitations, there is a comment prefixed with // "NewRule:". // In the below, we assume CRLF and CR have been normalize to CR. // wc ::= #x9 | #xA | #xC | #xD | #x20 var WC = '[\\t\\n\\f ]'; // w ::= wc* var W = WC + '*'; // nl ::= #xA | #xD #xA | #xD | #xC var NL = '[\\n\\f]'; // nonascii ::= [#x80-#xD7FF#xE000-#xFFFD#x10000-#x10FFFF] // NewRule: Supplemental codepoints are represented as surrogate pairs in JS. var SURROGATE_PAIR = '[\\ud800-\\udbff][\\udc00-\\udfff]'; var NONASCII = '[\\u0080-\\ud7ff\\ue000-\\ufffd]|' + SURROGATE_PAIR; // unicode ::= '\' [0-9a-fA-F]{1,6} wc? // NewRule: No point in having ESCAPE do (\\x|\\y) var UNICODE_TAIL = '[0-9a-fA-F]{1,6}' + WC + '?'; var UNICODE = '\\\\' + UNICODE_TAIL; // escape ::= unicode // | '\' [#x20-#x7E#x80-#xD7FF#xE000-#xFFFD#x10000-#x10FFFF] // NewRule: Below we use escape tail to efficiently match an escape or a // line continuation so we can decode string content. var ESCAPE_TAIL = '(?:' + UNICODE_TAIL + '|[\\u0020-\\u007e\\u0080-\\ud7ff\\ue000\\ufffd]|' + SURROGATE_PAIR + ')'; var ESCAPE = '\\\\' + ESCAPE_TAIL; // urlchar ::= [#x9#x21#x23-#x26#x28-#x7E] | nonascii | escape var URLCHAR = '(?:[\\t\\x21\\x23-\\x26\\x28-\\x5b\\x5d-\\x7e]|' + NONASCII + '|' + ESCAPE + ')'; // stringchar ::= urlchar | #x20 | '\' nl // We ignore mismatched surrogate pairs inside strings, so stringchar // simplifies to a non-(quote|newline|backslash) or backslash any. // Since we normalize CRLF to a single code-unit, there is no special // handling needed for '\\' + CRLF. var STRINGCHAR = '[^\'"\\n\\f\\\\]|\\\\[\\s\\S]'; // string ::= '"' (stringchar | "'")* '"' | "'" (stringchar | '"')* "'" var STRING = '"(?:\'|' + STRINGCHAR + ')*"' + '|\'(?:\"|' + STRINGCHAR + ')*\''; // num ::= [0-9]+ | [0-9]* '.' [0-9]+ // Diff: We attach signs to num tokens. var NUM = '[-+]?(?:[0-9]+(?:[.][0-9]+)?|[.][0-9]+)'; // nmstart ::= [a-zA-Z] | '_' | nonascii | escape var NMSTART = '(?:[a-zA-Z_]|' + NONASCII + '|' + ESCAPE + ')'; // nmchar ::= [a-zA-Z0-9] | '-' | '_' | nonascii | escape var NMCHAR = '(?:[a-zA-Z0-9_-]|' + NONASCII + '|' + ESCAPE + ')'; // name ::= nmchar+ var NAME = NMCHAR + '+'; // ident ::= '-'? nmstart nmchar* var IDENT = '-?' + NMSTART + NMCHAR + '*'; // ATKEYWORD ::= '@' ident var ATKEYWORD = '@' + IDENT; // HASH ::= '#' name var HASH = '#' + NAME; // NUMBER ::= num var NUMBER = NUM; // NewRule: union of IDENT, ATKEYWORD, HASH, but excluding #[0-9]. var WORD_TERM = '(?:@?-?' + NMSTART + '|#)' + NMCHAR + '*'; // PERCENTAGE ::= num '%' var PERCENTAGE = NUM + '%'; // DIMENSION ::= num ident var DIMENSION = NUM + IDENT; var NUMERIC_VALUE = NUM + '(?:%|' + IDENT + ')?'; // URI ::= "url(" w (string | urlchar* ) w ")" var URI = 'url[(]' + W + '(?:' + STRING + '|' + URLCHAR + '*)' + W + '[)]'; // UNICODE-RANGE ::= "U+" [0-9A-F?]{1,6} ('-' [0-9A-F]{1,6})? var UNICODE_RANGE = 'U[+][0-9A-F?]{1,6}(?:-[0-9A-F]{1,6})?'; // CDO ::= "<\!--" var CDO = '<\!--'; // CDC ::= "-->" var CDC = '-->'; // S ::= wc+ var S = WC + '+'; // COMMENT ::= "/*" [^*]* '*'+ ([^/] [^*]* '*'+)* "/" // Diff: recognizes // comments. var COMMENT = '/(?:[*][^*]*[*]+(?:[^/][^*]*[*]+)*/|/[^\\n\\f]*)'; // FUNCTION ::= ident '(' // Diff: We exclude url explicitly. // TODO: should we be tolerant of "fn ("? // ##### BEGIN: MODIFIED BY SAP // Avoid risk of 'catastrophic backtracking' when unicode escapes are used // var FUNCTION = '(?!url[(])' + IDENT + '[(]'; var FUNCTION = '(?!url[(])(?=(' + IDENT + '))\\1[(]'; // ##### END: MODIFIED BY SAP // INCLUDES ::= "~=" var INCLUDES = '~='; // DASHMATCH ::= "|=" var DASHMATCH = '[|]='; // PREFIXMATCH ::= "^=" var PREFIXMATCH = '[^]='; // SUFFIXMATCH ::= "$=" var SUFFIXMATCH = '[$]='; // SUBSTRINGMATCH ::= "*=" var SUBSTRINGMATCH = '[*]='; // NewRule: one rule for all the comparison operators. var CMP_OPS = '[~|^$*]='; // CHAR ::= any character not matched by the above rules, except for " or ' // Diff: We exclude / and \ since they are handled above to prevent // /* without a following */ from combining when comments are concatenated. var CHAR = '[^"\'\\\\/]|/(?![/*])'; // BOM ::= #xFEFF var BOM = '\\uFEFF'; var CSS_TOKEN = new RegExp([ BOM, UNICODE_RANGE, URI, FUNCTION, WORD_TERM, STRING, NUMERIC_VALUE, CDO, CDC, S, COMMENT, CMP_OPS, CHAR].join("|"), 'gi'); /** * Decodes CSS escape sequences in a CSS string body. */ decodeCss = function (css) { return css.replace( new RegExp('\\\\(?:' + ESCAPE_TAIL + '|' + NL + ')', 'g'), decodeCssEscape); }; /** * Given CSS Text, returns an array of normalized tokens. * @param {string} cssText * @return {Array.<string>} tokens where all ignorable token sequences have * been reduced to a single {@code " "} and all strings and * {@code url(...)} tokens have been normalized to use double quotes as * delimiters and to not otherwise contain double quotes. */ lexCss = function (cssText) { cssText = '' + cssText; var tokens = cssText.replace(/\r\n?/g, '\n') // Normalize CRLF & CR to LF. .match(CSS_TOKEN) || []; var j = 0; var last = ' '; for (var i = 0, n = tokens.length; i < n; ++i) { // Normalize all escape sequences. We will have to re-escape some // codepoints in string and url(...) bodies but we already know the // boundaries. // We might mistakenly treat a malformed identifier like \22\20\22 as a // string, but that will not break any valid stylesheets since we requote // and re-escape in string below. var tok = decodeCss(tokens[i]); var len = tok.length; var cc = tok.charCodeAt(0); tok = // All strings should be double quoted, and the body should never // contain a double quote. (cc == '"'.charCodeAt(0) || cc == '\''.charCodeAt(0)) ? escapeCssString(tok.substring(1, len - 1), escapeCssStrChar) // A breaking ignorable token should is replaced with a single space. : (cc == '/'.charCodeAt(0) && len > 1 // Comment. || tok == '\\' || tok == CDC || tok == CDO || tok == '\ufeff' // Characters in W. || cc <= ' '.charCodeAt(0)) ? ' ' // Make sure that all url(...)s are double quoted. : /url\(/i.test(tok) ? 'url(' + escapeCssString( tok.replace( new RegExp('^url\\(' + W + '["\']?|["\']?' + W + '\\)$', 'gi'), ''), escapeCssUrlChar) + ')' // Escapes in identifier like tokens will have been normalized above. : tok; // Merge adjacent space tokens. if (last != tok || tok != ' ') { tokens[j++] = last = tok; } } tokens.length = j; return tokens; }; })(); // Exports for closure compiler. if (typeof window !== 'undefined') { window['lexCss'] = lexCss; window['decodeCss'] = decodeCss; } // Copyright (C) 2011 Google Inc. // // Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. /** * @fileoverview * JavaScript support for client-side CSS sanitization. * The CSS property schema API is defined in CssPropertyPatterns.java which * is used to generate css-defs.js. * * @author mikesamuel@gmail.com * \@requires CSS_PROP_BIT_ALLOWED_IN_LINK * \@requires CSS_PROP_BIT_HASH_VALUE * \@requires CSS_PROP_BIT_NEGATIVE_QUANTITY * \@requires CSS_PROP_BIT_QSTRING_CONTENT * \@requires CSS_PROP_BIT_QSTRING_URL * \@requires CSS_PROP_BIT_QUANTITY * \@requires CSS_PROP_BIT_Z_INDEX * \@requires cssSchema * \@requires decodeCss * \@requires html4 * \@overrides window * \@requires parseCssStylesheet * \@provides sanitizeCssProperty * \@provides sanitizeCssSelectors * \@provides sanitizeStylesheet */ /** * Given a series of normalized CSS tokens, applies a property schema, as * defined in CssPropertyPatterns.java, and sanitizes the tokens in place. * @param property a property name. * @param propertySchema a property of cssSchema as defined by * CssPropertyPatterns.java * @param tokens as parsed by lexCss. Modified in place. * @param opt_naiveUriRewriter a URI rewriter; an object with a "rewrite" * function that takes a URL and returns a safe URL. */ var sanitizeCssProperty = (function () { var NOEFFECT_URL = 'url("about:blank")'; /** * The set of characters that need to be normalized inside url("..."). * We normalize newlines because they are not allowed inside quoted strings, * normalize quote characters, angle-brackets, and asterisks because they * could be used to break out of the URL or introduce targets for CSS * error recovery. We normalize parentheses since they delimit unquoted * URLs and calls and could be a target for error recovery. */ var NORM_URL_REGEXP = /[\n\f\r\"\'()*<>]/g; /** The replacements for NORM_URL_REGEXP. */ var NORM_URL_REPLACEMENTS = { '\n': '%0a', '\f': '%0c', '\r': '%0d', '"': '%22', '\'': '%27', '(': '%28', ')': '%29', '*': '%2a', '<': '%3c', '>': '%3e' }; function normalizeUrl(s) { if ('string' === typeof s) { return 'url("' + s.replace(NORM_URL_REGEXP, normalizeUrlChar) + '")'; } else { return NOEFFECT_URL; } } function normalizeUrlChar(ch) { return NORM_URL_REPLACEMENTS[ch]; } // From RFC3986 var URI_SCHEME_RE = new RegExp( '^' + '(?:' + '([^:\/?# ]+)' + // scheme ':)?' ); var ALLOWED_URI_SCHEMES = /^(?:https?|mailto)$/i; function safeUri(uri, prop, naiveUriRewriter) { if (!naiveUriRewriter) { return null; } var parsed = ('' + uri).match(URI_SCHEME_RE); if (parsed && (!parsed[1] || ALLOWED_URI_SCHEMES.test(parsed[1]))) { return naiveUriRewriter(uri, prop); } else { return null; } } function unionArrays(arrs) { var map = {}; for (var i = arrs.length; --i >= 0;) { var arr = arrs[i]; for (var j = arr.length; --j >= 0;) { map[arr[j]] = ALLOWED_LITERAL; } } return map; } /** * Normalize tokens within a function call they can match against * cssSchema[propName].cssExtra. * @return the exclusive end in tokens of the function call. */ function normalizeFunctionCall(tokens, start) { var parenDepth = 1, end = start + 1, n = tokens.length; while (end < n && parenDepth) { // TODO: Can URLs appear in functions? var token = tokens[end++]; parenDepth += (token === '(' ? 1 : token === ')' ? -1 : 0); } return end; } // Used as map value to avoid hasOwnProperty checks. var ALLOWED_LITERAL = {}; return function (property, propertySchema, tokens, opt_naiveUriRewriter) { var propBits = propertySchema.cssPropBits; // Used to determine whether to treat quoted strings as URLs or // plain text content, and whether unrecognized keywords can be quoted // to treate ['Arial', 'Black'] equivalently to ['"Arial Black"']. var qstringBits = propBits & ( CSS_PROP_BIT_QSTRING_CONTENT | CSS_PROP_BIT_QSTRING_URL); // TODO(mikesamuel): Figure out what to do with props like // content that admit both URLs and strings. // Used to join unquoted keywords into a single quoted string. var lastQuoted = NaN; var i = 0, k = 0; for (;i < tokens.length; ++i) { // Has the effect of normalizing hex digits, keywords, // and function names. var token = tokens[i].toLowerCase(); var cc = token.charCodeAt(0), cc1, cc2, isnum1, isnum2, end; var litGroup, litMap; token = ( // Strip out spaces. Normally cssparser.js dumps these, but we // strip them out in case the content doesn't come via cssparser.js. (cc === ' '.charCodeAt(0)) ? '' : (cc === '"'.charCodeAt(0)) ? ( // Quoted string. (qstringBits === CSS_PROP_BIT_QSTRING_URL && opt_naiveUriRewriter) // Sanitize and convert to url("...") syntax. // Treat url content as case-sensitive. ? (normalizeUrl(safeUri( decodeCss(tokens[i].substring(1, token.length - 1)), property, opt_naiveUriRewriter))) // Drop if plain text content strings not allowed. : (qstringBits === CSS_PROP_BIT_QSTRING_CONTENT) ? token : '') // Preserve hash color literals if allowed. : (cc === '#'.charCodeAt(0) && /^#(?:[0-9a-f]{3}){1,2}$/.test(token)) ? (propBits & CSS_PROP_BIT_HASH_VALUE ? token : '') : ('0'.charCodeAt(0) <= cc && cc <= '9'.charCodeAt(0)) // A number starting with a digit. ? ((propBits & CSS_PROP_BIT_QUANTITY) ? ((propBits & CSS_PROP_BIT_Z_INDEX) ? (token.match(/^\d{1,7}$/) ? token : '') : token) : '') // Normalize quantities so they don't start with a '.' or '+' sign and // make sure they all have an integer component so can't be confused // with a dotted identifier. // This can't be done in the lexer since ".4" is a valid rule part. : (cc1 = token.charCodeAt(1), cc2 = token.charCodeAt(2), isnum1 = '0'.charCodeAt(0) <= cc1 && cc1 <= '9'.charCodeAt(0), isnum2 = '0'.charCodeAt(0) <= cc2 && cc2 <= '9'.charCodeAt(0), // +.5 -> 0.5 if allowed. (cc === '+'.charCodeAt(0) && (isnum1 || (cc1 === '.'.charCodeAt(0) && isnum2)))) ? ((propBits & CSS_PROP_BIT_QUANTITY) ? ((propBits & CSS_PROP_BIT_Z_INDEX) ? (token.match(/^\+\d{1,7}$/) ? token : '') : ((isnum1 ? '' : '0') + token.substring(1))) : '') // -.5 -> -0.5 if allowed otherwise -> 0 if quantities allowed. : (cc === '-'.charCodeAt(0) && (isnum1 || (cc1 === '.'.charCodeAt(0) && isnum2))) ? ((propBits & CSS_PROP_BIT_NEGATIVE_QUANTITY) ? ((propBits & CSS_PROP_BIT_Z_INDEX) ? (token.match(/^\-\d{1,7}$/) ? token : '') : ((isnum1 ? '-' : '-0') + token.substring(1))) : ((propBits & CSS_PROP_BIT_QUANTITY) ? '0' : '')) // .5 -> 0.5 if allowed. : (cc === '.'.charCodeAt(0) && isnum1) ? ((propBits & CSS_PROP_BIT_QUANTITY) ? '0' + token : '') // Handle url("...") by rewriting the body. : ('url(' === token.substring(0, 4)) ? ((opt_naiveUriRewriter && (qstringBits & CSS_PROP_BIT_QSTRING_URL)) ? normalizeUrl(safeUri( tokens[i].substring(5, token.length - 2), property, opt_naiveUriRewriter)) : '') // Handle func(...) and literal tokens // such as keywords and punctuation. : ( // Step 1. Combine func(...) into something that can be compared // against propertySchema.cssExtra. (token.charAt(token.length-1) === '(') && (end = normalizeFunctionCall(tokens, i), // When tokens is // ['x', ' ', 'rgb(', '255', ',', '0', ',', '0', ')', ' ', 'y'] // and i is the index of 'rgb(' and end is the index of ')' // splices tokens to where i now is the index of the whole call: // ['x', ' ', 'rgb( 255 , 0 , 0 )', ' ', 'y'] tokens.splice(i, end - i, token = tokens.slice(i, end).join(' '))), litGroup = propertySchema.cssLitGroup, litMap = (litGroup ? (propertySchema.cssLitMap // Lazily compute the union from litGroup. || (propertySchema.cssLitMap = unionArrays(litGroup))) : ALLOWED_LITERAL), // A convenient empty object. (litMap[token] === ALLOWED_LITERAL || propertySchema.cssExtra && propertySchema.cssExtra.test(token))) // Token is in the literal map or matches extra. ? token : (/^\w+$/.test(token) && (qstringBits === CSS_PROP_BIT_QSTRING_CONTENT)) // Quote unrecognized keywords so font names like // Arial Bold // -> // "Arial Bold" ? (lastQuoted+1 === k // If the last token was also a keyword that was quoted, then // combine this token into that. ? (tokens[lastQuoted] = tokens[lastQuoted] .substring(0, tokens[lastQuoted].length-1) + ' ' + token + '"', token = '') : (lastQuoted = k, '"' + token + '"')) // Disallowed. : ''); if (token) { tokens[k++] = token; } } // For single URL properties, if the URL failed to pass the sanitizer, // then just drop it. if (k === 1 && tokens[0] === NOEFFECT_URL) { k = 0; } tokens.length = k; }; })(); /** * Given a series of tokens, returns two lists of sanitized selectors. * @param {Array.<string>} selectors In the form produces by csslexer.js. * @param {string} suffix a suffix that is added to all IDs and which is * used as a CLASS names so that the returned selectors will only match * nodes under one with suffix as a class name. * If suffix is {@code "sfx"}, the selector * {@code ["a", "#foo", " ", "b", ".bar"]} will be namespaced to * {@code [".sfx", " ", "a", "#foo-sfx", " ", "b", ".bar"]}. * @return {Array.<Array.<string>>} an array of length 2 where the zeroeth * element contains history-insensitive selectors and the first element * contains history-sensitive selectors. */ function sanitizeCssSelectors(selectors, suffix) { // Produce two distinct lists of selectors to sequester selectors that are // history sensitive (:visited), so that we can disallow properties in the // property groups for the history sensitive ones. var historySensitiveSelectors = []; var historyInsensitiveSelectors = []; // Remove any spaces that are not operators. var k = 0, i; for (i = 0; i < selectors.length; ++i) { if (!(selectors[i] == ' ' && (selectors[i-1] == '>' || selectors[i+1] == '>'))) { selectors[k++] = selectors[i]; } } selectors.length = k; // Split around commas. If there is an error in one of the comma separated // bits, we throw the whole away, but the failure of one selector does not // affect others. var n = selectors.length, start = 0; for (i = 0; i < n; ++i) { if (selectors[i] == ',') { processSelector(start, i); start = i+1; } } processSelector(start, n); function processSelector(start, end) { var historySensitive = false; // Space around commas is not an operator. if (selectors[start] === ' ') { ++start; } if (end-1 !== start && selectors[end] === ' ') { --end; } // Split the selector into element selectors, content around // space (ancestor operator) and '>' (descendant operator). var out = []; var lastOperator = start; var elSelector = ''; for (var i = start; i < end; ++i) { var tok = selectors[i]; var isChild = (tok === '>'); if (isChild || tok === ' ') { // We've found the end of a single link in the selector chain. // We disallow absolute positions relative to html. elSelector = processElementSelector(lastOperator, i, false); if (!elSelector || (isChild && /^html/i.test(elSelector))) { return; } lastOperator = i+1; out.push(elSelector, isChild ? ' > ' : ' '); } } elSelector = processElementSelector(lastOperator, end, true); if (!elSelector) { return; } out.push(elSelector); function processElementSelector(start, end, last) { var debugStart = start, debugEnd = end; // Split the element selector into three parts. // DIV.foo#bar:hover // ^ ^ // el classes pseudo var element, classId, pseudoSelector, tok, elType; element = ''; if (start < end) { tok = selectors[start].toLowerCase(); if (tok === '*' || (tok === 'body' && start+1 !== end && !last) || ('number' === typeof (elType = html4.ELEMENTS[tok]) && !(elType & html4.eflags.UNSAFE))) { ++start; element = tok; } } classId = ''; while (start < end) { tok = selectors[start]; if (tok.charAt(0) === '#') { if (/^#_|__$|[^#0-9A-Za-z:_\-]/.test(tok)) { return null; } // Rewrite ID elements to include the suffix. classId += tok + '-' + suffix; } else if (tok === '.') { if (++start < end && /^[0-9A-Za-z:_\-]+$/.test(tok = selectors[start]) && !/^_|__$/.test(tok)) { classId += '.' + tok; } else { return null; } } else { break; } ++start; }