1 /* 2 * Copyright 2009-2022 the original author or authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.googlecode.htmlcompressor.compressor; 17 18 import com.yahoo.platform.yui.compressor.JavaScriptCompressor; 19 20 import java.io.IOException; 21 import java.io.StringReader; 22 import java.io.StringWriter; 23 24 import org.mozilla.javascript.ErrorReporter; 25 import org.mozilla.javascript.EvaluatorException; 26 import org.slf4j.Logger; 27 import org.slf4j.LoggerFactory; 28 29 /** 30 * Basic JavaScript compressor implementation using <a href="http://developer.yahoo.com/yui/compressor/">Yahoo YUI 31 * Compressor</a> that could be used by {@link HtmlCompressor} for inline JavaScript compression. 32 * 33 * @author <a href="mailto:serg472@gmail.com">Sergiy Kovalchuk</a> 34 * 35 * @see HtmlCompressor#setJavaScriptCompressor(Compressor) 36 * @see <a href="http://developer.yahoo.com/yui/compressor/">Yahoo YUI Compressor</a> 37 */ 38 public class YuiJavaScriptCompressor implements Compressor { 39 40 /** The Constant logger. */ 41 private static final Logger logger = LoggerFactory.getLogger(YuiJavaScriptCompressor.class); 42 43 // YUICompressor default settings 44 45 /** The no munge. */ 46 private boolean noMunge; 47 48 /** The preserve all semi colons. */ 49 private boolean preserveAllSemiColons; 50 51 /** The disable optimizations. */ 52 private boolean disableOptimizations; 53 54 /** The line break. */ 55 private int lineBreak = -1; 56 57 /** The error reporter. */ 58 private ErrorReporter errorReporter = new DefaultErrorReporter(); 59 60 @Override 61 public String compress(String source) { 62 63 StringWriter result = new StringWriter(); 64 try { 65 JavaScriptCompressor compressor = new JavaScriptCompressor(new StringReader(source), errorReporter); 66 compressor.compress(result, lineBreak, !noMunge, false, preserveAllSemiColons, disableOptimizations); 67 } catch (IOException e) { 68 result.write(source); 69 logger.error("", e); 70 } 71 return result.toString(); 72 73 } 74 75 /** 76 * Default <code>ErrorReporter</code> implementation that uses <code>System.err</code> stream for error reporting. 77 * Used by YUI Compressor to log errors during JavaScript compression. 78 * 79 * @author <a href="mailto:serg472@gmail.com">Sergiy Kovalchuk</a> 80 * 81 * @see <a href="http://developer.yahoo.com/yui/compressor/">Yahoo YUI Compressor</a> 82 * @see <a href="http://www.mozilla.org/rhino/apidocs/org/mozilla/javascript/ErrorReporter.html">ErrorReporter 83 * Interface</a> 84 */ 85 public static class DefaultErrorReporter implements ErrorReporter { 86 87 @Override 88 public void warning(String message, String sourceName, int line, String lineSource, int lineOffset) { 89 if (line < 0) { 90 logger.error("[WARNING] HtmlCompressor: '{}' during JavaScript compression", message); 91 } else { 92 logger.error("[WARNING] HtmlCompressor: '{}' at line [{}:{}] during JavaScript compression {}", message, 93 line, lineOffset, lineSource != null ? ": " + lineSource : ""); 94 } 95 } 96 97 @Override 98 public void error(String message, String sourceName, int line, String lineSource, int lineOffset) { 99 if (line < 0) { 100 logger.error("[ERROR] HtmlCompressor: '{}' during JavaScript compression", message); 101 } else { 102 logger.error("[ERROR] HtmlCompressor: '{}' at line [{}:{}] during JavaScript compression {}", message, 103 line, lineOffset, lineSource != null ? ": " + lineSource : ""); 104 } 105 } 106 107 @Override 108 public EvaluatorException runtimeError(String message, String sourceName, int line, String lineSource, 109 int lineOffset) { 110 error(message, sourceName, line, lineSource, lineOffset); 111 return new EvaluatorException(message); 112 } 113 } 114 115 /** 116 * Returns <code>true</code> if Yahoo YUI Compressor will only minify javascript without obfuscating local symbols. 117 * This corresponds to <code>--nomunge</code> command line option. 118 * 119 * @return <code>nomunge</code> parameter value used for JavaScript compression. 120 * 121 * @see <a href="http://developer.yahoo.com/yui/compressor/">Yahoo YUI Compressor</a> 122 */ 123 public boolean isNoMunge() { 124 return noMunge; 125 } 126 127 /** 128 * Tells Yahoo YUI Compressor to only minify javascript without obfuscating local symbols. This corresponds to 129 * <code>--nomunge</code> command line option. This option has effect only if JavaScript compression is enabled. 130 * Default is <code>false</code>. 131 * 132 * @param noMunge 133 * set <code>true</code> to enable <code>nomunge</code> mode 134 * 135 * @see <a href="http://developer.yahoo.com/yui/compressor/">Yahoo YUI Compressor</a> 136 */ 137 public void setNoMunge(boolean noMunge) { 138 this.noMunge = noMunge; 139 } 140 141 /** 142 * Returns <code>true</code> if Yahoo YUI Compressor will preserve unnecessary semicolons during JavaScript 143 * compression. This corresponds to <code>--preserve-semi</code> command line option. 144 * 145 * @return <code>preserve-semi</code> parameter value used for JavaScript compression. 146 * 147 * @see <a href="http://developer.yahoo.com/yui/compressor/">Yahoo YUI Compressor</a> 148 */ 149 public boolean isPreserveAllSemiColons() { 150 return preserveAllSemiColons; 151 } 152 153 /** 154 * Tells Yahoo YUI Compressor to preserve unnecessary semicolons during JavaScript compression. This corresponds to 155 * <code>--preserve-semi</code> command line option. This option has effect only if JavaScript compression is 156 * enabled. Default is <code>false</code>. 157 * 158 * @param preserveAllSemiColons 159 * set <code>true</code> to enable <code>preserve-semi</code> mode 160 * 161 * @see <a href="http://developer.yahoo.com/yui/compressor/">Yahoo YUI Compressor</a> 162 */ 163 public void setPreserveAllSemiColons(boolean preserveAllSemiColons) { 164 this.preserveAllSemiColons = preserveAllSemiColons; 165 } 166 167 /** 168 * Returns <code>true</code> if Yahoo YUI Compressor will disable all the built-in micro optimizations during 169 * JavaScript compression. This corresponds to <code>--disable-optimizations</code> command line option. 170 * 171 * @return <code>disable-optimizations</code> parameter value used for JavaScript compression. 172 * 173 * @see <a href="http://developer.yahoo.com/yui/compressor/">Yahoo YUI Compressor</a> 174 */ 175 public boolean isDisableOptimizations() { 176 return disableOptimizations; 177 } 178 179 /** 180 * Tells Yahoo YUI Compressor to disable all the built-in micro optimizations during JavaScript compression. This 181 * corresponds to <code>--disable-optimizations</code> command line option. This option has effect only if 182 * JavaScript compression is enabled. Default is <code>false</code>. 183 * 184 * @param disableOptimizations 185 * set <code>true</code> to enable <code>disable-optimizations</code> mode 186 * 187 * @see <a href="http://developer.yahoo.com/yui/compressor/">Yahoo YUI Compressor</a> 188 */ 189 public void setDisableOptimizations(boolean disableOptimizations) { 190 this.disableOptimizations = disableOptimizations; 191 } 192 193 /** 194 * Returns number of symbols per line Yahoo YUI Compressor will use during JavaScript compression. This corresponds 195 * to <code>--line-break</code> command line option. 196 * 197 * @return <code>line-break</code> parameter value used for JavaScript compression. 198 * 199 * @see <a href="http://developer.yahoo.com/yui/compressor/">Yahoo YUI Compressor</a> 200 */ 201 public int getLineBreak() { 202 return lineBreak; 203 } 204 205 /** 206 * Tells Yahoo YUI Compressor to break lines after the specified number of symbols during JavaScript compression. 207 * This corresponds to <code>--line-break</code> command line option. This option has effect only if JavaScript 208 * compression is enabled. Default is <code>-1</code> to disable line breaks. 209 * 210 * @param lineBreak 211 * set number of symbols per line 212 * 213 * @see <a href="http://developer.yahoo.com/yui/compressor/">Yahoo YUI Compressor</a> 214 */ 215 public void setLineBreak(int lineBreak) { 216 this.lineBreak = lineBreak; 217 } 218 219 /** 220 * Returns <code>ErrorReporter</code> used by YUI Compressor to log error messages during JavasSript compression. 221 * 222 * @return <code>ErrorReporter</code> used by YUI Compressor to log error messages during JavasSript compression 223 * 224 * @see <a href="http://developer.yahoo.com/yui/compressor/">Yahoo YUI Compressor</a> 225 * @see <a href="http://www.mozilla.org/rhino/apidocs/org/mozilla/javascript/ErrorReporter.html">Error Reporter 226 * Interface</a> 227 */ 228 public ErrorReporter getErrorReporter() { 229 return errorReporter; 230 } 231 232 /** 233 * Sets <code>ErrorReporter</code> that YUI Compressor will use for reporting errors during JavaScript compression. 234 * If no <code>ErrorReporter</code> was provided {@link YuiJavaScriptCompressor.DefaultErrorReporter} will be used 235 * which reports errors to <code>System.err</code> stream. 236 * 237 * @param errorReporter 238 * <code>ErrorReporter</code> that will be used by YUI Compressor 239 * 240 * @see YuiJavaScriptCompressor.DefaultErrorReporter 241 * @see <a href="http://developer.yahoo.com/yui/compressor/">Yahoo YUI Compressor</a> 242 * @see <a href="http://www.mozilla.org/rhino/apidocs/org/mozilla/javascript/ErrorReporter.html">ErrorReporter 243 * Interface</a> 244 */ 245 public void setErrorReporter(ErrorReporter errorReporter) { 246 this.errorReporter = errorReporter; 247 } 248 249 }