1. [代码]JavaScriptCompressor.java
/**
 * This file is part of the Echo Web Application Framework (hereinafter "Echo").
 * Copyright (C) 2002-2009 NextApp, Inc.
 *
 * Compresses a String containing JavaScript by removing comments and whitespace.
 */
public class JavaScriptCompressor {
 
    private static final char LINE_FEED = '\n';
    private static final char CARRIAGE_RETURN = '\r';
    private static final char SPACE = ' ';
    private static final char TAB = '\t';
 
    /**
     * Compresses a String containing JavaScript by removing comments and 
     * whitespace.
     * 
     * @param script the String to compress
     * @return a compressed version
     */
    public static String compress(String script) {
        JavaScriptCompressor jsc = new JavaScriptCompressor(script);
        return jsc.outputBuffer.toString();
    }
 
    /** Original JavaScript text. */
    private String script;
     
    /** 
     * Compressed output buffer.
     * This buffer may only be modified by invoking the <code>append()</code>
     * method.
     */
    private StringBuffer outputBuffer;
     
    /** Current parser cursor position in original text. */
    private int pos;
     
    /** Character at parser cursor position. */
    private char ch;
     
    /** Last character appended to buffer. */
    private char lastAppend;
 
    /** Flag indicating if end-of-buffer has been reached. */
    private boolean endReached;
 
    /** Flag indicating whether content has been appended after last identifier. */
    private boolean contentAppendedAfterLastIdentifier = true;
 
    /**
     * Creates a new <code>JavaScriptCompressor</code> instance.
     * 
     * @param script
     */
    private JavaScriptCompressor(String script) {
        this.script = script;
        outputBuffer = new StringBuffer(script.length());
        nextChar();
 
        while (!endReached) {
            if (Character.isJavaIdentifierStart(ch)) {
                renderIdentifier();
            } else if (ch == ' ') {
                skipWhiteSpace();
            } else if (isWhitespace()) {
                // Compress whitespace
                skipWhiteSpace();
            } else if ((ch == '"') || (ch == '\'')) {
                // Handle strings
                renderString();
            } else if (ch == '/') {
                // Handle comments
                nextChar();
                if (ch == '/') {
                    nextChar();
                    skipLineComment();
                } else if (ch == '*') {
                    nextChar();
                    skipBlockComment();
                } else {
                    append('/');
                }
            } else {
                append(ch);
                nextChar();
            }
        }
    }
 
    /**
     * Append character to output.
     * flash动画
     * @param ch the character to append
     */http://www.huiyi8.com/donghua/​
    private void append(char ch) {
        lastAppend = ch;
        outputBuffer.append(ch);
        contentAppendedAfterLastIdentifier = true;
    }
     
    /**
     * Determines if current character is whitespace.
     * 
     * @return true if the character is whitespace
     */
    private boolean isWhitespace() {
        return ch == CARRIAGE_RETURN || ch == SPACE || ch == TAB || ch == LINE_FEED;        
    }
 
    /**
     * Load next character.
     */
    private void nextChar() {
        if (!endReached) {
            if (pos < script.length()) {
                ch = script.charAt(pos++);
            } else {
                endReached = true;
                ch = 0;
            }
        }
    }
 
    /**
     * Adds an identifier to output.
     */
    private void renderIdentifier() {
        if (!contentAppendedAfterLastIdentifier)
            append(SPACE);
        append(ch);
        nextChar();
        while (Character.isJavaIdentifierPart(ch)) {
            append(ch);
            nextChar();
        }
        contentAppendedAfterLastIdentifier = false;
    }
 
    /**
     * Adds quoted String starting at current character to output.
     */
    private void renderString() {
        char startCh = ch; // Save quote char
        append(ch);
        nextChar();
        while (true) {
            if ((ch == LINE_FEED) || (ch == CARRIAGE_RETURN) || (endReached)) {
                // JavaScript error: string not terminated
                return;
            } else {
                if (ch == '\\') {
                    append(ch);
                    nextChar();
                    if ((ch == LINE_FEED) || (ch == CARRIAGE_RETURN) || (endReached)) {
                        // JavaScript error: string not terminated
                        return;
                    }
                    append(ch);
                    nextChar();
                } else {
                    append(ch);
                    if (ch == startCh) {
                        nextChar();
                        return;
                    }
                    nextChar();
                }
            }
        }
    }
 
    /**
     * Moves cursor past a line comment.
     */
    private void skipLineComment() {
        while ((ch != CARRIAGE_RETURN) && (ch != LINE_FEED)) {
            if (endReached) {
                return;
            }
            nextChar();
        }
    }
 
    /**
     * Moves cursor past a block comment.
     */
    private void skipBlockComment() {
        while (true) {
            if (endReached) {
                return;
            }
            if (ch == '*') {
                nextChar();
                if (ch == '/') {
                    nextChar();
                    return;
                }
            } else
                nextChar();
        }
    }
     
    /**
     * Renders a new line character, provided previously rendered character 
     * is not a newline.
     */
    private void renderNewLine() {
        if (lastAppend != '\n' && lastAppend != '\r') {
            append('\n');
        }
    }
     
    /**
     * Moves cursor past white space (including newlines).
     */
    private void skipWhiteSpace() {
        if (ch == LINE_FEED || ch == CARRIAGE_RETURN) {
            renderNewLine();
        } else {
            append(ch);
        }
        nextChar();
        while (ch == LINE_FEED || ch == CARRIAGE_RETURN || ch == SPACE || ch == TAB) {
            if (ch == LINE_FEED || ch == CARRIAGE_RETURN) {
                renderNewLine();
            }
            nextChar();
        }
    }
}

