PageRenderTime 20ms CodeModel.GetById 9ms app.highlight 8ms RepoModel.GetById 1ms app.codeStats 0ms

/branches/jsdoc_tk_gui/setup/plugins/min.js

http://jsdoc-toolkit.googlecode.com/
JavaScript | 316 lines | 230 code | 25 blank | 61 comment | 36 complexity | f016290606c0b5274fd3c5ddf0246328 MD5 | raw file
  1/**
  2	@overview Remove unnecessary characters from source code and save file.
  3	Uses Franck Marcia's adaptation of Douglas Crockford's JsMin tool.
  4	@author Michael Mathews micmath@gmail.com
  5*/
  6function deploy_begin(context) {
  7	context.src = context.d+"/src";
  8	MakeDir(context.src);
  9}
 10
 11function deploy_each(sourceFile, context) {
 12	var name = sourceFile.fileName.replace(/(\.\.?)?[\/\\]/g, "_");
 13	inform("Saving minimized source file to "+name);
 14	
 15	var mini = jsmin(sourceFile.content);
 16	SaveFile(context.src, name, mini);
 17}
 18
 19function deploy_finish(context) {	
 20}
 21
 22
 23/*
 24jsmin.js - 2006-08-31
 25Author: Franck Marcia
 26
 27This work is an adaptation of jsminc.c published by Douglas Crockford.
 28and copyright (c) 2002 Douglas Crockford (www.crockford.com)
 29
 30Permission is hereby granted to use the Javascript version under the same
 31conditions as the jsmin.c on which it is based.
 32
 33Permission is hereby granted, free of charge, to any person obtaining a copy of
 34this software and associated documentation files (the "Software"), to deal in
 35the Software without restriction, including without limitation the rights to
 36use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 37of the Software, and to permit persons to whom the Software is furnished to do
 38so, subject to the following conditions:
 39
 40The above copyright notice and this permission notice shall be included in all
 41copies or substantial portions of the Software.
 42
 43The Software shall be used for Good, not Evil.
 44
 45THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 46IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 47FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 48AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 49LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 50OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 51SOFTWARE.
 52*/
 53
 54String.prototype.has = function(c) {
 55	return this.indexOf(c) > -1;
 56};
 57
 58/*
 59	level:
 60	1: minimal, keep linefeeds if single
 61	2: normal, the standard algorithm
 62	3: agressive, remove any linefeed and doesn't take care of potential
 63	   missing semicolons (can be regressive)
 64*/
 65function jsmin(input, level) {
 66
 67	if (level === undefined || level < 1 || level > 3) {
 68		level = 2;
 69	}
 70
 71	var a = '',
 72		b = '',
 73		EOF = -1,
 74		LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
 75		DIGITS = '0123456789',
 76		ALNUM = LETTERS + DIGITS + '_$\\',
 77		theLookahead = EOF;
 78
 79
 80	/* isAlphanum -- return true if the character is a letter, digit, underscore,
 81			dollar sign, or non-ASCII character.
 82	*/
 83
 84	function isAlphanum(c) {
 85		return c != EOF && (ALNUM.has(c) || c.charCodeAt(0) > 126);
 86	}
 87
 88	/* get -- return the next character. Watch out for lookahead. If the
 89			character is a control character, translate it to a space or
 90			linefeed.
 91	*/
 92
 93	function get() {
 94		var c = theLookahead;
 95		if (get.i == get.l) {
 96			return EOF;
 97		}
 98		theLookahead = EOF;
 99		if (c == EOF) {
100			c = input.charAt(get.i);
101			++get.i;
102		}
103		if (c >= ' ' || c == '\n') {
104			return c;
105		}
106		if (c == '\r') {
107			return '\n';
108		}
109		return ' ';
110	}
111
112	get.i = 0;
113	get.l = input.length;
114
115	/* peek -- get the next character without getting it.
116	*/
117
118	function peek() {
119		theLookahead = get();
120		return theLookahead;
121	}
122
123	/* next -- get the next character, excluding comments. peek() is used to see
124			if a '/' is followed by a '/' or '*'.
125	*/
126
127	function next() {
128		var c = get();
129		if (c == '/') {
130			switch (peek()) {
131			case '/':
132				for (;;) {
133					c = get();
134					if (c <= '\n') {
135						return c;
136					}
137				}
138				break;
139			case '*':
140				get();
141				for (;;) {
142					switch (get()) {
143					case '*':
144						if (peek() == '/') {
145							get();
146							return ' ';
147						}
148						break;
149					case EOF:
150						throw 'Error: Unterminated comment.';
151					}
152				}
153				break;
154			default:
155				return c;
156			}
157		}
158		return c;
159	}
160
161	/* action -- do something! What you do is determined by the argument:
162			1   Output A. Copy B to A. Get the next B.
163			2   Copy B to A. Get the next B. (Delete A).
164			3   Get the next B. (Delete B).
165	   action treats a string as a single character. Wow!
166	   action recognizes a regular expression if it is preceded by ( or , or =.
167	*/
168
169	function action(d) {
170		var r = [];
171
172		if (d == 1) {
173			r.push(a);
174		}
175
176		if (d < 3) {
177			a = b;
178			if (a == '\'' || a == '"') {
179				for (;;) {
180					r.push(a);
181					a = get();
182					if (a == b) {
183						break;
184					}
185					if (a <= '\n') {
186						throw 'Error: unterminated string literal: ' + a;
187					}
188					if (a == '\\') {
189						r.push(a);
190						a = get();
191					}
192				}
193			}
194		}
195
196		b = next();
197
198		if (b == '/' && '(,=:[!&|'.has(a)) {
199			r.push(a);
200			r.push(b);
201			for (;;) {
202				a = get();
203				if (a == '/') {
204					break;
205				} else if (a =='\\') {
206					r.push(a);
207					a = get();
208				} else if (a <= '\n') {
209					throw 'Error: unterminated Regular Expression literal';
210				}
211				r.push(a);
212			}
213			b = next();
214		}
215
216		return r.join('');
217	}
218
219	/* m -- Copy the input to the output, deleting the characters which are
220			insignificant to JavaScript. Comments will be removed. Tabs will be
221			replaced with spaces. Carriage returns will be replaced with
222			linefeeds.
223			Most spaces and linefeeds will be removed.
224	*/
225
226	function m() {
227		var r = [];
228		
229		// ignore UTF BOM characters
230		do {
231			a = next();
232		} while (a.charCodeAt(0) > 255);
233		
234		r.push(action(3));
235
236		while (a != EOF) {                                                  
237			switch (a) {
238			case ' ':
239				if (isAlphanum(b)) {
240					r.push(action(1));
241				} else {
242					r.push(action(2));
243				}
244				break;
245			case '\n':
246				switch (b) {
247				case '{':
248				case '[':
249				case '(':
250				case '+':
251				case '-':
252					r.push(action(1));
253					break;
254				case ' ':
255					r.push(action(3));
256					break;
257				default:
258					if (isAlphanum(b)) {
259						r.push(action(1));
260					} else {
261						if (level == 1 && b != '\n') {
262							r.push(action(1));
263						} else {
264							r.push(action(2));
265						}
266					}
267				}
268				break;
269			default:
270				switch (b) {
271				case ' ':
272					if (isAlphanum(a)) {
273						r.push(action(1));
274						break;
275					}
276					r.push(action(3));
277					break;
278				case '\n':
279					if (level == 1 && a != '\n') {
280						r.push(action(1));
281					} else {
282						switch (a) {
283						case '}':
284						case ']':
285						case ')':
286						case '+':
287						case '-':
288						case '"':
289						case '\'':
290							if (level == 3) {
291								r.push(action(3));
292							} else {
293								r.push(action(1));
294							}
295							break;
296						default:
297							if (isAlphanum(a)) {
298								r.push(action(1));
299							} else {
300								r.push(action(3));
301							}
302						}
303					}
304					break;
305				default:
306					r.push(action(1));
307					break;
308				}
309			}
310		}
311
312		return r.join('');
313	}
314
315	return m(input);
316}