/******************************************************************************* * This notice must be untouched at all times. * * CSS Sandpaper: smooths out differences between CSS implementations. * * This javascript library contains routines to implement the CSS transform, * box-shadow and gradient in IE. It also provides a common syntax for other * browsers that support vendor-specific methods. * * Written by: Zoltan Hawryluk. Version 1.0 beta 1 completed on March 8, 2010. * * Some routines are based on code from CSS Gradients via Canvas v1.2 * by Weston Ruter * * Requires sylvester.js by James Coglan http://sylvester.jcoglan.com/ * * cssSandpaper.js v.1.0 beta 1 available at http://www.useragentman.com/ * * released under the MIT License: * http://www.opensource.org/licenses/mit-license.php * ******************************************************************************/ if (!document.querySelectorAll) { document.querySelectorAll = cssQuery; } var cssSandpaper = new function(){ var me = this; var styleNodes, styleSheets = new Array(); var ruleSetRe = /[^\{]*{[^\}]*}/g; var ruleSplitRe = /[\{\}]/g; var reGradient = /gradient\([\s\S]*\)/g; var reHSL = /hsl\([\s\S]*\)/g; // This regexp from the article // http://james.padolsey.com/javascript/javascript-comment-removal-revisted/ var reMultiLineComment = /\/\/.+?(?=\n|\r|$)|\/\*[\s\S]+?\*\//g; var reAtRule = /@[^\{\};]*;|@[^\{\};]*\{[^\}]*\}/g; var reFunctionSpaces = /\(\s*/g var ruleLists = new Array(); var styleNode; var tempObj; var body; me.init = function(reinit){ if (EventHelpers.hasPageLoadHappened(arguments) && !reinit) { return; } body = document.body; tempObj = document.createElement('div'); getStyleSheets(); indexRules(); fixTransforms(); fixBoxShadow(); fixLinearGradients(); fixBackgrounds(); fixColors(); fixOpacity(); setClasses(); //fixBorderRadius(); } me.setOpacity = function(obj, value){ var property = CSS3Helpers.findProperty(document.body, 'opacity'); if (property == "filter") { // IE must have layout, see // http://jszen.blogspot.com/2005/04/ie6-opacity-filter-caveat.html // for details. obj.style.zoom = "100%"; var filter = CSS3Helpers.addFilter(obj, 'DXImageTransform.Microsoft.Alpha', StringHelpers.sprintf("opacity=%d", ((value) * 100))); filter.opacity = value * 100; } else if (obj.style[property] != null) { obj.style[property] = value; } } function fixOpacity(){ var transformRules = getRuleList('opacity').values; for (var i in transformRules) { var rule = transformRules[i]; var nodes = document.querySelectorAll(rule.selector); for (var j = 0; j < nodes.length; j++) { me.setOpacity(nodes[j], rule.value) } } } me.setTransform = function(obj, transformString){ var property = CSS3Helpers.findProperty(obj, 'transform'); if (property == "filter") { var matrix = CSS3Helpers.getTransformationMatrix(transformString); CSS3Helpers.setMatrixFilter(obj, matrix) } else if (obj.style[property] != null) { obj.style[property] = transformString; } } function fixTransforms(){ var transformRules = getRuleList('-sand-transform').values; var property = CSS3Helpers.findProperty(document.body, 'transform'); for (var i in transformRules) { var rule = transformRules[i]; var nodes = document.querySelectorAll(rule.selector); for (var j = 0; j < nodes.length; j++) { me.setTransform(nodes[j], rule.value) } } } me.setBoxShadow = function(obj, value){ var property = CSS3Helpers.findProperty(obj, 'boxShadow'); var values = CSS3Helpers.getBoxShadowValues(value); if (property == "filter") { var filter = CSS3Helpers.addFilter(obj, 'DXImageTransform.Microsoft.DropShadow', StringHelpers.sprintf("color=%s,offX=%d,offY=%d", values.color, values.offsetX, values.offsetY)); filter.color = values.color; filter.offX = values.offsetX; filter.offY = values.offsetY; } else if (obj.style[property] != null) { obj.style[property] = value; } } function fixBoxShadow(){ var transformRules = getRuleList('-sand-box-shadow').values; //var matrices = new Array(); for (var i in transformRules) { var rule = transformRules[i]; var nodes = document.querySelectorAll(rule.selector); for (var j = 0; j < nodes.length; j++) { me.setBoxShadow(nodes[j], rule.value) } } } function setGradientFilter(node, values){ if (values.colorStops.length == 2 && values.colorStops[0].stop == 0.0 && values.colorStops[1].stop == 1.0) { var startColor = new RGBColor(values.colorStops[0].color); var endColor = new RGBColor(values.colorStops[1].color); startColor = startColor.toHex(); endColor = endColor.toHex(); var filter = CSS3Helpers.addFilter(node, 'DXImageTransform.Microsoft.Gradient', StringHelpers.sprintf("GradientType = %s, StartColorStr = '%s', EndColorStr = '%s'", values.IEdir, startColor, endColor)); filter.GradientType = values.IEdir; filter.StartColorStr = startColor; filter.EndColorStr = endColor; node.style.zoom = 1; } } me.setGradient = function(node, value){ var support = CSS3Helpers.reportGradientSupport(); var values = CSS3Helpers.getGradient(value); if (values == null) { return; } if (node.filters) { setGradientFilter(node, values); } else if (support == implementation.MOZILLA) { node.style.backgroundImage = StringHelpers.sprintf('-moz-gradient( %s, %s, from(%s), to(%s))', values.dirBegin, values.dirEnd, values.colorStops[0].color, values.colorStops[1].color); } else if (support == implementation.WEBKIT) { var tmp = StringHelpers.sprintf('-webkit-gradient(%s, %s, %s %s, %s %s)', values.type, values.dirBegin, values.r0 ? values.r0 + ", " : "", values.dirEnd, values.r1 ? values.r1 + ", " : "", listColorStops(values.colorStops)); node.style.backgroundImage = tmp; } else if (support == implementation.CANVAS_WORKAROUND) { try { CSS3Helpers.applyCanvasGradient(node, values); } catch (ex) { // do nothing (for now). } } } me.setRGBABackground = function(node, value){ var support = CSS3Helpers.reportColorSpaceSupport('RGBA', colorType.BACKGROUND); switch (support) { case implementation.NATIVE: node.style.value = value; break; case implementation.FILTER_WORKAROUND: setGradientFilter(node, { IEdir: 0, colorStops: [{ stop: 0.0, color: value }, { stop: 1.0, color: value }] }); break; } } me.setHSLABackground = function(node, value) { var support = CSS3Helpers.reportColorSpaceSupport('HSLA', colorType.BACKGROUND); switch (support) { case implementation.NATIVE: /* node.style.value = value; break; */ case implementation.FILTER_WORKAROUND: var rgbColor = new RGBColor(value); if (rgbColor.a == 1) { node.style.backgroundColor = rgbColor.toHex(); } else { var rgba = rgbColor.toRGBA(); setGradientFilter(node, { IEdir: 0, colorStops: [{ stop: 0.0, color: rgba }, { stop: 1.0, color: rgba }] }); } break; } } /** * Convert a hyphenated string to camelized text. For example, the string "font-type" will be converted * to "fontType". * * @param {Object} s - the string that needs to be camelized. * @return {String} - the camelized text. */ me.camelize = function (s) { var r=""; for (var i=0; i