【Java】通过移除空行和注释来压缩 JavaScript 代码的更多相关文章

  1. java正则表达式移除网页中注释代码

    /** * 移除网页中注释掉的代码 * * @param str * @return */ public static String removedisablecode(String str) { P ...

  2. java简单统计.java文件中的有效代码行,空行,注释行

    package regxdemo; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundExc ...

  3. java编码规范_缩进和注释

    1.       缩进排版(Indentation) 4个空格常被作为缩进排版的一个单位.缩进的确切解释并未详细指定(空格 vs. 制表符).一个制表符等于n个空格(视具体的编辑器而定,Eclipse ...

  4. Java基础学习总结(92)——Java编码规范之排版、注释及命名

    为使开发人员养成良好的开发习惯,编写可读性强.易维护的程序,结合以往资料,现整理Java编码规范,将之作为开发人员的参照依据. 一.排版 1.相对独立的程序块之间必须加空行 下列情况应该使用一个空行: ...

  5. 007-使用python统计代码行数,空行以及注释

    # 自己写过的程序,统计一下你写过多少行代码.包括空行和注释,但是要分别列出来 1.打开文件方法 1.1 以读文件的模式打开一个文件对象,使用Python内置的open()函数,传入文件名和标示符 f ...

  6. linux过滤旧文件中的空行和注释行剩余内容组成新文件

    一.说明 在某些场景下我们想要将旧文件中空行和注释行过滤掉,将产生实际效果的行保留. 比如redis提供的配置示例文件中有很多用于说明的空行和注释行,我们想把产生实际效果的配置行筛选出来组成新的简洁的 ...

  7. java 生成jar包并保留注释

      java 生成jar包并保留注释 CreationTime--2018年7月17日08点32分 Author:Marydon 1.选中java项目-->右键-->Export: 2.去 ...

  8. python 判断是否是空行或注释行

    #coding:utf-8 '''''cdays-4-exercise-6.py 文件基本操作 @note: 文件读取写入, 列表排序, 字符串操作 @see: 字符串各方法可参考hekp(str)或 ...

  9. vim删除空行和注释

    vim删除空行和注释 来源:  http://jpuyy.com/2015/06/vim-delete-lines-using-regexp.html 删除空行 :g/^$/d 删除空行以及只有空格的 ...

随机推荐

  1. Eclipse 语言文件下载地址

    http://www.eclipse.org/babel/downloads.php 更改配色: 安装新软件: http://eclipse-color-theme.github.com/update

  2. 2018 ICPC 沈阳网络赛预赛 Supreme Number(找规律)

    [传送门]https://nanti.jisuanke.com/t/31452 [题目大意]:给定一个数字(最大可达10100),现在要求不超过它的最大超级质数.超级质数定义:对于一个数,把它看成数字 ...

  3. input标签附带提示文字(bootstrap里面输入框的两侧同时添加额外元素)

    一直不太喜欢用定位,今天写界面的时候,要在输入框右边添加默认的元素符号. 第一次尝试,因为本身项目用的是bootstrap所以就想利用输入框的两侧同时添加额外元素. 但是写了代码发现效果不同. 第二次 ...

  4. Chrome 浏览器安装Vue插件方法 (十分详细)

    博主最近在研究Vue,无奈新手想安装Chrome的Vue插件,整理下安装流程: 1.首先去github下载vue.zip文件插件(还有npm安装方法这里就不介绍了自行百度)下载地址:https://g ...

  5. 【c++】面向对象程序设计之关于继承

    面向对象程序设计的核心思想是数据抽象(类的接口与实现分离).继承和动态绑定 基类 虚函数:基类希望派生类各自定义适合自身的版本的函数 在c++中,当我们使用基类的引用或指针调用虚函数时将发生动态绑定. ...

  6. 转:国内Top500Android应用分析报告

    转自:https://mp.weixin.qq.com/s?__biz=MzA5OTMxMjQzMw==&mid=2648112527&idx=1&sn=b23c1b5f3e3 ...

  7. 项目整理--Echarts前端后台的贯通写法

    项目整理–Echarts前端后台的贯通写法 注:下面所有内容建立在FH admin开源框架和eharts插件基础上,建议观看本案例者进行了解. 业务逻辑 绘制两张图表.分别显示城市空间库和其它数据仓库 ...

  8. [HTML5] Show Images of Differing Resolutions Depending on the Viewport Width with srcset

    For small viewports, we want to save bandwidth and we may be dealing with slow speeds; so it's very ...

  9. js中对arry数组的各种操作小结 瀑布流AJAX无刷新加载数据列表--当页面滚动到Id时再继续加载数据 web前端url传递值 js加密解密 HTML中让表单input等文本框为只读不可编辑的方法 js监听用户的键盘敲击事件,兼容各大主流浏览器 HTML特殊字符

    js中对arry数组的各种操作小结   最近工作比较轻松,于是就花时间从头到尾的对js进行了详细的学习和复习,在看书的过程中,发现自己平时在做项目的过程中有很多地方想得不过全面,写的不够合理,所以说啊 ...

  10. C3P0连接池配置和实现详解(转)

    一.配置 <c3p0-config> <default-config> <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数.Default: 3 --> ...