From 89bda83e0570ab87c6e449f5955613d5385e90b3 Mon Sep 17 00:00:00 2001 From: "alexanders@b2ef00c0-3703-41da-baef-cfe82387ac0c" Date: Wed, 3 Feb 2010 00:50:41 +0000 Subject: removed obsolete svn folder from hg tree --HG-- extra : convert_revision : svn%3Ab2ef00c0-3703-41da-baef-cfe82387ac0c/trunk%408 --- .../platform/yui/compressor/CssCompressor.java | 188 +++++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/CssCompressor.java (limited to 'infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/CssCompressor.java') diff --git a/infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/CssCompressor.java b/infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/CssCompressor.java new file mode 100644 index 0000000..68b4de9 --- /dev/null +++ b/infrastructure/yuicompressor/src/com/yahoo/platform/yui/compressor/CssCompressor.java @@ -0,0 +1,188 @@ +/* + * YUI Compressor + * Author: Julien Lecomte + * Copyright (c) 2007, Yahoo! Inc. All rights reserved. + * Code licensed under the BSD License: + * http://developer.yahoo.net/yui/license.txt + * + * This code is a port of Isaac Schlueter's cssmin utility. + */ + +package com.yahoo.platform.yui.compressor; + +import java.io.IOException; +import java.io.Reader; +import java.io.Writer; +import java.util.regex.Pattern; +import java.util.regex.Matcher; + +public class CssCompressor { + + private StringBuffer srcsb = new StringBuffer(); + + public CssCompressor(Reader in) throws IOException { + // Read the stream... + int c; + while ((c = in.read()) != -1) { + srcsb.append((char) c); + } + } + + public void compress(Writer out, int linebreakpos) + throws IOException { + + Pattern p; + Matcher m; + String css; + StringBuffer sb; + int startIndex, endIndex; + + // Remove all comment blocks... + startIndex = 0; + boolean iemac = false; + boolean preserve = false; + sb = new StringBuffer(srcsb.toString()); + while ((startIndex = sb.indexOf("/*", startIndex)) >= 0) { + preserve = sb.length() > startIndex + 2 && sb.charAt(startIndex + 2) == '!'; + endIndex = sb.indexOf("*/", startIndex + 2); + if (endIndex < 0) { + if (!preserve) { + sb.delete(startIndex, sb.length()); + } + } else if (endIndex >= startIndex + 2) { + if (sb.charAt(endIndex-1) == '\\') { + // Looks like a comment to hide rules from IE Mac. + // Leave this comment, and the following one, alone... + startIndex = endIndex + 2; + iemac = true; + } else if (iemac) { + startIndex = endIndex + 2; + iemac = false; + } else if (!preserve) { + sb.delete(startIndex, endIndex + 2); + } else { + startIndex = endIndex + 2; + } + } + } + + css = sb.toString(); + + // Normalize all whitespace strings to single spaces. Easier to work with that way. + css = css.replaceAll("\\s+", " "); + + // Make a pseudo class for the Box Model Hack + css = css.replaceAll("\"\\\\\"}\\\\\"\"", "___PSEUDOCLASSBMH___"); + + // Remove the spaces before the things that should not have spaces before them. + // But, be careful not to turn "p :link {...}" into "p:link{...}" + // Swap out any pseudo-class colons with the token, and then swap back. + sb = new StringBuffer(); + p = Pattern.compile("(^|\\})(([^\\{:])+:)+([^\\{]*\\{)"); + m = p.matcher(css); + while (m.find()) { + String s = m.group(); + s = s.replaceAll(":", "___PSEUDOCLASSCOLON___"); + m.appendReplacement(sb, s); + } + m.appendTail(sb); + css = sb.toString(); + css = css.replaceAll("\\s+([!{};:>+\\(\\)\\],])", "$1"); + css = css.replaceAll("___PSEUDOCLASSCOLON___", ":"); + + // Remove the spaces after the things that should not have spaces after them. + css = css.replaceAll("([!{}:;>+\\(\\[,])\\s+", "$1"); + + // Add the semicolon where it's missing. + css = css.replaceAll("([^;\\}])}", "$1;}"); + + // Replace 0(px,em,%) with 0. + css = css.replaceAll("([\\s:])(0)(px|em|%|in|cm|mm|pc|pt|ex)", "$1$2"); + + // Replace 0 0 0 0; with 0. + css = css.replaceAll(":0 0 0 0;", ":0;"); + css = css.replaceAll(":0 0 0;", ":0;"); + css = css.replaceAll(":0 0;", ":0;"); + // Replace background-position:0; with background-position:0 0; + css = css.replaceAll("background-position:0;", "background-position:0 0;"); + + // Replace 0.6 to .6, but only when preceded by : or a white-space + css = css.replaceAll("(:|\\s)0+\\.(\\d+)", "$1.$2"); + + // Shorten colors from rgb(51,102,153) to #336699 + // This makes it more likely that it'll get further compressed in the next step. + p = Pattern.compile("rgb\\s*\\(\\s*([0-9,\\s]+)\\s*\\)"); + m = p.matcher(css); + sb = new StringBuffer(); + while (m.find()) { + String[] rgbcolors = m.group(1).split(","); + StringBuffer hexcolor = new StringBuffer("#"); + for (int i = 0; i < rgbcolors.length; i++) { + int val = Integer.parseInt(rgbcolors[i]); + if (val < 16) { + hexcolor.append("0"); + } + hexcolor.append(Integer.toHexString(val)); + } + m.appendReplacement(sb, hexcolor.toString()); + } + m.appendTail(sb); + css = sb.toString(); + + // Shorten colors from #AABBCC to #ABC. Note that we want to make sure + // the color is not preceded by either ", " or =. Indeed, the property + // filter: chroma(color="#FFFFFF"); + // would become + // filter: chroma(color="#FFF"); + // which makes the filter break in IE. + p = Pattern.compile("([^\"'=\\s])(\\s*)#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])"); + m = p.matcher(css); + sb = new StringBuffer(); + while (m.find()) { + // Test for AABBCC pattern + if (m.group(3).equalsIgnoreCase(m.group(4)) && + m.group(5).equalsIgnoreCase(m.group(6)) && + m.group(7).equalsIgnoreCase(m.group(8))) { + m.appendReplacement(sb, m.group(1) + m.group(2) + "#" + m.group(3) + m.group(5) + m.group(7)); + } else { + m.appendReplacement(sb, m.group()); + } + } + m.appendTail(sb); + css = sb.toString(); + + // Remove empty rules. + css = css.replaceAll("[^\\}]+\\{;\\}", ""); + + if (linebreakpos >= 0) { + // Some source control tools don't like it when files containing lines longer + // than, say 8000 characters, are checked in. The linebreak option is used in + // that case to split long lines after a specific column. + int i = 0; + int linestartpos = 0; + sb = new StringBuffer(css); + while (i < sb.length()) { + char c = sb.charAt(i++); + if (c == '}' && i - linestartpos > linebreakpos) { + sb.insert(i, '\n'); + linestartpos = i; + } + } + + css = sb.toString(); + } + + // Replace the pseudo class for the Box Model Hack + css = css.replaceAll("___PSEUDOCLASSBMH___", "\"\\\\\"}\\\\\"\""); + + // Replace multiple semi-colons in a row by a single one + // See SF bug #1980989 + css = css.replaceAll(";;+", ";"); + + // Trim the final string (for any leading or trailing white spaces) + css = css.trim(); + + // Write the output... + out.write(css); + } +} -- cgit v1.2.3