diff --git a/public(1).md b/public(1).md deleted file mode 100644 index 06a5d3c..0000000 --- a/public(1).md +++ /dev/null @@ -1,3457 +0,0 @@ -// 清除供应商前缀缓存的方法 -cleanPrefixes: function() -{ -// 将 mVENDOR_PREFIXES 属性置为 null,清除之前缓存的供应商前缀信息 -this.mVENDOR_PREFIXES = null; -}, - -// 根据属性获取对应的供应商前缀数组的方法 -prefixesForProperty: function(aProperty) -{ -// 检查 mVENDOR_PREFIXES 是否为 null,如果为 null 则进行初始化 -if (!this.mVENDOR_PREFIXES) { -// 初始化 mVENDOR_PREFIXES 为一个空对象 -this.mVENDOR_PREFIXES = {}; -// 遍历 kCSS_VENDOR_PREFIXES.properties 数组 -for (var i = 0; i < kCSS_VENDOR_PREFIXES.properties.length; i++) { -// 获取当前属性 -var p = kCSS_VENDOR_PREFIXES.properties[i]; -// 检查该属性是否有 gecko 前缀,并且有 webkit、presto 或 trident 前缀之一 -if (p.gecko && (p.webkit || p.presto || p.trident)) { -// 初始化一个空对象 o 用于存储不同前缀 -var o = {}; -// 如果 kEXPORTS_FOR_GECKO 为 true,则将 gecko 前缀添加到 o 中 -if (this.kEXPORTS_FOR_GECKO) o[p.gecko] = true; -// 如果 kEXPORTS_FOR_WEBKIT 为 true 且有 webkit 前缀,则将 webkit 前缀添加到 o 中 -if (this.kEXPORTS_FOR_WEBKIT && p.webkit) o[p.webkit] = true; -// 如果 kEXPORTS_FOR_PRESTO 为 true 且有 presto 前缀,则将 presto 前缀添加到 o 中 -if (this.kEXPORTS_FOR_PRESTO && p.presto) o[p.presto] = true; -// 如果 kEXPORTS_FOR_TRIDENT 为 true 且有 trident 前缀,则将 trident 前缀添加到 o 中 -if (this.kEXPORTS_FOR_TRIDENT && p.trident) o[p.trident] = true; -// 在 mVENDOR_PREFIXES 中为 gecko 前缀创建一个空数组 -this.mVENDOR_PREFIXES[p.gecko] = []; -// 遍历 o 对象,将其中的前缀添加到 mVENDOR_PREFIXES[p.gecko] 数组中 -for (var j in o) -this.mVENDOR_PREFIXES[p.gecko].push(j) -} -} -} -// 检查传入的属性是否存在于 mVENDOR_PREFIXES 中 -if (aProperty in this.mVENDOR_PREFIXES) -// 如果存在,则对该属性对应的前缀数组进行排序并返回 -return this.mVENDOR_PREFIXES[aProperty].sort(); -// 如果不存在,则返回 null -return null; -}, - -// 解析颜色停止点的方法 -parseColorStop: function(parser, token) -{ -// 调用 parser 的 parseColor 方法解析颜色 -var color = parser.parseColor(token); -// 初始化位置为空字符串 -var position = ""; -// 如果颜色解析失败,则返回 null -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) -{ -// 初始化是否为径向渐变的标志为 false -var isRadial = false; -// 初始化渐变对象,设置是否重复为 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(")) { -// 如果是径向渐变函数,则将 isRadial 标志置为 true -if (token.isFunction("-moz-radial-gradient(") || -token.isFunction("-moz-repeating-radial-gradient(")) { -gradient.isRadial = true; -} -// 如果是重复渐变函数,则将 isRepeating 标志置为 true -if (token.isFunction("-moz-repeating-linear-gradient(") || -token.isFunction("-moz-repeating-radial-gradient(")) { -gradient.isRepeating = true; -} - - // 获取下一个标记 - token = parser.getToken(true, true); - // 初始化是否有渐变线的标志为 false - var haveGradientLine = false; - // 初始化是否找到水平位置的标志为 false - var foundHorizPosition = false; - // 初始化是否有角度的标志为 false - var haveAngle = false; - - // 检查标记是否为角度 - if (token.isAngle()) { - // 如果是,则将角度值赋给渐变对象的 angle 属性 - gradient.angle = token.value; - // 将 haveGradientLine 标志置为 true - haveGradientLine = true; - // 将 haveAngle 标志置为 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 - haveGradientLine = true; - // 检查标记是否为长度或水平位置标识符 - if (token.isLength() - || token.isIdent("left") - || token.isIdent("right")) { - // 如果是,则将 foundHorizPosition 标志置为 true - foundHorizPosition = true; - } - // 将标记的值赋给渐变对象的 position 属性 - gradient.position = token.value; - // 获取下一个标记 - token = parser.getToken(true, true); - } - - // 如果有渐变线 - if (haveGradientLine) { - // 如果没有角度且标记为角度 - if (!haveAngle && token.isAngle()) { - // 将角度值赋给渐变对象的 angle 属性 - gradient.angle = token.value; - // 将 haveAngle 标志置为 true - 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")))) { - // 如果符合条件,则更新渐变对象的 position 属性 - gradient.position = ("position" in gradient) ? gradient.position + " ": ""; - gradient.position += token.value; - // 获取下一个标记 - token = parser.getToken(true, true); - } - - // 如果没有角度且标记为角度 - if (!haveAngle && token.isAngle()) { - // 将角度值赋给渐变对象的 angle 属性 - gradient.angle = token.value; - // 将 haveAngle 标志置为 true - haveAngle = true; - // 获取下一个标记 - token = parser.getToken(true, true); - } - - // 检查标记是否为逗号 - if (!token.isSymbol(",")) - // 如果不是,则返回 null - return null; - // 获取下一个标记 - token = parser.getToken(true, true); - } - - // 如果是径向渐变 - if (gradient.isRadial) { - // 检查标记是否为圆形或椭圆形标识符 - if (token.isIdent("circle") || - token.isIdent("ellipse")) { - // 如果是,则将标识符的值赋给渐变对象的 shape 属性 - 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")) { - // 如果是,则将标识符的值赋给渐变对象的 size 属性 - gradient.size = token.value; - // 获取下一个标记 - token = parser.getToken(true, true); - } - // 如果 shape 属性不存在且标记为圆形或椭圆形标识符 - if (!("shape" in gradient) && - (token.isIdent("circle") || - token.isIdent("ellipse"))) { - // 将标识符的值赋给渐变对象的 shape 属性 - gradient.shape = token.value; - // 获取下一个标记 - token = parser.getToken(true, true); - } - // 如果 shape 或 size 属性存在且标记不是逗号 - if ((("shape" in gradient) || ("size" in gradient)) && !token.isSymbol(",")) - // 返回 null - return null; - // 如果 shape 或 size 属性存在 - else if (("shape" in gradient) || ("size" in gradient)) - // 获取下一个标记 - token = parser.getToken(true, true); - } - - // 解析第一个颜色停止点 - var stop1 = this.parseColorStop(parser, token); - // 如果解析失败,则返回 null - if (!stop1) - return null; - // 获取当前标记 - token = parser.currentToken(); - // 检查标记是否为逗号 - if (!token.isSymbol(",")) - // 如果不是,则返回 null - return null; - // 获取下一个标记 - token = parser.getToken(true, true); - // 解析第二个颜色停止点 - var stop2 = this.parseColorStop(parser, token); - // 如果解析失败,则返回 null - if (!stop2) - return null; - // 获取当前标记 - token = parser.currentToken(); - // 如果标记为逗号 - if (token.isSymbol(",")) { - // 获取下一个标记 - token = parser.getToken(true, true); - } - // 将前两个颜色停止点添加到渐变对象的 stops 数组中 - gradient.stops = [stop1, stop2]; - // 循环解析剩余的颜色停止点,直到遇到右括号 - while (!token.isSymbol(")")) { - // 解析颜色停止点 - var colorstop = this.parseColorStop(parser, token); - // 如果解析失败,则返回 null - if (!colorstop) - return null; - // 获取当前标记 - token = parser.currentToken(); - // 检查标记是否为右括号或逗号 - if (!token.isSymbol(")") && !token.isSymbol(",")) - // 如果不是,则返回 null - return null; - // 如果标记为逗号 - if (token.isSymbol(",")) - // 获取下一个标记 - token = parser.getToken(true, true); - // 将颜色停止点添加到渐变对象的 stops 数组中 - gradient.stops.push(colorstop); - } - // 返回解析好的渐变对象 - return gradient; - } - } - // 如果解析失败,则返回 null - return null; -}, - -// 解析盒阴影的方法 -parseBoxShadows: function(aString) -{ -// 创建一个 CSSParser 实例 -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"; - // 初始化是否为内阴影的标志为 false - var inset = false; - // 循环处理标记,直到标记为空 - while (token.isNotNull()) { - // 检查标记是否为 "none" - if (token.isIdent("none")) { - // 如果是,则将一个包含 none 为 true 的对象添加到阴影数组中 - shadows.push( { none: true } ); - // 获取下一个标记 - token = parser.getToken(true, true); - } - else { - // 检查标记是否为 "inset" - if (token.isIdent('inset')) { - // 如果是,则将 inset 标志置为 true - 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")) { - // 如果是,则将标记的值赋给 offsetX - var offsetX = token.value; - // 获取下一个标记 - token = parser.getToken(true, true); - } - else - // 如果不是,则返回空数组 - return []; - - // 如果不是内阴影且标记为 "inset" - if (!inset && token.isIdent('inset')) { - // 将 inset 标志置为 true - 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")) { - // 如果是,则将标记的值赋给 offsetY - var offsetY = token.value; - // 获取下一个标记 - token = parser.getToken(true, true); - } - else - // 如果不是,则返回空数组 - return []; - - // 如果不是内阴影且标记为 "inset" - if (!inset && token.isIdent('inset')) { - // 将 inset 标志置为 true - 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")) { - // 如果是,则将标记的值赋给 blurRadius - var blurRadius = token.value; - // 获取下一个标记 - token = parser.getToken(true, true); - } - - // 如果不是内阴影且标记为 "inset" - if (!inset && token.isIdent('inset')) { - // 将 inset 标志置为 true - inset = true; - // 获取下一个标记 - token = parser.getToken(true, true); - } - - // 检查标记是否为颜色函数、符号或标识符 - if (token.isFunction("rgb(") || - token.isFunction("rgba(") || - token.isFunction("hsl(") || - token.isFunction("hsla(") || - token.isSymbol("#") || - token.isIdent()) { - // 如果是,则调用解析器的 parseColor 方法解析颜色 - var color = parser.parseColor(token); - // 获取下一个标记 - token = parser.getToken(true, true); - } - - // 如果不是内阴影且标记为 "inset" - if (!inset && token.isIdent('inset')) { - // 将 inset 标志置为 true - 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) -{ -// 创建一个 CSSParser 实例 -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()) { - // 检查标记是否为 "none" - if (token.isIdent("none")) { - // 如果是,则将一个包含 none 为 true 的对象添加到阴影数组中 - 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()) { - // 如果是,则调用解析器的 parseColor 方法解析颜色 - 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")) { - // 如果是,则将标记的值赋给 offsetX - 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")) { - // 如果是,则将标记的值赋给 offsetY - 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")) { - // 如果是,则将标记的值赋给 blurRadius - 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())) { - // 调用解析器的 parseColor 方法解析颜色 - 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) -{ -// 创建一个 CSSParser 实例 -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 */ - // 检查标记是否为 url 函数 - if (token.isFunction("url(")) { - // 获取下一个标记 - token = parser.getToken(true, true); - // 调用解析器的 parseURL 方法解析 URL - var urlContent = parser.parseURL(token); - // 将解析好的 URL 信息添加到背景数组中 - 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(")) { - // 调用 parseGradient 方法解析渐变 - var gradient = this.parseGradient(parser, token); - // 根据渐变类型将渐变信息添加到背景数组中 - backgrounds.push( { type: gradient.isRadial ? "radial-gradient" : "linear-gradient", value: gradient }); - // 获取下一个标记 - token = parser.getToken(true, true); - } - else - // 如果标记不符合要求,则返回 null - return null; - // 检查标记是否为逗号 - if (token.isSymbol(",")) { - // 获取下一个标记 - token = parser.getToken(true, true); - // 如果标记为空,则返回 null - 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) -{ -// 创建一个 CSSParser 实例 -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); - // 检查标记是否为 url 函数 - if (token.isFunction("url(")) { - // 获取下一个标记 - token = parser.getToken(true, true); - // 调用解析器的 parseURL 方法解析 URL - var urlContent = parser.parseURL(token); - // 如果 URL 解析成功 - if (urlContent) { - // 处理 URL 字符串,去除首尾引号 - 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 - // 如果 URL 解析失败,则返回 null - return null; - } - else - // 如果标记不是 url 函数,则返回 null - return null; - - // 获取下一个标记 - token = parser.getToken(true, true); - // 检查标记是否为数字或百分比 - if (token.isNumber() || token.isPercentage()) - // 如果是,则将标记的值添加到边框图像的 offsets 数组中 - borderImage.offsets.push(token.value); - else - // 如果不是,则返回 null - return null; - // 循环处理后续的标记,最多处理 3 个 - var i; - for (i= 0; i < 3; i++) { - // 获取下一个标记 - token = parser.getToken(true, true); - // 检查标记是否为数字或百分比 - if (token.isNumber() || token.isPercentage()) - // 如果是,则将标记的值添加到边框图像的 offsets 数组中 - borderImage.offsets.push(token.value); - else - // 如果不是,则跳出循环 - break; - } - // 如果处理了 3 个标记,则获取下一个标记 - if (i == 3) - token = parser.getToken(true, true); - - // 检查标记是否为斜杠 - if (token.isSymbol("/")) { - // 获取下一个标记 - token = parser.getToken(true, true); - // 检查标记是否为尺寸、数字 0 或特定的边框宽度名称 - if (token.isDimension() - || token.isNumber("0") - || (token.isIdent() && token.value in parser.kBORDER_WIDTH_NAMES)) - // 如果是,则将标记的值添加到边框图像的 widths 数组中 - borderImage.widths.push(token.value); - else - // 如果不是,则返回 null - return null; - - // 循环处理后续的标记,最多处理 3 个 - for (var i = 0; i < 3; i++) { - // 获取下一个标记 - token = parser.getToken(true, true); - // 检查标记是否为尺寸、数字 0 或特定的边框宽度名称 - if (token.isDimension() - || token.isNumber("0") - || (token.isIdent() && token.value in parser.kBORDER_WIDTH_NAMES)) - // 如果是,则将标记的值添加到边框图像的 widths 数组中 - borderImage.widths.push(token.value); - else - // 如果不是,则跳出循环 - break; - } - // 如果处理了 3 个标记,则获取下一个标记 - if (i == 3) - token = parser.getToken(true, true); - } - - // 循环处理后续的标记,最多处理 2 个 - for (var i = 0; i < 2; i++) { - // 检查标记是否为特定的尺寸标识符 - if (token.isIdent("stretch") - || token.isIdent("repeat") - || token.isIdent("round")) - // 如果是,则将标记的值添加到边框图像的 sizes 数组中 - borderImage.sizes.push(token.value); - else if (!token.isNotNull()) - // 如果标记为空,则返回边框图像对象 - return borderImage; - else - // 如果标记不符合要求,则返回 null - return null; - // 获取下一个标记 - token = parser.getToken(true, true); - } - // 如果标记为空,则返回边框图像对象 - if (!token.isNotNull()) - return borderImage; - - // 如果解析失败,则返回 null - 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 - -// 模拟 kCSS_VENDOR_PREFIXES -const kCSS_VENDOR_PREFIXES = { -properties: [ -{ gecko: '-moz-example', webkit: '-webkit-example', presto: '-o-example', trident: '-ms-example' } -] -}; - -// 模拟 CSSParser 类 -class CSSParser { -constructor() { -this.mScanner = { -init: function (aString) { -// 初始化扫描器逻辑 -} -}; -} - - _init() { - // 初始化解析器逻辑 - } - - getToken() { - // 模拟获取标记逻辑 - return { - isNotNull: function () { return true; }, - isFunction: function (name) { return false; }, - isAngle: function () { return false; }, - isLength: function () { return false; }, - isIdent: function (value) { return false; }, - isSymbol: function (symbol) { return false; }, - isPercentage: function () { return false; }, - isDimensionOfUnit: function (unit) { return false; }, - parseColor: function (token) { return 'color'; }, - currentToken: function () { return { isSymbol: function (symbol) { return false; } }; }, - parseURL: function (token) { return 'url-content'; } - }; - } -} - -// 定义对象 -const obj = { -kEXPORTS_FOR_GECKO: true, -kEXPORTS_FOR_WEBKIT: true, -kEXPORTS_FOR_PRESTO: true, -kEXPORTS_FOR_TRIDENT: true, -mVENDOR_PREFIXES: null, - - // 清除前缀缓存 - 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()) { - 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()) { - gradient.angle = token.value; - haveAngle = true; - token = parser.getToken(true, true); - } - - if (!token.isSymbol(",")) - return null; - token = parser.getToken(true, true); - } - - 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"))) { - 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); - } - - 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); - } - 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 { - // 检查是否有 inset 关键字 - if (token.isIdent('inset')) { - inset = true; - token = parser.getToken(true, true); - } - - // 解析偏移量 X - 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); - } - - // 解析偏移量 Y - 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 (!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.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); - } - // 解析偏移量 X - 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 []; - // 解析偏移量 Y - 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("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; - } -}; - -// 简单测试 -console.log(obj.prefixesForProperty('-moz-example')); - -// 解析命名空间规则 -parseNamespaceRule: function(aToken, aSheet) { -// 获取当前行号,通过 CountLF 函数统计已扫描内容中的换行符数量 -var currentLine = CountLF(this.mScanner.getAlreadyScanned()); -// 初始化规则字符串,赋值为当前 token 的值 -var s = aToken.value; -// 标记规则是否有效,初始为 false -var valid = false; -// 保存当前解析状态 -this.preserveState(); -// 获取下一个 token -var token = this.getToken(true, true); -if (token.isNotNull()) { -// 初始化前缀为空字符串 -var prefix = ""; -// 初始化 URL 为空字符串 -var url = ""; -if (token.isIdent()) { -// 如果 token 是标识符,将其赋值给前缀 -prefix = token.value; -// 将前缀添加到规则字符串中 -s += " " + prefix; -// 获取下一个 token -token = this.getToken(true, true); -} -if (token) { -// 标记是否找到 URL,初始为 false -var foundURL = false; -if (token.isString()) { -// 如果 token 是字符串,标记找到 URL -foundURL = true; -// 将字符串赋值给 URL -url = token.value; -// 将 URL 添加到规则字符串中 -s += " " + url; -} else if (token.isFunction("url(")) { -// 如果 token 是 url 函数,获取下一个 token -token = this.getToken(true, true); -// 解析 URL 内容 -var urlContent = this.parseURL(token); -if (urlContent) { -// 如果解析成功,将 url 内容添加到 URL 中 -url += "url(" + urlContent; -// 标记找到 URL -foundURL = true; -// 将 url 内容添加到规则字符串中 -s += " " + urlContent; -} -} -} -if (foundURL) { -// 如果找到 URL,获取下一个 token -token = this.getToken(true, true); -if (token.isSymbol(";")) { -// 如果 token 是分号,将分号添加到规则字符串中 -s += ";"; -// 忘记之前保存的状态 -this.forgetState(); -// 创建一个新的 jscsspNamespaceRule 对象 -var rule = new jscsspNamespaceRule(); -// 设置规则的当前行号 -rule.currentLine = currentLine; -// 设置规则的解析后的 CSS 文本 -rule.parsedCssText = s; -// 设置规则的前缀 -rule.prefix = prefix; -// 设置规则的 URL -rule.url = url; -// 设置规则的父样式表 -rule.parentStyleSheet = aSheet; -// 将规则添加到父样式表的 CSS 规则列表中 -aSheet.cssRules.push(rule); -// 返回 true 表示规则解析成功 -return true; -} -} -} -// 恢复之前保存的状态 -this.restoreState(); -// 将未知的 @namespace 规则添加到样式表中 -this.addUnknownAtRule(aSheet, "@namespace"); -// 返回 false 表示规则解析失败 -return false; -}, - -// 解析字体规则 -parseFontFaceRule: function(aToken, aSheet) { -// 获取当前行号,通过 CountLF 函数统计已扫描内容中的换行符数量 -var currentLine = CountLF(this.mScanner.getAlreadyScanned()); -// 初始化规则字符串,赋值为当前 token 的值 -var s = aToken.value; -// 标记规则是否有效,初始为 false -var valid = false; -// 初始化描述符数组 -var descriptors = []; -// 保存当前解析状态 -this.preserveState(); -// 获取下一个 token -var token = this.getToken(true, true); -if (token.isNotNull()) { -// 期望遇到块开始符号 { -if (token.isSymbol("{")) { -// 将块开始符号添加到规则字符串中 -s += " " + token.value; -// 获取下一个 token -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 -token = this.getToken(true, false); -} -} -} -if (valid) { -// 如果规则有效,忘记之前保存的状态 -this.forgetState(); -// 创建一个新的 jscsspFontFaceRule 对象 -var rule = new jscsspFontFaceRule(); -// 设置规则的当前行号 -rule.currentLine = currentLine; -// 设置规则的解析后的 CSS 文本 -rule.parsedCssText = s; -// 设置规则的描述符 -rule.descriptors = descriptors; -// 设置规则的父样式表 -rule.parentStyleSheet = aSheet; -// 将规则添加到父样式表的 CSS 规则列表中 -aSheet.cssRules.push(rule); -// 返回 true 表示规则解析成功 -return true; -} -// 恢复之前保存的状态 -this.restoreState(); -// 返回 false 表示规则解析失败 -return false; -}, - -// 解析页面规则 -parsePageRule: function(aToken, aSheet) { -// 获取当前行号,通过 CountLF 函数统计已扫描内容中的换行符数量 -var currentLine = CountLF(this.mScanner.getAlreadyScanned()); -// 初始化规则字符串,赋值为当前 token 的值 -var s = aToken.value; -// 标记规则是否有效,初始为 false -var valid = false; -// 初始化声明数组 -var declarations = []; -// 保存当前解析状态 -this.preserveState(); -// 获取下一个 token -var token = this.getToken(true, true); -// 初始化页面选择器为空字符串 -var pageSelector = ""; -if (token.isSymbol(":") || token.isIdent()) { -if (token.isSymbol(":")) { -// 如果 token 是冒号,将其添加到页面选择器中 -pageSelector = ":"; -// 获取下一个 token -token = this.getToken(false, false); -} -if (token.isIdent()) { -// 如果 token 是标识符,将其添加到页面选择器中 -pageSelector += token.value; -// 将页面选择器添加到规则字符串中 -s += " " + pageSelector; -// 获取下一个 token -token = this.getToken(true, true); -} -} -if (token.isNotNull()) { -// 期望遇到块开始符号 { -if (token.isSymbol("{")) { -// 将块开始符号添加到规则字符串中 -s += " " + token.value; -// 获取下一个 token -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 -token = this.getToken(true, false); -} -} -} -if (valid) { -// 如果规则有效,忘记之前保存的状态 -this.forgetState(); -// 创建一个新的 jscsspPageRule 对象 -var rule = new jscsspPageRule(); -// 设置规则的当前行号 -rule.currentLine = currentLine; -// 设置规则的解析后的 CSS 文本 -rule.parsedCssText = s; -// 设置规则的页面选择器 -rule.pageSelector = pageSelector; -// 设置规则的声明 -rule.declarations = declarations; -// 设置规则的父样式表 -rule.parentStyleSheet = aSheet; -// 将规则添加到父样式表的 CSS 规则列表中 -aSheet.cssRules.push(rule); -// 返回 true 表示规则解析成功 -return true; -} -// 恢复之前保存的状态 -this.restoreState(); -// 返回 false 表示规则解析失败 -return false; -}, - -// 解析默认属性值 -parseDefaultPropertyValue: function(token, aDecl, aAcceptPriority, descriptor, aSheet) { -// 初始化属性值文本为空字符串 -var valueText = ""; -// 初始化块栈,用于处理嵌套的块 -var blocks = []; -// 标记是否找到优先级,初始为 false -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 { -// 将 inherit 赋值给属性值文本 -valueText = this.kINHERIT; -// 创建一个新的 jscsspVariable 对象表示 inherit 值 -var value = new jscsspVariable(kJscsspINHERIT_VALUE, aSheet); -// 将值添加到值数组中 -values.push(value); -// 获取下一个 token -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(); -} -} -} -// 处理函数调用 -if (token.isFunction()) { -if (token.isFunction("var(")) { -// 如果是 var 函数,获取下一个 token -token = this.getToken(true, true); -if (token.isIdent()) { -// 如果是标识符,获取变量名 -var name = token.value; -// 获取下一个 token -token = this.getToken(true, true); -if (token.isSymbol(")")) { -// 如果是右括号,创建一个新的 jscsspVariable 对象表示变量值 -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 -token = this.getToken(false, true); -// 解析函数参数 -var arg = this.parseFunctionArgument(token); -if (arg) { -// 如果解析成功,将函数名和参数添加到属性值文本中 -valueText += fn + arg; -// 创建一个新的 jscsspVariable 对象表示函数值 -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; -// 创建一个新的 jscsspVariable 对象表示颜色值 -var value = new jscsspVariable(kJscsspPRIMITIVE_VALUE, aSheet); -// 设置颜色值 -value.value = color; -// 将值添加到值数组中 -values.push(value); -} else { -// 解析失败,返回空字符串 -return ""; -} -} else if (!token.isWhiteSpace() && !token.isSymbol(",")) { -// 如果不是空白字符或逗号,创建一个新的 jscsspVariable 对象表示原始值 -var value = new jscsspVariable(kJscsspPRIMITIVE_VALUE, aSheet); -// 设置原始值 -value.value = token.value; -// 将值添加到值数组中 -values.push(value); -// 将原始值添加到属性值文本中 -valueText += token.value; -} else { -// 将空白字符或逗号添加到属性值文本中 -valueText += token.value; -} -// 获取下一个 token -token = this.getToken(false, true); -} -if (values.length && valueText) { -// 如果值数组和属性值文本都不为空,忘记之前保存的状态 -this.forgetState(); -// 创建一个新的 jscsspDeclaration 对象并添加到声明数组中 -aDecl.push(this._createJscsspDeclarationFromValuesArray(descriptor, values, valueText)); -// 返回属性值文本 -return valueText; -} -// 解析失败,返回空字符串 -return ""; -}, - -// 解析边距或内边距简写属性 -parseMarginOrPaddingShorthand: function(token, aDecl, aAcceptPriority, aProperty) { -// 初始化顶部边距或内边距为 null -var top = null; -// 初始化底部边距或内边距为 null -var bottom = null; -// 初始化左边距或内边距为 null -var left = null; -// 初始化右边距或内边距为 null -var right = null; -// 初始化值数组 -var values = []; -while (true) { -if (!token.isNotNull()) { -// 如果 token 为空,跳出循环 -break; -} -if (token.isSymbol(";") -|| (aAcceptPriority && token.isSymbol("!")) -|| token.isSymbol("}")) { -if (token.isSymbol("}")) { -// 如果遇到块结束符号 },将其放回扫描器 -this.ungetToken(); -} -// 跳出循环 -break; -} else if (!values.length && token.isIdent(this.kINHERIT)) { -// 如果值数组为空且 token 是 inherit,将 inherit 添加到值数组中 -values.push(token.value); -// 获取下一个 token -token = this.getToken(true, true); -// 跳出循环 -break; -} else if (token.isDimension() -|| token.isNumber("0") -|| token.isPercentage() -|| token.isIdent("auto")) { -// 如果 token 是尺寸、数字 0、百分比或 auto,将其添加到值数组中 -values.push(token.value); -} else { -// 解析失败,返回空字符串 -return ""; -} -// 获取下一个 token -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) { -// 初始化顶部边框颜色为 null -var top = null; -// 初始化底部边框颜色为 null -var bottom = null; -// 初始化左边框颜色为 null -var left = null; -// 初始化右边框颜色为 null -var right = null; -// 初始化值数组 -var values = []; -while (true) { -if (!token.isNotNull()) { -// 如果 token 为空,跳出循环 -break; -} -if (token.isSymbol(";") -|| (aAcceptPriority && token.isSymbol("!")) -|| token.isSymbol("}")) { -if (token.isSymbol("}")) { -// 如果遇到块结束符号 },将其放回扫描器 -this.ungetToken(); -} -// 跳出循环 -break; -} else if (!values.length && token.isIdent(this.kINHERIT)) { -// 如果值数组为空且 token 是 inherit,将 inherit 添加到值数组中 -values.push(token.value); -// 获取下一个 token -token = this.getToken(true, true); -// 跳出循环 -break; -} else { -// 解析颜色值 -var color = this.parseColor(token); -if (color) { -// 如果解析成功,将颜色值添加到值数组中 -values.push(color); -} else { -// 解析失败,返回空字符串 -return ""; -} -} -// 获取下一个 token -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 = []; -while (true) { -if (!token.isNotNull()) { -// 如果 token 为空,跳出循环 -break; -} -if (token.isSymbol(";") -|| (aAcceptPriority && token.isSymbol("!")) -|| token.isSymbol("}")) { -if (token.isSymbol("}")) { -// 如果遇到块结束符号 },将其放回扫描器 -this.ungetToken(); -} -// 跳出循环 -break; -} else if (!values.length && token.isIdent(this.kINHERIT)) { -// 如果值数组为空且 token 是 inherit,将 inherit 添加到值数组中 -values.push(token.value); -} else if (token.isIdent("none")) { -// 如果 token 是 none,将其添加到值数组中 -values.push(token.value); -} else if (token.isFunction("url(")) { -// 如果 token 是 url 函数,获取下一个 token -var token = this.getToken(true, true); -// 解析 URL 内容 -var urlContent = this.parseURL(token); -if (urlContent) { -// 如果解析成功,将 url 内容添加到值数组中 -values.push("url(" + urlContent); -} else { -// 解析失败,返回空字符串 -return ""; -} -} else { -// 解析失败,返回空字符串 -return ""; -} -// 获取下一个 token -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 = []; -while (true) { -if (!token.isNotNull()) { -// 如果 token 为空,跳出循环 -break; -} -if (token.isSymbol(";") -|| (aAcceptPriority && token.isSymbol("!")) -|| token.isSymbol("}")) { -if (token.isSymbol("}")) { -// 如果遇到块结束符号 },将其放回扫描器 -this.ungetToken(); -} -// 跳出循环 -break; -} else if (!values.length && token.isIdent(this.kINHERIT)) { -// 如果值数组为空且 token 是 inherit,将 inherit 添加到值数组中 -values.push(token.value); -} else if (token.isDimensionOfUnit("ms") -|| token.isDimensionOfUnit("s") -|| token.isPercentage() -|| token.isNumber("0")) { -// 如果 token 是毫秒、秒、百分比或数字 0,将其添加到值数组中 -values.push(token.value); -} else { -// 解析失败,返回空字符串 -return ""; -} -// 获取下一个 token -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) { -// 初始化顶部边框宽度为 null -var top = null; -// 初始化底部边框宽度为 null -var bottom = null; -// 初始化左边框宽度为 null -var left = null; -// 初始化右边框宽度为 null -var right = null; -// 初始化值数组 -var values = []; -while (true) { -if (!token.isNotNull()) { -// 如果 token 为空,跳出循环 -break; -} -if (token.isSymbol(";") -|| (aAcceptPriority && token.isSymbol("!")) -|| token.isSymbol("}")) { -if (token.isSymbol("}")) { -// 如果遇到块结束符号 },将其放回扫描器 -this.ungetToken(); -} -// 跳出循环 -break; -} else if (!values.length && token.isIdent(this.kINHERIT)) { -// 如果值数组为空且 token 是 inherit,将 inherit 添加到值数组中 -values.push(token.value); -} else if (token.isDimension() -|| token.isNumber("0") -|| (token.isIdent() && token.value in this.kBORDER_WIDTH_NAMES)) { -// 如果 token 是尺寸、数字 0 或边框宽度名称,将其添加到值数组中 -values.push(token.value); -} else { -// 解析失败,返回空字符串 -return ""; -} -// 获取下一个 token -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) { -// 初始化顶部边框样式为 null -var top = null; -// 初始化底部边框样式为 null -var bottom = null; -// 初始化左边框样式为 null -var left = null; -// 初始化右边框样式为 null -var right = null; -// 初始化值数组 -var values = []; -while (true) { -if (!token.isNotNull()) { -// 如果 token 为空,跳出循环 -break; -} -if (token.isSymbol(";") -|| (aAcceptPriority && token.isSymbol("!")) -|| token.isSymbol("}")) { -if (token.isSymbol("}")) { -// 如果遇到块结束符号 },将其放回扫描器 -this.ungetToken(); -} -// 跳出循环 -break; -} else if (!values.length && token.isIdent(this.kINHERIT)) { -// 如果值数组为空且 token 是 inherit,将 inherit 添加到值数组中 -values.push(token.value); -} else if (token.isIdent() && token.value in this.kBORDER_STYLE_NAMES) { -// 如果 token 是边框样式名称,将其添加到值数组中 -values.push(token.value); -} else { -// 解析失败,返回空字符串 -return ""; -} -// 获取下一个 token -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._createJscsspDeclarationFrom - -以下是为你提供的代码注释: - -```javascript -// 解析媒体规则的函数 -// aToken: 当前的 token -// aSheet: 当前的样式表 -parseMediaRule: function(aToken, aSheet) { - // 开启媒体查询模式 - this.mScanner.mMediaQueryMode = true; - // 计算当前行数 - var currentLine = CountLF(this.mScanner.getAlreadyScanned()); - // 获取当前 token 的值 - var s = aToken.value; - // 标记规则是否有效 - var valid = false; - // 创建一个新的媒体规则对象 - var mediaRule = new jscsspMediaRule(); - // 设置媒体规则的当前行数 - mediaRule.currentLine = currentLine; - // 保存当前状态 - this.preserveState(); - // 获取下一个 token - var token = this.getToken(true, true); - // 标记是否找到媒体类型 - var foundMedia = false; - // 循环处理 token - while (token.isNotNull()) { - if (token.isIdent()) { - // 找到媒体类型 - foundMedia = true; - // 拼接媒体类型到字符串 s 中 - s += " " + token.value; - // 将媒体类型添加到媒体规则的媒体列表中 - mediaRule.media.push(token.value); - // 获取下一个 token - token = this.getToken(true, true); - if (token.isSymbol(",")) { - // 如果是逗号,拼接逗号到字符串 s 中 - s += ","; - } else { - if (token.isSymbol("{")) - // 如果是左花括号,将 token 放回队列 - this.ungetToken(); - else { - // 错误处理,将 token 类型设为 NULL_TYPE - token.type = jscsspToken.NULL_TYPE; - break; - } - } - } - else if (token.isSymbol("{")) - // 如果是左花括号,跳出循环 - break; - else if (foundMedia) { - // 如果已经找到媒体类型,但当前 token 不符合要求,将 token 类型设为 NULL_TYPE - token.type = jscsspToken.NULL_TYPE; - // 不是有效的媒体列表,跳出循环 - break; - } - // 获取下一个 token - token = this.getToken(true, true); - } - if (token.isSymbol("{") && mediaRule.media.length) { - // 如果是左花括号且媒体列表不为空,开始解析样式规则 - s += " { "; - // 获取下一个 token - token = this.getToken(true, false); - while (token.isNotNull()) { - if (token.isComment() && this.mPreserveComments) { - // 如果是注释且需要保留注释,拼接注释到字符串 s 中 - s += " " + token.value; - // 创建一个新的注释对象 - var comment = new jscsspComment(); - // 设置注释对象的解析后的 CSS 文本 - comment.parsedCssText = token.value; - // 将注释对象添加到媒体规则的 CSS 规则列表中 - mediaRule.cssRules.push(comment); - } else if (token.isSymbol("}")) { - // 如果是右花括号,标记规则有效 - valid = true; - break; - } else { - // 解析样式规则 - var r = this.parseStyleRule(token, mediaRule, true); - if (r) - // 如果解析成功,拼接解析结果到字符串 s 中 - s += r; - } - // 获取下一个 token - token = this.getToken(true, false); - } - } - if (valid) { - // 如果规则有效,忘记保存的状态 - this.forgetState(); - // 设置媒体规则的解析后的 CSS 文本 - mediaRule.parsedCssText = s; - // 将媒体规则添加到样式表的 CSS 规则列表中 - aSheet.cssRules.push(mediaRule); - return true; - } - // 恢复保存的状态 - this.restoreState(); - return false; -}, - -// 去除字符串首尾空格的函数 -// str: 要处理的字符串 -trim11: function(str) { - // 去除字符串开头的空格 - str = str.replace(/^\s+/, ''); - // 从字符串末尾开始遍历 - for (var i = str.length - 1; i >= 0; i--) { - if (/\S/.test( str.charAt(i) )) { - // 如果当前字符不是空格,截取字符串 - str = str.substring(0, i + 1); - break; - } - } - return str; -}, - -// 解析样式规则的函数 -// aToken: 当前的 token -// aOwner: 规则的所有者 -// aIsInsideMediaRule: 是否在媒体规则内部 -parseStyleRule: function(aToken, aOwner, aIsInsideMediaRule) -{ - // 计算当前行数 - var currentLine = CountLF(this.mScanner.getAlreadyScanned()); - // 保存当前状态 - this.preserveState(); - // 解析选择器 - var selector = this.parseSelector(aToken, false); - // 标记规则是否有效 - var valid = false; - // 声明列表 - var declarations = []; - if (selector) { - // 去除选择器首尾空格 - selector = this.trim11(selector.selector); - // 选择器字符串 - var s = selector; - // 获取下一个 token - var token = this.getToken(true, true); - if (token.isSymbol("{")) { - // 如果是左花括号,拼接左花括号到字符串 s 中 - s += " { "; - // 获取下一个 token - var token = this.getToken(true, false); - while (true) { - if (!token.isNotNull()) { - // 如果 token 为空,标记规则有效 - valid = true; - break; - } - if (token.isSymbol("}")) { - // 如果是右花括号,拼接右花括号到字符串 s 中,标记规则有效 - s += "}"; - valid = true; - break; - } else { - // 解析声明 - var d = this.parseDeclaration(token, declarations, true, true, aOwner); - s += ((d && declarations.length) ? " " : "") + d; - } - // 获取下一个 token - token = this.getToken(true, false); - } - } - } - else { - // 选择器无效,整个规则无效 - } - - if (valid) { - // 如果规则有效,创建一个新的样式规则对象 - var rule = new jscsspStyleRule(); - // 设置样式规则的当前行数 - rule.currentLine = currentLine; - // 设置样式规则的解析后的 CSS 文本 - rule.parsedCssText = s; - // 设置样式规则的声明列表 - rule.declarations = declarations; - // 设置样式规则的选择器文本 - rule.mSelectorText = selector; - if (aIsInsideMediaRule) - // 如果在媒体规则内部,设置样式规则的父规则 - rule.parentRule = aOwner; - else - // 否则,设置样式规则的父样式表 - rule.parentStyleSheet = aOwner; - // 将样式规则添加到所有者的 CSS 规则列表中 - aOwner.cssRules.push(rule); - return s; - } - // 恢复保存的状态 - this.restoreState(); - // 获取当前 token 的值 - s = this.currentToken().value; - // 添加未知的 @ 规则 - this.addUnknownAtRule(aOwner, s); - return ""; -}, - -// 解析选择器的函数 -// aToken: 当前的 token -// aParseSelectorOnly: 是否只解析选择器 -parseSelector: function(aToken, aParseSelectorOnly) { - // 选择器字符串 - var s = ""; - // 选择器的优先级 - var specificity = {a: 0, b: 0, c: 0, d: 0}; - // 标记是否是选择器链的第一个元素 - var isFirstInChain = true; - // 当前 token - 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("{")) { - // 如果不是只解析选择器且遇到左花括号,结束选择器解析 - valid = !combinatorFound; - if (valid) this.ungetToken(); - break; - } - - if (token.isSymbol(",")) { - // 如果是逗号,拼接逗号到字符串 s 中 - s += token.value; - // 标记是选择器链的第一个元素 - isFirstInChain = true; - // 标记未找到组合器 - combinatorFound = false; - // 获取下一个 token - token = this.getToken(false, true); - continue; - } - // 处理组合器和分组 - else if (!combinatorFound - && (token.isWhiteSpace() - || token.isSymbol(">") - || token.isSymbol("+") - || token.isSymbol("~"))) { - if (token.isWhiteSpace()) { - // 如果是空格,拼接空格到字符串 s 中 - s += " "; - // 查看下一个 token - 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 是组合器,获取下一个 token 并拼接 - token = this.getToken(true, true); - s += token.value + " "; - // 标记找到组合器 - combinatorFound = true; - } - } - else { - // 如果不是空格,拼接组合器到字符串 s 中 - s += token.value; - // 标记找到组合器 - combinatorFound = true; - } - // 标记是选择器链的第一个元素 - isFirstInChain = true; - // 获取下一个 token - token = this.getToken(true, true); - continue; - } - else { - // 解析简单选择器 - var simpleSelector = this.parseSimpleSelector(token, isFirstInChain, true); - if (!simpleSelector) - // 如果解析失败,跳出循环 - break; - // 拼接简单选择器到字符串 s 中 - s += simpleSelector.selector; - // 更新选择器的优先级 - specificity.b += simpleSelector.specificity.b; - specificity.c += simpleSelector.specificity.c; - specificity.d += simpleSelector.specificity.d; - // 标记不是选择器链的第一个元素 - isFirstInChain = false; - // 标记未找到组合器 - combinatorFound = false; - } - - // 获取下一个 token - token = this.getToken(false, true); - } - - if (valid) { - // 如果选择器有效,返回选择器和优先级 - return {selector: s, specificity: specificity }; - } - return ""; -}, - -// 判断是否为伪元素的函数 -// aIdent: 要判断的标识符 -isPseudoElement: function(aIdent) -{ - switch (aIdent) { - case "first-letter": - case "first-line": - case "before": - case "after": - case "marker": - return true; - break; - default: return false; - break; - } -}, - -// 解析简单选择器的函数 -// token: 当前的 token -// isFirstInChain: 是否是选择器链的第一个元素 -// canNegate: 是否可以使用否定伪类 -parseSimpleSelector: function(token, isFirstInChain, canNegate) -{ - // 简单选择器字符串 - var s = ""; - // 简单选择器的优先级 - var specificity = {a: 0, b: 0, c: 0, d: 0}; - - if (isFirstInChain - && (token.isSymbol("*") || token.isSymbol("|") || token.isIdent())) { - // 如果是选择器链的第一个元素,处理类型或通用选择器 - if (token.isSymbol("*") || token.isIdent()) { - // 可能是前缀或通用选择器 - s += token.value; - // 标记是否为标识符 - var isIdent = token.isIdent(); - // 获取下一个 token - token = this.getToken(false, true); - if (token.isSymbol("|")) { - // 如果是竖线,拼接竖线到字符串 s 中 - s += token.value; - // 获取下一个 token - token = this.getToken(false, true); - if (token.isIdent() || token.isSymbol("*")) { - // 如果是标识符或星号,拼接标识符或星号到字符串 s 中 - s += token.value; - if (token.isIdent()) - // 如果是标识符,更新优先级 - specificity.d++; - } else - // 错误处理,返回 null - return null; - } else { - // 将 token 放回队列 - this.ungetToken(); - if (isIdent) - // 如果是标识符,更新优先级 - specificity.d++; - } - } else if (token.isSymbol("|")) { - // 如果是竖线,拼接竖线到字符串 s 中 - s += token.value; - // 获取下一个 token - token = this.getToken(false, true); - if (token.isIdent() || token.isSymbol("*")) { - // 如果是标识符或星号,拼接标识符或星号到字符串 s 中 - s += token.value; - if (token.isIdent()) - // 如果是标识符,更新优先级 - specificity.d++; - } else - // 错误处理,返回 null - return null; - } - } - - else if (token.isSymbol(".") || token.isSymbol("#")) { - // 如果是点号或井号,处理类选择器或 ID 选择器 - var isClass = token.isSymbol("."); - // 拼接点号或井号到字符串 s 中 - s += token.value; - // 获取下一个 token - token = this.getToken(false, true); - if (token.isIdent()) { - // 如果是标识符,拼接标识符到字符串 s 中 - s += token.value; - if (isClass) - // 如果是类选择器,更新优先级 - specificity.c++; - else - // 如果是 ID 选择器,更新优先级 - specificity.b++; - } - else - // 错误处理,返回 null - return null; - } - - else if (token.isSymbol(":")) { - // 如果是冒号,处理伪类或伪元素 - s += token.value; - // 获取下一个 token - token = this.getToken(false, true); - if (token.isSymbol(":")) { - // 如果是双冒号,拼接双冒号到字符串 s 中 - s += token.value; - // 获取下一个 token - token = this.getToken(false, true); - } - if (token.isIdent()) { - // 如果是标识符,拼接标识符到字符串 s 中 - s += token.value; - if (this.isPseudoElement(token.value)) - // 如果是伪元素,更新优先级 - specificity.d++; - else - // 如果是伪类,更新优先级 - specificity.c++; - } - else if (token.isFunction()) { - // 如果是函数,拼接函数到字符串 s 中 - s += token.value; - if (token.isFunction(":not(")) { - // 如果是 :not() 函数 - if (!canNegate) - // 如果不允许使用否定伪类,返回 null - return null; - // 获取下一个 token - token = this.getToken(true, true); - // 解析简单选择器 - var simpleSelector = this.parseSimpleSelector(token, isFirstInChain, false); - if (!simpleSelector) - // 如果解析失败,返回 null - return null; - else { - // 拼接简单选择器到字符串 s 中 - s += simpleSelector.selector; - // 获取下一个 token - token = this.getToken(true, true); - if (token.isSymbol(")")) - // 如果是右括号,拼接右括号到字符串 s 中 - s += ")"; - else - // 错误处理,返回 null - return null; - } - // 更新优先级 - specificity.c++; - } - else { - while (true) { - // 处理函数参数 - token = this.getToken(false, true); - if (token.isSymbol(")")) { - // 如果是右括号,拼接右括号到字符串 s 中 - s += ")"; - break; - } else - // 拼接参数到字符串 s 中 - s += token.value; - } - // 更新优先级 - specificity.c++; - } - } else - // 错误处理,返回 null - return null; - - } else if (token.isSymbol("[")) { - // 如果是左方括号,处理属性选择器 - s += "["; - // 获取下一个 token - token = this.getToken(true, true); - if (token.isIdent() || token.isSymbol("*")) { - // 如果是标识符或星号,拼接标识符或星号到字符串 s 中 - s += token.value; - // 获取下一个 token - var nextToken = this.getToken(true, true); - if (token.isSymbol("|")) { - // 如果是竖线,拼接竖线到字符串 s 中 - s += "|"; - // 获取下一个 token - token = this.getToken(true, true); - if (token.isIdent()) - // 如果是标识符,拼接标识符到字符串 s 中 - s += token.value; - else - // 错误处理,返回 null - return null; - } else - // 将 token 放回队列 - this.ungetToken(); - } else if (token.isSymbol("|")) { - // 如果是竖线,拼接竖线到字符串 s 中 - s += "|"; - // 获取下一个 token - token = this.getToken(true, true); - if (token.isIdent()) - // 如果是标识符,拼接标识符到字符串 s 中 - s += token.value; - else - // 错误处理,返回 null - return null; - } - else - // 错误处理,返回 null - return null; - - // 处理属性选择器的操作符 - token = this.getToken(true, true); - if (token.isIncludes() - || token.isDashmatch() - || token.isBeginsmatch() - || token.isEndsmatch() - || token.isContainsmatch() - || token.isSymbol("=")) { - // 如果是操作符,拼接操作符到字符串 s 中 - s += token.value; - // 获取下一个 token - token = this.getToken(true, true); - if (token.isString() || token.isIdent()) { - // 如果是字符串或标识符,拼接字符串或标识符到字符串 s 中 - s += token.value; - // 获取下一个 token - token = this.getToken(true, true); - } - else - // 错误处理,返回 null - return null; - - if (token.isSymbol("]")) { - // 如果是右方括号,拼接右方括号到字符串 s 中 - s += token.value; - // 更新优先级 - specificity.c++; - } - else - // 错误处理,返回 null - return null; - } - else if (token.isSymbol("]")) { - // 如果是右方括号,拼接右方括号到字符串 s 中 - s += token.value; - // 更新优先级 - specificity.c++; - } - else - // 错误处理,返回 null - return null; - - } - else if (token.isWhiteSpace()) { - // 如果是空格,查看下一个 token - var t = this.lookAhead(true, true); - if (t.isSymbol('{')) - // 如果下一个 token 是左花括号,返回空字符串 - return "" - } - if (s) - // 如果简单选择器字符串不为空,返回简单选择器和优先级 - return {selector: s, specificity: specificity }; - return null; -}, - -// 保存当前状态的函数 -preserveState: function() { - // 将当前 token 保存到保存的 token 列表中 - this.mPreservedTokens.push(this.currentToken()); - // 保存扫描器的状态 - this.mScanner.preserveState(); -}, - -// 恢复保存状态的函数 -restoreState: function() { - if (this.mPreservedTokens.length) { - // 如果保存的 token 列表不为空,恢复扫描器的状态 - this.mScanner.restoreState(); - // 从保存的 token 列表中取出最后一个 token - this.mToken = this.mPreservedTokens.pop(); - } -}, - -// 忘记保存状态的函数 -forgetState: function() { - if (this.mPreservedTokens.length) { - // 如果保存的 token 列表不为空,忘记扫描器的状态 - this.mScanner.forgetState(); - // 从保存的 token 列表中取出最后一个 token - this.mPreservedTokens.pop(); - } -}, - -// 解析 CSS 字符串的函数 -// aString: 要解析的 CSS 字符串 -// aTryToPreserveWhitespaces: 是否尝试保留空格 -// aTryToPreserveComments: 是否尝试保留注释 -parse: function(aString, aTryToPreserveWhitespaces, aTryToPreserveComments) { - if (!aString) - // 如果字符串为空,返回 null - return null; - - // 设置是否保留空格 - this.mPreserveWS = aTryToPreserveWhitespaces; - // 设置是否保留注释 - this.mPreserveComments = aTryToPreserveComments; - // 初始化保存的 token 列表 - this.mPreservedTokens = []; - // 初始化扫描器 - this.mScanner.init(aString); - // 创建一个新的样式表对象 - var sheet = new jscsspStylesheet(); - - // @charset 规则只能出现在样式表的开头 - var token = this.getToken(false, false); - if (!token.isNotNull()) - return; - if (token.isAtRule("@charset")) { - // 解析 @charset 规则 - this.parseCharsetRule(token, sheet); - // 获取下一个 token - token = this.getToken(false, false); - } - - // 标记是否找到样式规则 - var foundStyleRules = false; - // 标记是否找到 @import 规则 - var foundImportRules = false; - // 标记是否找到 @namespace 规则 - var foundNameSpaceRules = false; - while (true) { - if (!token.isNotNull()) - // 如果 token 为空,跳出循环 - 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")) { - // 如果是 @variables 规则 - if (!foundImportRules && !foundStyleRules) - // 如果还没有找到 @import 规则和样式规则,解析 @variables 规则 - this.parseVariablesRule(token, sheet); - else { - // 错误处理,报告错误并添加未知的 @ 规则 - this.reportError(kVARIABLES_RULE_POSITION); - this.addUnknownAtRule(sheet, token.value); - } - } - else if (token.isAtRule("@import")) { - // 如果是 @import 规则 - // @import 规则必须出现在所有样式规则和 @namespace 规则之前 - if (!foundStyleRules && !foundNameSpaceRules) - // 如果还没有找到样式规则和 @namespace 规则,解析 @import 规则 - foundImportRules = this.parseImportRule(token, sheet); - else { - // 错误处理,报告错误并添加未知的 @ 规则 - this.reportError(kIMPORT_RULE_POSITION); - this.addUnknownAtRule(sheet, token.value); - } - } - else if (token.isAtRule("@namespace")) { - // 如果是 @namespace 规则 - // @namespace 规则必须出现在所有样式规则之后,所有 @import 规则之前 - if (!foundStyleRules) - // 如果还没有找到样式规则,解析 @namespace 规则 - foundNameSpaceRules = this.parseNamespaceRule(token, sheet); - else { - // 错误处理,报告错误并添加未知的 @ 规则 - this.reportError(kNAMESPACE_RULE_POSITION); - this.addUnknownAtRule(sheet, token.value); - } - } - else if (token.isAtRule("@font-face")) { - // 如果是 @font-face 规则 - if (this.parseFontFaceRule(token, sheet)) - // 如果解析成功,标记找到样式规则 - foundStyleRules = true; - else - // 解析失败,添加未知的 @ 规则 - this.addUnknownAtRule(sheet, token.value); - } - else if (token.isAtRule("@page")) { - // 如果是 @page 规则 - if (this.parsePageRule(token, sheet)) - // 如果解析成功,标记找到样式规则 - foundStyleRules = true; - else - // 解析失败,添加未知的 @ 规则 - this.addUnknownAtRule(sheet, token.value); - } - else if (token.isAtRule("@media")) { - // 如果是 @media 规则 - if (this.parseMediaRule(token, sheet)) - // 如果解析成功,标记找到样式规则 - foundStyleRules = true; - else - // 解析失败,添加未知的 @ 规则 - this.addUnknownAtRule(sheet, token.value); - } - else if (token.isAtRule("@keyframes")) { - // 如果是 @keyframes 规则 - if (!this.parseKeyframesRule(token, sheet)) - // 如果解析失败,添加未知的 @ 规则 - this.addUnknownAtRule(sheet, token.value); - } - else if (token.isAtRule("@charset")) { - // 如果是 @charset 规则出现在非开头位置,报告错误并添加未知的 @ 规则 - this.reportError(kCHARSET_RULE_CHARSET_SOF); - this.addUnknownAtRule(sheet, token.value); - } - else { - // 未知的 @ 规则,报告错误并添加未知的 @ 规则 - this.reportError(kUNKNOWN_AT_RULE); - this.addUnknownAtRule(sheet, token.value); - } - } - - else // 普通样式规则 - { - // 解析样式规则 - var ruleText = this.parseStyleRule(token, sheet, false); - if (ruleText) - // 如果解析成功,标记找到样式规则 - foundStyleRules = true; - } - // 获取下一个 token - token = this.getToken(false); - } - - return sheet; -} - -}; - -// jscsspToken 构造函数 -// aType: token 的类型 -// aValue: token 的值 -// aUnit: token 的单位 -function jscsspToken(aType, aValue, aUnit) -{ - // 设置 token 的类型 - this.type = aType; - // 设置 token 的值 - this.value = aValue; - // 设置 token 的单位 - this.unit = aUnit; -} - -// 定义 token 的类型 -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 原型对象 -jscsspToken.prototype = { - - // 判断 token 是否不为空的函数 - isNotNull: function () - { - return this.type; - }, - - // 判断 token 是否为指定类型和值的函数 - _isOfType: function (aType, aValue) - { - return (this.type == aType && (!aValue || this.value.toLowerCase() == aValue)); - }, - - // 判断 token 是否为空格的函数 - isWhiteSpace: function(w) - { - return this._isOfType(jscsspToken.WHITESPACE_TYPE, w); - }, - - // 判断 token 是否为字符串的函数 - isString: function() - { - return this._isOfType(jscsspToken.STRING_TYPE); - }, - - // 判断 token 是否为注释的函数 - isComment: function() - { - return this._isOfType(jscsspToken.COMMENT_TYPE); - }, - - // 判断 token 是否为数字的函数 - isNumber: function(n) - { - return this._isOfType(jscsspToken.NUMBER_TYPE, n); - }, - - // 判断 token 是否为符号的函数 - isSymbol: function(c) - { - return this._isOfType(jscsspToken.SYMBOL_TYPE, c); - }, - - // 判断 token 是否为标识符的函数 - isIdent: function(i) - { - return this._isOfType(jscsspToken.IDENT_TYPE, i); - }, - - // 判断 token 是否为函数的函数 - isFunction: function(f) - { - return this._isOfType(jscsspToken.FUNCTION_TYPE, f); - }, - - // 判断 token 是否为 @ 规则的函数 - isAtRule: function(a) - { - return this._isOfType(jscsspToken.ATRULE_TYPE, a); - }, - - // 判断 token 是否为包含操作符的函数 - isIncludes: function() - { - return this._isOfType(jscsspToken.INCLUDES_TYPE); - }, - - // 判断 token 是否为连字符匹配操作符的函数 - isDashmatch: function() - { - return this._isOfType(jscsspToken.DASHMATCH_TYPE); - }, - - // 判断 token 是否为开头匹配操作符的函数 - isBeginsmatch: function() - { - return this._isOfType(jscsspToken.BEGINSMATCH_TYPE); - }, - - // 判断 token 是否为结尾匹配操作符的函数 - isEndsmatch: function() - { - return this._isOfType(jscsspToken.ENDSMATCH_TYPE); - }, - - // 判断 token 是否为包含匹配操作符的函数 - isContainsmatch: function() - { - return this._isOfType(jscsspToken.CONTAINSMATCH_TYPE); - }, - - // 判断 token 是否为符号的函数 - isSymbol: function(c) - { - return this._isOfType(jscsspToken.SYMBOL_TYPE, c); - }, - - // 判断 token 是否为维度的函数 - isDimension: function() - { - return this._isOfType(jscsspToken.DIMENSION_TYPE); - }, - - // 判断 token 是否为百分比的函数 - isPercentage: function() - { - return this._isOfType(jscsspToken.PERCENTAGE_TYPE); - }, - - // 判断 token 是否为十六进制的函数 - isHex: function() - { - return this._isOfType(jscsspToken.HEX_TYPE); - }, - - // 判断 token 是否为指定单位的维度的函数 - isDimensionOfUnit: function(aUnit) - { - return (this.isDimension() && this.unit == aUnit); - }, - - // 判断 token 是否为长度的函数 - 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")); - }, - - // 判断 token 是否为角度的函数 - 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 \ No newline at end of file