Server : Apache/2.4.18 (Ubuntu) System : Linux canvaswebdesign 3.13.0-71-generic #114-Ubuntu SMP Tue Dec 1 02:34:22 UTC 2015 x86_64 User : oppastar ( 1041) PHP Version : 7.0.33-0ubuntu0.16.04.15 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority, Directory : /var/www/ptbos.biz/public_html/application/third_party/dompdf/www/cssSandpaper/js/ |
Upload File : |
/******************************************************************************* * 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 <http://weston.ruter.net/projects/css-gradients-via-canvas/> * * 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<s.length; i++) { if (s.substring(i, i+1) == '-') { i++; r+= s.substring(i, i+1).toUpperCase(); } else { r+= s.substring(i, i+1); } } return r; } me.setHSLColor = function (node, property, value) { var support = CSS3Helpers.reportColorSpaceSupport('HSL', colorType.FOREGROUND); switch (support) { case implementation.NATIVE: /* node.style.value = value; break; */ case implementation.HEX_WORKAROUND: var hslColor = value.match(reHSL)[0]; var hexColor = new RGBColor(hslColor).toHex() var newPropertyValue = value.replace(reHSL, hexColor); node.style[me.camelize(property)] = newPropertyValue; break; } } function fixLinearGradients(){ var backgroundRules = getRuleList('background').values.concat(getRuleList('background-image').values); for (var i in backgroundRules) { var rule = backgroundRules[i]; var nodes = document.querySelectorAll(rule.selector); for (var j = 0; j < nodes.length; j++) { me.setGradient(nodes[j], rule.value) } } } function fixBackgrounds(){ var support = CSS3Helpers.reportColorSpaceSupport('RGBA', colorType.BACKGROUND); if (support == implementation.NATIVE) { return; } var backgroundRules = getRuleList('background').values.concat(getRuleList('background-color').values); for (var i in backgroundRules) { var rule = backgroundRules[i]; var nodes = document.querySelectorAll(rule.selector); for (var j = 0; j < nodes.length; j++) { if (rule.value.indexOf('rgba(') == 0) { me.setRGBABackground(nodes[j], rule.value); } else if (rule.value.indexOf('hsla(') == 0 || rule.value.indexOf('hsl(') == 0) { me.setHSLABackground(nodes[j], rule.value); } } } } me.getProperties = function (obj, objName) { var result = "" if (!obj) { return result; } for (var i in obj) { try { result += objName + "." + i.toString() + " = " + obj[i] + ", "; } catch (ex) { // nothing } } return result } function fixColors() { var support = CSS3Helpers.reportColorSpaceSupport('HSL', colorType.FOREGROUND); if (support == implementation.NATIVE) { return; } var colorRules = getRuleList('color').values; var properties = ['color', 'border', 'border-left', 'border-right', 'border-bottom', 'border-top', 'border-left-color', 'border-right-color', 'border-bottom-color', 'border-top-color']; for (var i=0; i<properties.length; i++) { var rules = getRuleList(properties[i]).values; colorRules = colorRules.concat(rules); } for (var i in colorRules) { var rule = colorRules[i]; var nodes = document.querySelectorAll(rule.selector); for (var j = 0; j < nodes.length; j++) { var isBorder = (rule.name.indexOf('border') == 0); var ruleMatch = rule.value.match(reHSL); if (ruleMatch) { var cssProperty; if (isBorder && rule.name.indexOf('-color') < 0) { cssProperty = rule.name; } else { cssProperty = rule.name; } me.setHSLColor(nodes[j], cssProperty, rule.value); } } } } function listColorStops(colorStops){ var sb = new StringBuffer(); for (var i = 0; i < colorStops.length; i++) { sb.append(StringHelpers.sprintf("color-stop(%s, %s)", colorStops[i].stop, colorStops[i].color)); if (i < colorStops.length - 1) { sb.append(', '); } } return sb.toString(); } function getStyleSheet(node){ var sheetCssText; switch (node.nodeName.toLowerCase()) { case 'style': sheetCssText = StringHelpers.uncommentHTML(node.innerHTML); //does not work with inline styles because IE doesn't allow you to get the text content of a STYLE element break; case 'link': var xhr = XMLHelpers.getXMLHttpRequest(node.href, null, "GET", null, false); sheetCssText = xhr.responseText; break; } sheetCssText = sheetCssText.replace(reMultiLineComment, '').replace(reAtRule, ''); return sheetCssText; } function getStyleSheets(){ styleNodes = document.querySelectorAll('style, link[rel="stylesheet"]'); for (var i = 0; i < styleNodes.length; i++) { if (!CSSHelpers.isMemberOfClass(styleNodes[i], 'cssSandpaper-noIndex')) { styleSheets.push(getStyleSheet(styleNodes[i])) } } } function indexRules(){ for (var i = 0; i < styleSheets.length; i++) { var sheet = styleSheets[i]; rules = sheet.match(ruleSetRe); if (rules) { for (var j = 0; j < rules.length; j++) { var parsedRule = rules[j].split(ruleSplitRe); var selector = parsedRule[0].trim(); var propertiesStr = parsedRule[1]; var properties = propertiesStr.split(';'); for (var k = 0; k < properties.length; k++) { if (properties[k].trim() != '') { var splitProperty = properties[k].split(':') var name = splitProperty[0].trim().toLowerCase(); var value = splitProperty[1]; if (!ruleLists[name]) { ruleLists[name] = new RuleList(name); } if (value && typeof(ruleLists[name]) == 'object') { ruleLists[name].add(selector, value.trim()); } } } } } } } function getRuleList(name){ var list = ruleLists[name]; if (!list) { list = new RuleList(name); } return list; } function setClasses(){ var htmlNode = document.getElementsByTagName('html')[0]; var properties = ['transform', 'opacity']; for (var i = 0; i < properties.length; i++) { var prop = properties[i]; if (CSS3Helpers.supports(prop)) { CSSHelpers.addClass(htmlNode, 'cssSandpaper-' + prop); } } // Now .. remove the initially hidden classes var hiddenNodes = CSSHelpers.getElementsByClassName(document, 'cssSandpaper-initiallyHidden'); for (var i=0; i<hiddenNodes.length; i++){ CSSHelpers.removeClass(hiddenNodes[i], 'cssSandpaper-initiallyHidden'); } } } function RuleList(propertyName){ var me = this; me.values = new Array(); me.propertyName = propertyName; me.add = function(selector, value){ me.values.push(new CSSRule(selector, me.propertyName, value)); } } function CSSRule(selector, name, value){ var me = this; me.selector = selector; me.name = name; me.value = value; me.toString = function(){ return StringHelpers.sprintf("%s { %s: %s}", me.selector, me.name, me.value); } } var MatrixGenerator = new function(){ var me = this; var reUnit = /[a-z]+$/; me.identity = $M([[1, 0, 0], [0, 1, 0], [0, 0, 1]]); function degreesToRadians(degrees){ return (degrees - 360) * Math.PI / 180; } function getRadianScalar(angleStr){ var num = parseFloat(angleStr); var unit = angleStr.match(reUnit); if (angleStr.trim() == '0') { num = 0; unit = 'rad'; } if (unit.length != 1 || num == 0) { return 0; } unit = unit[0]; var rad; switch (unit) { case "deg": rad = degreesToRadians(num); break; case "rad": rad = num; break; default: throw "Not an angle: " + angleStr; } return rad; } me.prettyPrint = function(m){ return StringHelpers.sprintf('| %s %s %s | - | %s %s %s | - |%s %s %s|', m.e(1, 1), m.e(1, 2), m.e(1, 3), m.e(2, 1), m.e(2, 2), m.e(2, 3), m.e(3, 1), m.e(3, 2), m.e(3, 3)) } me.rotate = function(angleStr){ var num = getRadianScalar(angleStr); return Matrix.RotationZ(num); } me.scale = function(sx, sy){ sx = parseFloat(sx) if (!sy) { sy = sx; } else { sy = parseFloat(sy) } return $M([[sx, 0, 0], [0, sy, 0], [0, 0, 1]]); } me.scaleX = function(sx){ return me.scale(sx, 1); } me.scaleY = function(sy){ return me.scale(1, sy); } me.skew = function(ax, ay){ var xRad = getRadianScalar(ax); var yRad; if (ay != null) { yRad = getRadianScalar(ay) } else { yRad = xRad } if (xRad != null && yRad != null) { return $M([[1, Math.tan(xRad), 0], [Math.tan(yRad), 1, 0], [0, 0, 1]]); } else { return null; } } me.skewX = function(ax){ return me.skew(ax, "0"); } me.skewY = function(ay){ return me.skew("0", ay); } me.translate = function(tx, ty){ var TX = parseInt(tx); var TY = parseInt(ty) //jslog.debug(StringHelpers.sprintf('translate %f %f', TX, TY)); return $M([[1, 0, TX], [0, 1, TY], [0, 0, 1]]); } me.translateX = function(tx){ return me.translate(tx, 0); } me.translateY = function(ty){ return me.translate(0, ty); } me.matrix = function(a, b, c, d, e, f){ // for now, e and f are ignored return $M([[a, c, parseInt(e)], [b, d, parseInt(f)], [0, 0, 1]]) } } var CSS3Helpers = new function(){ var me = this; var reTransformListSplitter = /[a-zA-Z]+\([^\)]*\)\s*/g; var reLeftBracket = /\(/g; var reRightBracket = /\)/g; var reComma = /,/g; var reSpaces = /\s+/g var reFilterNameSplitter = /progid:([^\(]*)/g; var reLinearGradient var canvas; var cache = new Array(); me.supports = function(cssProperty){ if (CSS3Helpers.findProperty(document.body, cssProperty) != null) { return true; } else { return false; } } me.getCanvas = function(){ if (canvas) { return canvas; } else { canvas = document.createElement('canvas'); return canvas; } } me.getTransformationMatrix = function(CSS3TransformProperty, doThrowIfError){ var transforms = CSS3TransformProperty.match(reTransformListSplitter); /* * Do a check here to see if there is anything in the transformation * besides legit transforms */ if (doThrowIfError) { var checkString = transforms.join(" ").replace(/\s*/g, ' '); var normalizedCSSProp = CSS3TransformProperty.replace(/\s*/g, ' '); if (checkString != normalizedCSSProp) { throw ("An invalid transform was given.") } } var resultantMatrix = MatrixGenerator.identity; for (var j = 0; j < transforms.length; j++) { var transform = transforms[j]; transform = transform.replace(reLeftBracket, '("').replace(reComma, '", "').replace(reRightBracket, '")'); try { var matrix = eval('MatrixGenerator.' + transform); //jslog.debug( transform + ': ' + MatrixGenerator.prettyPrint(matrix)) resultantMatrix = resultantMatrix.x(matrix); } catch (ex) { if (doThrowIfError) { var method = transform.split('(')[0]; var funcCall = transform.replace(/\"/g, ''); if (MatrixGenerator[method] == undefined) { throw "Error: invalid tranform function: " + funcCall; } else { throw "Error: Invalid or missing parameters in function call: " + funcCall; } } // do nothing; } } return resultantMatrix; } me.getBoxShadowValues = function(propertyValue){ var r = new Object(); var values = propertyValue.split(reSpaces); if (values[0] == 'inset') { r.inset = true; values = values.reverse().pop().reverse(); } else { r.inset = false; } r.offsetX = parseInt(values[0]); r.offsetY = parseInt(values[1]); if (values.length > 3) { r.blurRadius = values[2]; if (values.length > 4) { r.spreadRadius = values[3] } } r.color = values[values.length - 1]; return r; } me.getGradient = function(propertyValue){ var r = new Object(); r.colorStops = new Array(); var substring = me.getBracketedSubstring(propertyValue, '-sand-gradient'); if (substring == undefined) { return null; } var parameters = substring.match(/[^\(,]+(\([^\)]*\))?[^,]*/g); //substring.split(reComma); r.type = parameters[0].trim(); if (r.type == 'linear') { r.dirBegin = parameters[1].trim(); r.dirEnd = parameters[2].trim(); var beginCoord = r.dirBegin.split(reSpaces); var endCoord = r.dirEnd.split(reSpaces); for (var i = 3; i < parameters.length; i++) { r.colorStops.push(parseColorStop(parameters[i].trim(), i - 3)); } /* The following logic only applies to IE */ if (document.body.filters) { if (r.x0 == r.x1) { /* IE only supports "center top", "center bottom", "top left" and "top right" */ switch (beginCoord[1]) { case 'top': r.IEdir = 0; break; case 'bottom': swapIndices(r.colorStops, 0, 1); r.IEdir = 0; /* r.from = parameters[4].trim(); r.to = parameters[3].trim(); */ break; } } if (r.y0 == r.y1) { switch (beginCoord[0]) { case 'left': r.IEdir = 1; break; case 'right': r.IEdir = 1; swapIndices(r.colorStops, 0, 1); break; } } } } else { // don't even bother with IE if (document.body.filters) { return null; } r.dirBegin = parameters[1].trim(); r.r0 = parameters[2].trim(); r.dirEnd = parameters[3].trim(); r.r1 = parameters[4].trim(); var beginCoord = r.dirBegin.split(reSpaces); var endCoord = r.dirEnd.split(reSpaces); for (var i = 5; i < parameters.length; i++) { r.colorStops.push(parseColorStop(parameters[i].trim(), i - 5)); } } r.x0 = beginCoord[0]; r.y0 = beginCoord[1]; r.x1 = endCoord[0]; r.y1 = endCoord[1]; return r; } function swapIndices(array, index1, index2){ var tmp = array[index1]; array[index1] = array[index2]; array[index2] = tmp; } function parseColorStop(colorStop, index){ var r = new Object(); var substring = me.getBracketedSubstring(colorStop, 'color-stop'); var from = me.getBracketedSubstring(colorStop, 'from'); var to = me.getBracketedSubstring(colorStop, 'to'); if (substring) { //color-stop var parameters = substring.split(',') r.stop = normalizePercentage(parameters[0].trim()); r.color = parameters[1].trim(); } else if (from) { r.stop = 0.0; r.color = from.trim(); } else if (to) { r.stop = 1.0; r.color = to.trim(); } else { if (index <= 1) { r.color = colorStop; if (index == 0) { r.stop = 0.0; } else { r.stop = 1.0; } } else { throw (StringHelpers.sprintf('invalid argument "%s"', colorStop)); } } return r; } function normalizePercentage(s){ if (s.substring(s.length - 1, s.length) == '%') { return parseFloat(s) / 100 + ""; } else { return s; } } me.reportGradientSupport = function(){ if (!cache["gradientSupport"]) { var r; var div = document.createElement('div'); div.style.cssText = "background-image:-webkit-gradient(linear, 0% 0%, 0% 100%, from(red), to(blue));"; if (div.style.backgroundImage) { r = implementation.WEBKIT; } else { /* div.style.cssText = "background-image:-moz-linear-gradient(top, blue, white 80%, orange);"; if (div.style.backgroundImage) { r = implementation.MOZILLA; } else { */ var canvas = CSS3Helpers.getCanvas(); if (canvas.getContext && canvas.toDataURL) { r = implementation.CANVAS_WORKAROUND; } else { r = implementation.NONE; } /* } */ } cache["gradientSupport"] = r; } return cache["gradientSupport"]; } me.reportColorSpaceSupport = function(colorSpace, type){ if (!cache[colorSpace + type]) { var r; var div = document.createElement('div'); switch (type) { case colorType.BACKGROUND: switch(colorSpace) { case 'RGBA': div.style.cssText = "background-color: rgba(255, 32, 34, 0.5)"; break; case 'HSL': div.style.cssText = "background-color: hsl(0,0%,100%)"; break; case 'HSLA': div.style.cssText = "background-color: hsla(0,0%,100%,.5)"; break; default: break; } var body = document.body; if (div.style.backgroundColor) { r = implementation.NATIVE; } else if (body.filters && body.filters != undefined) { r = implementation.FILTER_WORKAROUND; } else { r = implementation.NONE; } break; case colorType.FOREGROUND: switch(colorSpace) { case 'RGBA': div.style.cssText = "color: rgba(255, 32, 34, 0.5)"; break; case 'HSL': div.style.cssText = "color: hsl(0,0%,100%)"; break; case 'HSLA': div.style.cssText = "color: hsla(0,0%,100%,.5)"; break; default: break; } if (div.style.color) { r = implementation.NATIVE; } else if (colorSpace == 'HSL') { r = implementation.HEX_WORKAROUND; } else { r = implementation.NONE; } break } cache[colorSpace] = r; } return cache[colorSpace]; } me.getBracketedSubstring = function(s, header){ var gradientIndex = s.indexOf(header + '(') if (gradientIndex != -1) { var substring = s.substring(gradientIndex); var openBrackets = 1; for (var i = header.length + 1; i < 100 || i < substring.length; i++) { var c = substring.substring(i, i + 1); switch (c) { case "(": openBrackets++; break; case ")": openBrackets--; break; } if (openBrackets == 0) { break; } } return substring.substring(gradientIndex + header.length + 1, i); } } me.setMatrixFilter = function(obj, matrix){ if (!hasIETransformWorkaround(obj)) { addIETransformWorkaround(obj) } var container = obj.parentNode; //container.xTransform = degrees; filter = obj.filters.item('DXImageTransform.Microsoft.Matrix'); //jslog.debug(MatrixGenerator.prettyPrint(matrix)) filter.M11 = matrix.e(1, 1); filter.M12 = matrix.e(1, 2); filter.M21 = matrix.e(2, 1); filter.M22 = matrix.e(2, 2); // Now, adjust the margins of the parent object var offsets = me.getIEMatrixOffsets(obj, matrix, container.xOriginalWidth, container.xOriginalHeight); container.style.marginLeft = offsets.x; container.style.marginTop = offsets.y; container.style.marginRight = 0; container.style.marginBottom = 0; } me.getTransformedDimensions = function (obj, matrix) { var r = {}; if (hasIETransformWorkaround(obj)) { r.width = obj.offsetWidth; r.height = obj.offsetHeight; } else { var pts = [ matrix.x($V([0, 0, 1])) , matrix.x($V([0, obj.offsetHeight, 1])), matrix.x($V([obj.offsetWidth, 0, 1])), matrix.x($V([obj.offsetWidth, obj.offsetHeight, 1])) ]; var maxX = 0, maxY =0, minX=0, minY=0; for (var i = 0; i < pts.length; i++) { var pt = pts[i]; var x = pt.e(1), y = pt.e(2); var minX = Math.min(minX, x); var maxX = Math.max(maxX, x); var minY = Math.min(minY, y); var maxY = Math.max(maxY, y); } r.width = maxX - minX; r.height = maxY - minY; } return r; } me.getIEMatrixOffsets = function (obj, matrix, width, height) { var r = {}; var originalWidth = parseFloat(width); var originalHeight = parseFloat(height); var offset; if (CSSHelpers.getComputedStyle(obj, 'display') == 'inline') { offset = 0; } else { offset = 13; // This works ... don't know why. } var transformedDimensions = me.getTransformedDimensions(obj, matrix); r.x = (((originalWidth - transformedDimensions.width) / 2) - offset + matrix.e(1, 3)) + 'px'; r.y = (((originalHeight - transformedDimensions.height) / 2) - offset + matrix.e(2, 3)) + 'px'; return r; } function hasIETransformWorkaround(obj){ return CSSHelpers.isMemberOfClass(obj.parentNode, 'IETransformContainer'); } function addIETransformWorkaround(obj){ if (!hasIETransformWorkaround(obj)) { var parentNode = obj.parentNode; var filter; // This is the container to offset the strange rotation behavior var container = document.createElement('div'); CSSHelpers.addClass(container, 'IETransformContainer'); container.style.width = obj.offsetWidth + 'px'; container.style.height = obj.offsetHeight + 'px'; container.xOriginalWidth = obj.offsetWidth; container.xOriginalHeight = obj.offsetHeight; container.style.position = 'absolute' container.style.zIndex = obj.currentStyle.zIndex; var horizPaddingFactor = 0; //parseInt(obj.currentStyle.paddingLeft); var vertPaddingFactor = 0; //parseInt(obj.currentStyle.paddingTop); if (obj.currentStyle.display == 'block') { container.style.left = obj.offsetLeft + 13 - horizPaddingFactor + "px"; container.style.top = obj.offsetTop + 13 + -vertPaddingFactor + 'px'; } else { container.style.left = obj.offsetLeft + "px"; container.style.top = obj.offsetTop + 'px'; } //container.style.float = obj.currentStyle.float; obj.style.top = "auto"; obj.style.left = "auto" obj.style.bottom = "auto"; obj.style.right = "auto"; // This is what we need in order to insert to keep the document // flow ok var replacement = obj.cloneNode(true); replacement.style.visibility = 'hidden'; obj.replaceNode(replacement); // now, wrap container around the original node ... obj.style.position = 'absolute'; container.appendChild(obj); parentNode.insertBefore(container, replacement); container.style.backgroundColor = 'transparent'; container.style.padding = '0'; filter = me.addFilter(obj, 'DXImageTransform.Microsoft.Matrix', "M11=1, M12=0, M21=0, M22=1, sizingMethod='auto expand'") var bgImage = obj.currentStyle.backgroundImage.split("\"")[1]; /* if (bgImage) { var alphaFilter = me.addFilter(obj, "DXImageTransform.Microsoft.AlphaImageLoader", "src='" + bgImage + "', sizingMethod='scale'"); alert(bgImage) alphaFilter.src = bgImage; sizingMethod = 'scale'; obj.style.background = 'none'; obj.style.backgroundImage = 'none'; } */ } } me.addFilter = function(obj, filterName, filterValue){ // now ... insert the filter so we can exploit its wonders var filter; try { filter = obj.filters.item(filterName); } catch (ex) { // dang! We have to go through all of them and make sure filter // is set right before we add the new one. var filterList = new MSFilterList(obj) filterList.fixFilterStyle(); var comma = ", "; if (obj.filters.length == 0) { comma = ""; } obj.style.filter += StringHelpers.sprintf("%sprogid:%s(%s)", comma, filterName, filterValue); filter = obj.filters.item(filterName); } return filter; } function degreesToRadians(degrees){ return (degrees - 360) * Math.PI / 180; } me.findProperty = function(obj, type){ capType = type.capitalize(); var r = cache[type] if (!r) { var style = obj.style; var properties = [type, 'Moz' + capType, 'Webkit' + capType, 'O' + capType, 'filter']; for (var i = 0; i < properties.length; i++) { if (style[properties[i]] != null) { r = properties[i]; break; } } if (r == 'filter' && document.body.filters == undefined) { r = null; } cache[type] = r; } return r; } /* * "A point is a pair of space-separated values. The syntax supports numbers, * percentages or the keywords top, bottom, left and right for point values." * This keywords and percentages into pixel equivalents */ me.parseCoordinate = function(value, max){ //Convert keywords switch (value) { case 'top': case 'left': return 0; case 'bottom': case 'right': return max; case 'center': return max / 2; } //Convert percentage if (value.indexOf('%') != -1) value = parseFloat(value.substr(0, value.length - 1)) / 100 * max; //Convert bare number (a pixel value) else value = parseFloat(value); if (isNaN(value)) throw Error("Unable to parse coordinate: " + value); return value; } me.applyCanvasGradient = function(el, gradient){ var canvas = me.getCanvas(); var computedStyle = document.defaultView.getComputedStyle(el, null); canvas.width = parseInt(computedStyle.width) + parseInt(computedStyle.paddingLeft) + parseInt(computedStyle.paddingRight) + 1; // inserted by Zoltan canvas.height = parseInt(computedStyle.height) + parseInt(computedStyle.paddingTop) + parseInt(computedStyle.paddingBottom) + 2; // 1 inserted by Zoltan var ctx = canvas.getContext('2d'); //Iterate over the gradients and build them up var canvasGradient; // Linear gradient if (gradient.type == 'linear') { canvasGradient = ctx.createLinearGradient(me.parseCoordinate(gradient.x0, canvas.width), me.parseCoordinate(gradient.y0, canvas.height), me.parseCoordinate(gradient.x1, canvas.width), me.parseCoordinate(gradient.y1, canvas.height)); } // Radial gradient else /*if(gradient.type == 'radial')*/ { canvasGradient = ctx.createRadialGradient(me.parseCoordinate(gradient.x0, canvas.width), me.parseCoordinate(gradient.y0, canvas.height), gradient.r0, me.parseCoordinate(gradient.x1, canvas.width), me.parseCoordinate(gradient.y1, canvas.height), gradient.r1); } //Add each of the color stops to the gradient for (var i = 0; i < gradient.colorStops.length; i++) { var cs = gradient.colorStops[i]; canvasGradient.addColorStop(cs.stop, cs.color); }; //Paint the gradient ctx.fillStyle = canvasGradient; ctx.fillRect(0, 0, canvas.width, canvas.height); //Apply the gradient to the selectedElement el.style.backgroundImage = "url('" + canvas.toDataURL() + "')"; } } function MSFilterList(node){ var me = this; me.list = new Array(); me.node = node; var reFilterListSplitter = /[\s\S]*\([\s\S]*\)/g; var styleAttr = node.style; function init(){ var filterCalls = styleAttr.filter.match(reFilterListSplitter); if (filterCalls != null) { for (var i = 0; i < filterCalls.length; i++) { var call = filterCalls[i]; me.list.push(new MSFilter(node, call)); } } } me.toString = function(){ var sb = new StringBuffer(); for (var i = 0; i < me.list.length; i++) { sb.append(me.list[i].toString()); if (i < me.list.length - 1) { sb.append(',') } } return sb.toString(); } me.fixFilterStyle = function(){ try { me.node.style.filter = me.toString(); } catch (ex) { // do nothing. } } init(); } function MSFilter(node, filterCall){ var me = this; me.node = node; me.filterCall = filterCall; var reFilterNameSplitter = /progid:([^\(]*)/g; var reParameterName = /([a-zA-Z0-9]+\s*)=/g; function init(){ me.name = me.filterCall.match(reFilterNameSplitter)[0].replace('progid:', ''); //This may not be the best way to do this. var parameterString = filterCall.split('(')[1].replace(')', ''); me.parameters = parameterString.match(reParameterName); for (var i = 0; i < me.parameters.length; i++) { me.parameters[i] = me.parameters[i].replace('=', ''); } } me.toString = function(){ var sb = new StringBuffer(); sb.append(StringHelpers.sprintf('progid:%s(', me.name)); for (var i = 0; i < me.parameters.length; i++) { var param = me.parameters[i]; var filterObj = me.node.filters.item(me.name); var paramValue = filterObj[param]; if (typeof(paramValue) == 'string') { sb.append(StringHelpers.sprintf('%s="%s"', param, filterObj[param])); } else { sb.append(StringHelpers.sprintf('%s=%s', param, filterObj[param])); } if (i != me.parameters.length - 1) { sb.append(', ') } } sb.append(')'); return sb.toString(); } init(); } var implementation = new function(){ this.NONE = 0; // Native Support. this.NATIVE = 1; // Vendor specific prefix implementations this.MOZILLA = 2; this.WEBKIT = 3; this.IE = 4; this.OPERA = 5; // Non CSS3 Workarounds this.CANVAS_WORKAROUND = 6; this.FILTER_WORKAROUND = 7; this.HEX_WORKAROUND = 8; } var colorType = new function () { this.BACKGROUND = 0; this.FOREGROUND = 1; } /* * Extra helper routines */ if (!window.StringHelpers) { StringHelpers = new function(){ var me = this; // used by the String.prototype.trim() me.initWhitespaceRe = /^\s\s*/; me.endWhitespaceRe = /\s\s*$/; me.whitespaceRe = /\s/; /******************************************************************************* * Function sprintf(format_string,arguments...) Javascript emulation of the C * printf function (modifiers and argument types "p" and "n" are not supported * due to language restrictions) * * Copyright 2003 K&L Productions. All rights reserved * http://www.klproductions.com * * Terms of use: This function can be used free of charge IF this header is not * modified and remains with the function code. * * Legal: Use this code at your own risk. K&L Productions assumes NO * resposibility for anything. ******************************************************************************/ me.sprintf = function(fstring){ var pad = function(str, ch, len){ var ps = ''; for (var i = 0; i < Math.abs(len); i++) ps += ch; return len > 0 ? str + ps : ps + str; } var processFlags = function(flags, width, rs, arg){ var pn = function(flags, arg, rs){ if (arg >= 0) { if (flags.indexOf(' ') >= 0) rs = ' ' + rs; else if (flags.indexOf('+') >= 0) rs = '+' + rs; } else rs = '-' + rs; return rs; } var iWidth = parseInt(width, 10); if (width.charAt(0) == '0') { var ec = 0; if (flags.indexOf(' ') >= 0 || flags.indexOf('+') >= 0) ec++; if (rs.length < (iWidth - ec)) rs = pad(rs, '0', rs.length - (iWidth - ec)); return pn(flags, arg, rs); } rs = pn(flags, arg, rs); if (rs.length < iWidth) { if (flags.indexOf('-') < 0) rs = pad(rs, ' ', rs.length - iWidth); else rs = pad(rs, ' ', iWidth - rs.length); } return rs; } var converters = new Array(); converters['c'] = function(flags, width, precision, arg){ if (typeof(arg) == 'number') return String.fromCharCode(arg); if (typeof(arg) == 'string') return arg.charAt(0); return ''; } converters['d'] = function(flags, width, precision, arg){ return converters['i'](flags, width, precision, arg); } converters['u'] = function(flags, width, precision, arg){ return converters['i'](flags, width, precision, Math.abs(arg)); } converters['i'] = function(flags, width, precision, arg){ var iPrecision = parseInt(precision); var rs = ((Math.abs(arg)).toString().split('.'))[0]; if (rs.length < iPrecision) rs = pad(rs, ' ', iPrecision - rs.length); return processFlags(flags, width, rs, arg); } converters['E'] = function(flags, width, precision, arg){ return (converters['e'](flags, width, precision, arg)).toUpperCase(); } converters['e'] = function(flags, width, precision, arg){ iPrecision = parseInt(precision); if (isNaN(iPrecision)) iPrecision = 6; rs = (Math.abs(arg)).toExponential(iPrecision); if (rs.indexOf('.') < 0 && flags.indexOf('#') >= 0) rs = rs.replace(/^(.*)(e.*)$/, '$1.$2'); return processFlags(flags, width, rs, arg); } converters['f'] = function(flags, width, precision, arg){ iPrecision = parseInt(precision); if (isNaN(iPrecision)) iPrecision = 6; rs = (Math.abs(arg)).toFixed(iPrecision); if (rs.indexOf('.') < 0 && flags.indexOf('#') >= 0) rs = rs + '.'; return processFlags(flags, width, rs, arg); } converters['G'] = function(flags, width, precision, arg){ return (converters['g'](flags, width, precision, arg)).toUpperCase(); } converters['g'] = function(flags, width, precision, arg){ iPrecision = parseInt(precision); absArg = Math.abs(arg); rse = absArg.toExponential(); rsf = absArg.toFixed(6); if (!isNaN(iPrecision)) { rsep = absArg.toExponential(iPrecision); rse = rsep.length < rse.length ? rsep : rse; rsfp = absArg.toFixed(iPrecision); rsf = rsfp.length < rsf.length ? rsfp : rsf; } if (rse.indexOf('.') < 0 && flags.indexOf('#') >= 0) rse = rse.replace(/^(.*)(e.*)$/, '$1.$2'); if (rsf.indexOf('.') < 0 && flags.indexOf('#') >= 0) rsf = rsf + '.'; rs = rse.length < rsf.length ? rse : rsf; return processFlags(flags, width, rs, arg); } converters['o'] = function(flags, width, precision, arg){ var iPrecision = parseInt(precision); var rs = Math.round(Math.abs(arg)).toString(8); if (rs.length < iPrecision) rs = pad(rs, ' ', iPrecision - rs.length); if (flags.indexOf('#') >= 0) rs = '0' + rs; return processFlags(flags, width, rs, arg); } converters['X'] = function(flags, width, precision, arg){ return (converters['x'](flags, width, precision, arg)).toUpperCase(); } converters['x'] = function(flags, width, precision, arg){ var iPrecision = parseInt(precision); arg = Math.abs(arg); var rs = Math.round(arg).toString(16); if (rs.length < iPrecision) rs = pad(rs, ' ', iPrecision - rs.length); if (flags.indexOf('#') >= 0) rs = '0x' + rs; return processFlags(flags, width, rs, arg); } converters['s'] = function(flags, width, precision, arg){ var iPrecision = parseInt(precision); var rs = arg; if (rs.length > iPrecision) rs = rs.substring(0, iPrecision); return processFlags(flags, width, rs, 0); } farr = fstring.split('%'); retstr = farr[0]; fpRE = /^([-+ #]*)(\d*)\.?(\d*)([cdieEfFgGosuxX])(.*)$/; for (var i = 1; i < farr.length; i++) { fps = fpRE.exec(farr[i]); if (!fps) continue; if (arguments[i] != null) retstr += converters[fps[4]](fps[1], fps[2], fps[3], arguments[i]); retstr += fps[5]; } return retstr; } /** * Take out the first comment inside a block of HTML * * @param {String} s - an HTML block * @return {String} s - the HTML block uncommented. */ me.uncommentHTML = function(s){ if (s.indexOf('-->') != -1 && s.indexOf('<!--') != -1) { return s.replace("<!--", "").replace("-->", ""); } else { return s; } } } } if (!window.XMLHelpers) { XMLHelpers = new function(){ var me = this; /** * Wrapper for XMLHttpRequest Object. Grabbing data (XML and/or text) from a URL. * Grabbing data from a URL. Input is one parameter, url. It returns a request * object. Based on code from * http://www.xml.com/pub/a/2005/02/09/xml-http-request.html. IE caching problem * fix from Wikipedia article http://en.wikipedia.org/wiki/XMLHttpRequest * * @param {String} url - the URL to retrieve * @param {Function} processReqChange - the function/method to call at key events of the URL retrieval. * @param {String} method - (optional) "GET" or "POST" (default "GET") * @param {String} data - (optional) the CGI data to pass. Default null. * @param {boolean} isAsync - (optional) is this call asyncronous. Default true. * * @return {Object} a XML request object. */ me.getXMLHttpRequest = function(url, processReqChange) //, method, data, isAsync) { var argv = me.getXMLHttpRequest.arguments; var argc = me.getXMLHttpRequest.arguments.length; var httpMethod = (argc > 2) ? argv[2] : 'GET'; var data = (argc > 3) ? argv[3] : ""; var isAsync = (argc > 4) ? argv[4] : true; var req; // branch for native XMLHttpRequest object if (window.XMLHttpRequest) { req = new XMLHttpRequest(); // branch for IE/Windows ActiveX version } else if (window.ActiveXObject) { try { req = new ActiveXObject('Msxml2.XMLHTTP'); } catch (ex) { req = new ActiveXObject("Microsoft.XMLHTTP"); } // the browser doesn't support XML HttpRequest. Return null; } else { return null; } if (isAsync) { req.onreadystatechange = processReqChange; } if (httpMethod == "GET" && data != "") { url += "?" + data; } req.open(httpMethod, url, isAsync); //Fixes IE Caching problem req.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT"); req.send(data); return req; } } } if (!window.CSSHelpers) { CSSHelpers = new function(){ var me = this; var blankRe = new RegExp('\\s'); /* * getComputedStyle: code from http://blog.stchur.com/2006/06/21/css-computed-style/ */ me.getComputedStyle = function(elem, style) { var computedStyle; if (typeof elem.currentStyle != 'undefined') { computedStyle = elem.currentStyle; } else { computedStyle = document.defaultView.getComputedStyle(elem, null); } return computedStyle[style]; } /** * Determines if an HTML object is a member of a specific class. * @param {Object} obj - an HTML object. * @param {Object} className - the CSS class name. */ me.isMemberOfClass = function(obj, className){ if (blankRe.test(className)) return false; var re = new RegExp(getClassReString(className), "g"); return (re.test(obj.className)); } /** * Make an HTML object be a member of a certain class. * * @param {Object} obj - an HTML object * @param {String} className - a CSS class name. */ me.addClass = function(obj, className){ if (blankRe.test(className)) { return; } // only add class if the object is not a member of it yet. if (!me.isMemberOfClass(obj, className)) { obj.className += " " + className; } } /** * Make an HTML object *not* be a member of a certain class. * * @param {Object} obj - an HTML object * @param {Object} className - a CSS class name. */ me.removeClass = function(obj, className){ if (blankRe.test(className)) { return; } var re = new RegExp(getClassReString(className), "g"); var oldClassName = obj.className; if (obj.className) { obj.className = oldClassName.replace(re, ''); } } function getClassReString(className) { return '\\s'+className+'\\s|^' + className + '\\s|\\s' + className + '$|' + '^' + className +'$'; } /** * Given an HTML element, find all child nodes of a specific class. * * With ideas from Jonathan Snook * (http://snook.ca/archives/javascript/your_favourite_1/) * Since this was presented within a post on this site, it is for the * public domain according to the site's copyright statement. * * @param {Object} obj - an HTML element. If you want to search a whole document, set * this to the document object. * @param {String} className - the class name of the objects to return * @return {Array} - the list of objects of class cls. */ me.getElementsByClassName = function (obj, className) { if (obj.getElementsByClassName) { return DOMHelpers.nodeListToArray(obj.getElementsByClassName(className)) } else { var a = []; var re = new RegExp(getClassReString(className)); var els = DOMHelpers.getAllDescendants(obj); for (var i = 0, j = els.length; i < j; i++) { if (re.test(els[i].className)) { a.push(els[i]); } } return a; } } /** * Generates a regular expression string that can be used to detect a class name * in a tag's class attribute. It is used by a few methods, so I * centralized it. * * @param {String} className - a name of a CSS class. */ function getClassReString(className){ return '\\s' + className + '\\s|^' + className + '\\s|\\s' + className + '$|' + '^' + className + '$'; } } } /* * Adding trim method to String Object. Ideas from * http://www.faqts.com/knowledge_base/view.phtml/aid/1678/fid/1 and * http://blog.stevenlevithan.com/archives/faster-trim-javascript */ String.prototype.trim = function(){ var str = this; // The first method is faster on long strings than the second and // vice-versa. if (this.length > 6000) { str = this.replace(StringHelpers.initWhitespaceRe, ''); var i = str.length; while (StringHelpers.whitespaceRe.test(str.charAt(--i))) ; return str.slice(0, i + 1); } else { return this.replace(StringHelpers.initWhitespaceRe, '').replace(StringHelpers.endWhitespaceRe, ''); } }; if (!window.DOMHelpers) { DOMHelpers = new function () { var me = this; /** * Returns all children of an element. Needed if it is necessary to do * the equivalent of getElementsByTagName('*') for IE5 for Windows. * * @param {Object} e - an HTML object. */ me.getAllDescendants = function(obj) { return obj.all ? obj.all : obj.getElementsByTagName('*'); } /****** * Converts a DOM live node list to a static/dead array. Good when you don't * want the thing you are iterating in a for loop changing as the DOM changes. * * @param {Object} nodeList - a node list (like one returned by document.getElementsByTagName) * @return {Array} - an array of nodes. * *******/ me.nodeListToArray = function (nodeList) { var ary = []; for(var i=0, len = nodeList.length; i < len; i++) { ary.push(nodeList[i]); } return ary; } } } //+ Jonas Raoni Soares Silva //@ http://jsfromhell.com/string/capitalize [v1.0] String.prototype.capitalize = function(){ //v1.0 return this.charAt(0).toUpperCase() + this.substr(1); }; /* * stringBuffer.js - ideas from * http://www.multitask.com.au/people/dion/archives/000354.html */ function StringBuffer(){ var me = this; var buffer = []; me.append = function(string){ buffer.push(string); return me; } me.appendBuffer = function(bufferToAppend){ buffer = buffer.concat(bufferToAppend); } me.toString = function(){ return buffer.join(""); } me.getLength = function(){ return buffer.length; } me.flush = function(){ buffer.length = 0; } } /** * A class to parse color values * @author Stoyan Stefanov <sstoo@gmail.com> (with modifications) * @link http://www.phpied.com/rgb-color-parser-in-javascript/ * @license Use it if you like it */ function RGBColor(color_string){ var me = this; me.ok = false; // strip any leading # if (color_string.charAt(0) == '#') { // remove # if any color_string = color_string.substr(1, 6); } color_string = color_string.replace(/ /g, ''); color_string = color_string.toLowerCase(); // before getting into regexps, try simple matches // and overwrite the input var simple_colors = { aliceblue: 'f0f8ff', antiquewhite: 'faebd7', aqua: '00ffff', aquamarine: '7fffd4', azure: 'f0ffff', beige: 'f5f5dc', bisque: 'ffe4c4', black: '000000', blanchedalmond: 'ffebcd', blue: '0000ff', blueviolet: '8a2be2', brown: 'a52a2a', burlywood: 'deb887', cadetblue: '5f9ea0', chartreuse: '7fff00', chocolate: 'd2691e', coral: 'ff7f50', cornflowerblue: '6495ed', cornsilk: 'fff8dc', crimson: 'dc143c', cyan: '00ffff', darkblue: '00008b', darkcyan: '008b8b', darkgoldenrod: 'b8860b', darkgray: 'a9a9a9', darkgreen: '006400', darkkhaki: 'bdb76b', darkmagenta: '8b008b', darkolivegreen: '556b2f', darkorange: 'ff8c00', darkorchid: '9932cc', darkred: '8b0000', darksalmon: 'e9967a', darkseagreen: '8fbc8f', darkslateblue: '483d8b', darkslategray: '2f4f4f', darkturquoise: '00ced1', darkviolet: '9400d3', deeppink: 'ff1493', deepskyblue: '00bfff', dimgray: '696969', dodgerblue: '1e90ff', feldspar: 'd19275', firebrick: 'b22222', floralwhite: 'fffaf0', forestgreen: '228b22', fuchsia: 'ff00ff', gainsboro: 'dcdcdc', ghostwhite: 'f8f8ff', gold: 'ffd700', goldenrod: 'daa520', gray: '808080', green: '008000', greenyellow: 'adff2f', honeydew: 'f0fff0', hotpink: 'ff69b4', indianred: 'cd5c5c', indigo: '4b0082', ivory: 'fffff0', khaki: 'f0e68c', lavender: 'e6e6fa', lavenderblush: 'fff0f5', lawngreen: '7cfc00', lemonchiffon: 'fffacd', lightblue: 'add8e6', lightcoral: 'f08080', lightcyan: 'e0ffff', lightgoldenrodyellow: 'fafad2', lightgrey: 'd3d3d3', lightgreen: '90ee90', lightpink: 'ffb6c1', lightsalmon: 'ffa07a', lightseagreen: '20b2aa', lightskyblue: '87cefa', lightslateblue: '8470ff', lightslategray: '778899', lightsteelblue: 'b0c4de', lightyellow: 'ffffe0', lime: '00ff00', limegreen: '32cd32', linen: 'faf0e6', magenta: 'ff00ff', maroon: '800000', mediumaquamarine: '66cdaa', mediumblue: '0000cd', mediumorchid: 'ba55d3', mediumpurple: '9370d8', mediumseagreen: '3cb371', mediumslateblue: '7b68ee', mediumspringgreen: '00fa9a', mediumturquoise: '48d1cc', mediumvioletred: 'c71585', midnightblue: '191970', mintcream: 'f5fffa', mistyrose: 'ffe4e1', moccasin: 'ffe4b5', navajowhite: 'ffdead', navy: '000080', oldlace: 'fdf5e6', olive: '808000', olivedrab: '6b8e23', orange: 'ffa500', orangered: 'ff4500', orchid: 'da70d6', palegoldenrod: 'eee8aa', palegreen: '98fb98', paleturquoise: 'afeeee', palevioletred: 'd87093', papayawhip: 'ffefd5', peachpuff: 'ffdab9', peru: 'cd853f', pink: 'ffc0cb', plum: 'dda0dd', powderblue: 'b0e0e6', purple: '800080', red: 'ff0000', rosybrown: 'bc8f8f', royalblue: '4169e1', saddlebrown: '8b4513', salmon: 'fa8072', sandybrown: 'f4a460', seagreen: '2e8b57', seashell: 'fff5ee', sienna: 'a0522d', silver: 'c0c0c0', skyblue: '87ceeb', slateblue: '6a5acd', slategray: '708090', snow: 'fffafa', springgreen: '00ff7f', steelblue: '4682b4', tan: 'd2b48c', teal: '008080', metle: 'd8bfd8', tomato: 'ff6347', turquoise: '40e0d0', violet: 'ee82ee', violetred: 'd02090', wheat: 'f5deb3', white: 'ffffff', whitesmoke: 'f5f5f5', yellow: 'ffff00', yellowgreen: '9acd32' }; for (var key in simple_colors) { if (color_string == key) { color_string = simple_colors[key]; } } // emd of simple type-in colors // array of color definition objects var color_defs = [{ re: /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/, example: ['rgb(123, 234, 45)', 'rgb(255,234,245)'], process: function(bits){ return [parseInt(bits[1]), parseInt(bits[2]), parseInt(bits[3])]; } }, { re: /^(\w{2})(\w{2})(\w{2})$/, example: ['#00ff00', '336699'], process: function(bits){ return [parseInt(bits[1], 16), parseInt(bits[2], 16), parseInt(bits[3], 16)]; } }, { re: /^(\w{1})(\w{1})(\w{1})$/, example: ['#fb0', 'f0f'], process: function(bits){ return [parseInt(bits[1] + bits[1], 16), parseInt(bits[2] + bits[2], 16), parseInt(bits[3] + bits[3], 16)]; } }, { re: /^rgba\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3}),\s*(0{0,1}\.\d{1,}|0\.{0,}0*|1\.{0,}0*)\)$/, example: ['rgba(123, 234, 45, 22)', 'rgba(255, 234,245, 34)'], process: function(bits){ return [parseInt(bits[1]), parseInt(bits[2]), parseInt(bits[3]), parseFloat(bits[4])]; } }, { re: /^hsla\((\d{1,3}),\s*(\d{1,3}%),\s*(\d{1,3}%),\s*(0{0,1}\.\d{1,}|0\.{0,}0*|1\.{0,}0*)\)$/, example: ['hsla(0,100%,50%,0.2)'], process: function(bits){ var result = hsl2rgb(parseInt(bits[1]), parseInt(bits[2]), parseInt(bits[3]), parseFloat(bits[4])); return [result.r, result.g, result.b, parseFloat(bits[4])]; } }, { re: /^hsl\((\d{1,3}),\s*(\d{1,3}%),\s*(\d{1,3}%)\)$/, example: ['hsl(0,100%,50%)'], process: function(bits){ var result = hsl2rgb(parseInt(bits[1]), parseInt(bits[2]), parseInt(bits[3]), 1); return [result.r, result.g, result.b, 1]; } }]; // search through the definitions to find a match for (var i = 0; i < color_defs.length; i++) { var re = color_defs[i].re; var processor = color_defs[i].process; var bits = re.exec(color_string); if (bits) { channels = processor(bits); me.r = channels[0]; me.g = channels[1]; me.b = channels[2]; me.a = channels[3]; me.ok = true; } } // validate/cleanup values me.r = (me.r < 0 || isNaN(me.r)) ? 0 : ((me.r > 255) ? 255 : me.r); me.g = (me.g < 0 || isNaN(me.g)) ? 0 : ((me.g > 255) ? 255 : me.g); me.b = (me.b < 0 || isNaN(me.b)) ? 0 : ((me.b > 255) ? 255 : me.b); me.a = (isNaN(me.a)) ? 1 : ((me.a > 255) ? 255 : (me.a < 0) ? 0 : me.a); // some getters me.toRGB = function(){ return 'rgb(' + me.r + ', ' + me.g + ', ' + me.b + ')'; } // some getters me.toRGBA = function(){ return 'rgba(' + me.r + ', ' + me.g + ', ' + me.b + ', ' + me.a + ')'; } /** * Converts an RGB color value to HSV. Conversion formula * adapted from http://en.wikipedia.org/wiki/HSV_color_space. * Assumes r, g, and b are contained in the set [0, 255] and * returns h, s, and v in the set [0, 1]. * * This routine by Michael Jackson (not *that* one), * from http://www.mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript * * @param Number r The red color value * @param Number g The green color value * @param Number b The blue color value * @return Array The HSV representation */ me.toHSV = function(){ var r = me.r / 255, g = me.g / 255, b = me.b / 255; var max = Math.max(r, g, b), min = Math.min(r, g, b); var h, s, v = max; var d = max - min; s = max == 0 ? 0 : d / max; if (max == min) { h = 0; // achromatic } else { switch (max) { case r: h = (g - b) / d + (g < b ? 6 : 0); break; case g: h = (b - r) / d + 2; break; case b: h = (r - g) / d + 4; break; } h /= 6; } return { h: h, s: s, v: v }; } /* * hsl2rgb from http://codingforums.com/showthread.php?t=11156 * code by Jason Karl Davis (http://www.jasonkarldavis.com) */ function hsl2rgb(h, s, l) { var m1, m2, hue; var r, g, b s /=100; l /= 100; if (s == 0) r = g = b = (l * 255); else { if (l <= 0.5) m2 = l * (s + 1); else m2 = l + s - l * s; m1 = l * 2 - m2; hue = h / 360; r = HueToRgb(m1, m2, hue + 1/3); g = HueToRgb(m1, m2, hue); b = HueToRgb(m1, m2, hue - 1/3); } return {r: Math.round(r), g: Math.round(g), b: Math.round(b)}; } function HueToRgb(m1, m2, hue) { var v; if (hue < 0) hue += 1; else if (hue > 1) hue -= 1; if (6 * hue < 1) v = m1 + (m2 - m1) * hue * 6; else if (2 * hue < 1) v = m2; else if (3 * hue < 2) v = m1 + (m2 - m1) * (2/3 - hue) * 6; else v = m1; return 255 * v; } me.toHex = function(){ var r = me.r.toString(16); var g = me.g.toString(16); var b = me.b.toString(16); var a = Math.floor((me.a * 255)).toString(16); if (r.length == 1) r = '0' + r; if (g.length == 1) g = '0' + g; if (b.length == 1) b = '0' + b; if (a == 'ff') { a = ''; } else if (a.length == 1) { a = '0' + a; } return '#' + a + r + g + b; } } document.write('<style type="text/css">.cssSandpaper-initiallyHidden { visibility: hidden;} </style>'); EventHelpers.addPageLoadEvent('cssSandpaper.init')