同步操作将从 黎晓/JavaScript 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
/** YUI Compressor* http://developer.yahoo.com/yui/compressor/* Author: Julien Lecomte - http://www.julienlecomte.net/* Author: Isaac Schlueter - http://foohack.com/* Author: Stoyan Stefanov - http://phpied.com/* Copyright (c) 2011 Yahoo! Inc. All rights reserved.* The copyrights embodied in the content of this file are licensed* by Yahoo! Inc. under the BSD (revised) open source license.*/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;import java.util.ArrayList;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);}}// Leave data urls alone to increase parse performance.protected String extractDataUrls(String css, ArrayList preservedTokens) {int maxIndex = css.length() - 1;int appendIndex = 0;StringBuffer sb = new StringBuffer();Pattern p = Pattern.compile("url\\(\\s*([\"']?)data\\:");Matcher m = p.matcher(css);/** Since we need to account for non-base64 data urls, we need to handle* ' and ) being part of the data string. Hence switching to indexOf,* to determine whether or not we have matching string terminators and* handling sb appends directly, instead of using matcher.append* methods.*/while (m.find()) {int startIndex = m.start() + 4; // "url(".length()String terminator = m.group(1); // ', " or empty (not quoted)if (terminator.length() == 0) {terminator = ")";}boolean foundTerminator = false;int endIndex = m.end() - 1;while(foundTerminator == false && endIndex+1 <= maxIndex) {endIndex = css.indexOf(terminator, endIndex+1);if ((endIndex > 0) && (css.charAt(endIndex-1) != '\\')) {foundTerminator = true;if (!")".equals(terminator)) {endIndex = css.indexOf(")", endIndex);}}}// Enough searching, start moving stuff over to the buffersb.append(css.substring(appendIndex, m.start()));if (foundTerminator) {String token = css.substring(startIndex, endIndex);token = token.replaceAll("\\s+", "");preservedTokens.add(token);String preserver = "url(___YUICSSMIN_PRESERVED_TOKEN_" + (preservedTokens.size() - 1) + "___)";sb.append(preserver);appendIndex = endIndex + 1;} else {// No end terminator found, re-add the whole match. Should we throw/warn here?sb.append(css.substring(m.start(), m.end()));appendIndex = m.end();}}sb.append(css.substring(appendIndex));return sb.toString();}public void compress(Writer out, int linebreakpos)throws IOException {Pattern p;Matcher m;String css = srcsb.toString();int startIndex = 0;int endIndex = 0;int i = 0;int max = 0;ArrayList preservedTokens = new ArrayList(0);ArrayList comments = new ArrayList(0);String token;int totallen = css.length();String placeholder;css = this.extractDataUrls(css, preservedTokens);StringBuffer sb = new StringBuffer(css);// collect all comment blocks...while ((startIndex = sb.indexOf("/*", startIndex)) >= 0) {endIndex = sb.indexOf("*/", startIndex + 2);if (endIndex < 0) {endIndex = totallen;}token = sb.substring(startIndex + 2, endIndex);comments.add(token);sb.replace(startIndex + 2, endIndex, "___YUICSSMIN_PRESERVE_CANDIDATE_COMMENT_" + (comments.size() - 1) + "___");startIndex += 2;}css = sb.toString();// preserve strings so their content doesn't get accidentally minifiedsb = new StringBuffer();p = Pattern.compile("(\"([^\\\\\"]|\\\\.|\\\\)*\")|(\'([^\\\\\']|\\\\.|\\\\)*\')");m = p.matcher(css);while (m.find()) {token = m.group();char quote = token.charAt(0);token = token.substring(1, token.length() - 1);// maybe the string contains a comment-like substring?// one, maybe more? put'em back thenif (token.indexOf("___YUICSSMIN_PRESERVE_CANDIDATE_COMMENT_") >= 0) {for (i = 0, max = comments.size(); i < max; i += 1) {token = token.replace("___YUICSSMIN_PRESERVE_CANDIDATE_COMMENT_" + i + "___", comments.get(i).toString());}}// minify alpha opacity in filter stringstoken = token.replaceAll("(?i)progid:DXImageTransform.Microsoft.Alpha\\(Opacity=", "alpha(opacity=");preservedTokens.add(token);String preserver = quote + "___YUICSSMIN_PRESERVED_TOKEN_" + (preservedTokens.size() - 1) + "___" + quote;m.appendReplacement(sb, preserver);}m.appendTail(sb);css = sb.toString();// strings are safe, now wrestle the commentsfor (i = 0, max = comments.size(); i < max; i += 1) {token = comments.get(i).toString();placeholder = "___YUICSSMIN_PRESERVE_CANDIDATE_COMMENT_" + i + "___";// ! in the first position of the comment means preserve// so push to the preserved tokens while stripping the !if (token.startsWith("!")) {preservedTokens.add(token);css = css.replace(placeholder, "___YUICSSMIN_PRESERVED_TOKEN_" + (preservedTokens.size() - 1) + "___");continue;}// \ in the last position looks like hack for Mac/IE5// shorten that to /*\*/ and the next one to /**/if (token.endsWith("\\")) {preservedTokens.add("\\");css = css.replace(placeholder, "___YUICSSMIN_PRESERVED_TOKEN_" + (preservedTokens.size() - 1) + "___");i = i + 1; // attn: advancing the looppreservedTokens.add("");css = css.replace("___YUICSSMIN_PRESERVE_CANDIDATE_COMMENT_" + i + "___", "___YUICSSMIN_PRESERVED_TOKEN_" + (preservedTokens.size() - 1) + "___");continue;}// keep empty comments after child selectors (IE7 hack)// e.g. html >/**/ bodyif (token.length() == 0) {startIndex = css.indexOf(placeholder);if (startIndex > 2) {if (css.charAt(startIndex - 3) == '>') {preservedTokens.add("");css = css.replace(placeholder, "___YUICSSMIN_PRESERVED_TOKEN_" + (preservedTokens.size() - 1) + "___");}}}// in all other cases kill the commentcss = css.replace("/*" + placeholder + "*/", "");}// Normalize all whitespace strings to single spaces. Easier to work with that way.css = css.replaceAll("\\s+", " ");// 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(":", "___YUICSSMIN_PSEUDOCLASSCOLON___");s = s.replaceAll( "\\\\", "\\\\\\\\" ).replaceAll( "\\$", "\\\\\\$" );m.appendReplacement(sb, s);}m.appendTail(sb);css = sb.toString();// Remove spaces before the things that should not have spaces before them.css = css.replaceAll("\\s+([!{};:>+\\(\\)\\],])", "1ドル");// bring back the coloncss = css.replaceAll("___YUICSSMIN_PSEUDOCLASSCOLON___", ":");// retain space for special IE6 casescss = css.replaceAll(":first\\-(line|letter)(\\{|,)", ":first-1ドル 2ドル");// no space after the end of a preserved commentcss = css.replaceAll("\\*/ ", "*/");// If there is a @charset, then only allow one, and push to the top of the file.css = css.replaceAll("^(.*)(@charset \"[^\"]*\";)", "2ドル1ドル");css = css.replaceAll("^(\\s*@charset [^;]+;\\s*)+", "1ドル");// Put the space back in some cases, to support stuff like// @media screen and (-webkit-min-device-pixel-ratio:0){css = css.replaceAll("\\band\\(", "and (");// Remove the spaces after the things that should not have spaces after them.css = css.replaceAll("([!{}:;>+\\(\\[,])\\s+", "1ドル");// remove unnecessary semicolonscss = css.replaceAll(";+}", "}");// 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(;|})", ":01ドル");css = css.replaceAll(":0 0 0(;|})", ":01ドル");css = css.replaceAll(":0 0(;|})", ":01ドル");// Replace background-position:0; with background-position:0 0;// same for transform-originsb = new StringBuffer();p = Pattern.compile("(?i)(background-position|transform-origin|webkit-transform-origin|moz-transform-origin|o-transform-origin|ms-transform-origin):0(;|})");m = p.matcher(css);while (m.find()) {m.appendReplacement(sb, m.group(1).toLowerCase() + ":0 0" + m.group(2));}m.appendTail(sb);css = sb.toString();// Replace 0.6 to .6, but only when preceded by : or a white-spacecss = 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 (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.// We also want to make sure we're only compressing #AABBCC patterns inside { }, not id selectors ( #FAABAC {} )// We also want to avoid compressing invalid values (e.g. #AABBCCD to #ABCD)p = Pattern.compile("(\\=\\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])" + "(:?\\}|[^0-9a-fA-F{][^{]*?\\})");m = p.matcher(css);sb = new StringBuffer();int index = 0;while (m.find(index)) {sb.append(css.substring(index, m.start()));boolean isFilter = (m.group(1) != null && !"".equals(m.group(1)));if (isFilter) {// Restore, as is. Compression will break filterssb.append(m.group(1) + "#" + m.group(2) + m.group(3) + m.group(4) + m.group(5) + m.group(6) + m.group(7));} else {if( m.group(2).equalsIgnoreCase(m.group(3)) &&m.group(4).equalsIgnoreCase(m.group(5)) &&m.group(6).equalsIgnoreCase(m.group(7))) {// #AABBCC patternsb.append("#" + (m.group(3) + m.group(5) + m.group(7)).toLowerCase());} else {// Non-compressible color, restore, but lower case.sb.append("#" + (m.group(2) + m.group(3) + m.group(4) + m.group(5) + m.group(6) + m.group(7)).toLowerCase());}}index = m.end(7);}sb.append(css.substring(index));css = sb.toString();// border: none -> border:0sb = new StringBuffer();p = Pattern.compile("(?i)(border|border-top|border-right|border-bottom|border-right|outline|background):none(;|})");m = p.matcher(css);while (m.find()) {m.appendReplacement(sb, m.group(1).toLowerCase() + ":0" + m.group(2));}m.appendTail(sb);css = sb.toString();// shorter opacity IE filtercss = css.replaceAll("(?i)progid:DXImageTransform.Microsoft.Alpha\\(Opacity=", "alpha(opacity=");// Remove empty rules.css = css.replaceAll("[^\\}\\{/;]+\\{\\}", "");// TODO: Should this be after we re-insert tokens. These could alter the break points. However then// we'd need to make sure we don't break in the middle of a string etc.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.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 multiple semi-colons in a row by a single one// See SF bug #1980989css = css.replaceAll(";;+", ";");// restore preserved comments and stringsfor(i = 0, max = preservedTokens.size(); i < max; i++) {css = css.replace("___YUICSSMIN_PRESERVED_TOKEN_" + i + "___", preservedTokens.get(i).toString());}// Trim the final string (for any leading or trailing white spaces)css = css.trim();// Write the output...out.write(css);}}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。