Commit f73ad782 authored by Rafael Monnerat's avatar Rafael Monnerat

Added Compression Libraries for Javascript and CSS.

Made by Lucas Carvalho.


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@24715 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 3206e108
##############################################################################
#
# Copyright (c) 2008 Nexedi SA and Contributors. All Rights Reserved.
# Lucas Carvalho Teixeira <lucas@nexedi.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import re
def compressCSS(css):
"""
CSS file compressor
This compressor remove the comments, eol
and all the possible tabs.
"""
white_space_regex = re.compile("[\n|\t|\r]")
commment_regex = re.compile("/\*.*?\*/")
class_regex = re.compile(r"([^{]*?){(.*?)}")
style = re.compile(r"([\w\s-]*):([^;]*);?")
css = commment_regex.sub('', white_space_regex.sub("", css))
return '\n'.join(["%s{%s}" % (x[0].strip(), \
''.join(["%s:%s;" % (y[0].strip(), y[1].strip()) \
for y in style.findall(x[1])])) for x in class_regex.findall(css)])
This diff is collapsed.
This diff is collapsed.
/*
Copyright (c) 20xx-2006 Nexedi SARL and Contributors. All Rights Reserved.
This program is Free Software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
function submitAction(form, act) {
form.action = act;
form.submit();
}
// This function will be called when the user click the save button. As
// submitAction function may have changed the action before, it's better to
// reset the form action to it's original behaviour. This is actually
// usefull when the user click the back button.
function clickSaveButton(act) {
document.forms[0].action = act;
}
// The first input element with an "autofocus" class will get the focus,
// else if no element have autofocus class, the first element which is not the
// search field will get the focus. This is generally the title input text of
// a view
function autoFocus() {
var first_autofocus_expr = ".//input[@class='autofocus']"
var FIRST_RESULT = XPathResult.FIRST_ORDERED_NODE_TYPE
var input = document.evaluate(first_autofocus_expr, document, null, FIRST_RESULT, null).singleNodeValue;
if (input) {
input.focus();
}else{
// The following is disabled, because it is too annoying to have an auto focus at everywhere.
//var first_text_input_expr = ".//input[@type='text'][@name != 'field_your_search_text']"
//var first_text_input = document.evaluate(first_text_input_expr, document, null, FIRST_RESULT, null).singleNodeValue;
//if (first_text_input){
// first_text_input.focus();
//}
}
}
function buildTables(element_list, rowPredicate, columnPredicate,
tableClassName) {
/* Generic code to build a table from elements in element_list.
* rowPredicate(element) -> bool
* When it returns a true value, a new line is started with element.
* When is returns a false value, element is skipped.
* columnPredicate(element, initial_element) -> bitfield
* bit 3: end_table (if true, imlies end_row)
* End current table.
* bit 2: end_row
* End current row.
* bit 1: use_element
* Element passed to columnPredicate will be put in current row.
* Hardcoded:
* - items in a table line must be siblings in existing DOM
* - table is put in place of first element of the first row
*/
var element_index = 0;
while (element_index < element_list.length) {
var row_list = [];
var end_table = false;
while ((!end_table) && element_index < element_list.length) {
var row_begin = element_list[element_index];
if (rowPredicate(row_begin)) {
var item_list = [row_begin];
var row_item = row_begin;
var end_line = false;
while ((!end_line) && (row_item = row_item.nextSibling) != null) {
var predicate_result = columnPredicate(row_item, row_begin)
if ((predicate_result & 1) != 0)
item_list.push(row_item);
end_table = ((predicate_result & 4) != 0);
end_line = ((predicate_result & 6) != 0);
}
row_list.push(item_list);
}
element_index++;
}
/* Do not create a table with just one cell. */
if ((row_list.length > 1) ||
(row_list.length == 1 && row_list[0].length > 1)) {
var first_element = row_list[0][0];
var container = first_element.parentNode;
var fake_table = document.createElement("table");
var i;
var j;
fake_table.className = tableClassName;
container.insertBefore(fake_table, first_element);
for (i = 0; i < row_list.length; i++) {
var fake_row = document.createElement("tr");
var row_element_list = row_list[i];
for (j = 0; j < row_element_list.length; j++) {
var fake_cell = document.createElement("td");
fake_cell.appendChild(row_element_list[j]);
fake_row.appendChild(fake_cell);
}
fake_table.appendChild(fake_row);
}
}
}
}
function matchChunk(string, separator, chunk_value) {
if (string != null) {
var id_chunks = string.split(separator);
var i;
for (i = 0; i < id_chunks.length; i++) {
if (id_chunks[i] == chunk_value)
return true;
}
}
return false;
}
function matchLeftFieldset(element) {
return (element.tagName == "FIELDSET") &&
matchChunk(element.id, '_', "left");
}
function matchRightFieldset(element, ignored) {
if ((element.tagName == "FIELDSET") &&
matchChunk(element.id, '_', "right"))
return 7; /* End row, table and use element */
return 0;
}
function fixLeftRightHeightAndFocus(fix_height) {
if (fix_height == 1) {
buildTables(document.getElementsByTagName('fieldset'),
matchLeftFieldset, matchRightFieldset,
"fake");
}
autoFocus();
}
// This function can be used to catch ENTER pressed in an input
// and modify respective main form action
function submitFormOnEnter(event, main_form_id, method_name){
var key_code = event.keyCode;
if(key_code == 13){
var main_form = getElement(main_form_id)
main_form.action=method_name;};
}
var old_index=0;
function shiftCheck(evt) {
evt=(evt)?evt:event;
var target=(evt.target)?evt.target:evt.srcElement;
// remove "checkbox" part from ID
// This part can be reused easilly by usual left column
var target_index= target.id.substr(8);
if(!evt.shiftKey) {
old_index= target_index
check_option = target.checked;
return false;
}
target.checked=1;
var low=Math.min(target_index , old_index);
var high=Math.max(target_index , old_index);
for(var i=low;i<=high;i++) {
document.getElementById("checkbox" + i ).checked = check_option;
}
return true;
}
var indexAllCheckBoxesAtBTInstallationOnLoad = function() {
// This Part is used basically for Business Template Installation.
var inputs = window.getElementsByTagAndClassName("input", "shift_check_support");
for(i=0;i<=inputs.length-1;i++) { inputs[i].id = "checkbox" + i; }
}
addLoadEvent(indexAllCheckBoxesAtBTInstallationOnLoad)
This diff is collapsed.
eval(function(p,a,c,k,e,d){e=function(c){return(c<a?"":e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp("\\b"+e(c)+"\\b","g"),k[c]);return p}('/*\n4X (c) 4W-4V 4U 4T N 4S. 4R 4Q 4P.\n\nl 1s f 1r 1q; 4O 11 4N v N/1w\n1L v 4M 9 4L u 9 1v 1u 1t X\n4K 4J 1E 9 1r 1q 2j; 4I 2k 2\nu 9 X, 1w (29 4H 4G) 4F 4E 2k.\n\nl 1s f 4D q 9 4C 4B v H x 4A,\n4z 4y 4x 4w; 4v 4u 9 4t 4s u\n4r 1w 4q 4p A 4o 4n. 4m 9\n1v 1u 1t X o 4l 4k.\n\n4j 4i V 4h a 4g u 9 1v 1u 1t X\n4f Q 4e 1s; e 1f, 4d r 9 1r 1q\n2j, 4c., 4b 4a 49 - 48 47, 46, 45 44-43, 42.\n*/\n\nd 2i(C, W) {\n C.y = W;\n C.41();\n}\n\n// l d H x 40 2h 9 2g 2f 9 3Z 2e. 3Y \n// 2i d 3X V 3W 9 y 3V, v\'s 3U r\n// 3T 9 C y r v\'s 3S 3R. l f 3Q\n// 3P 2h 9 2g 2f 9 3O 2e.\nd 3N(W) {\n g.3M[0].y = W;\n}\n\n\n// 2a U k b Q 14 "1o" 1p H 2d 9 I,\n// 2b e 3L b V 1o 1p, 9 U b 3K f 1f 9\n// 3J 3I H 2d 9 I. l f 3H 9 3G k 28 u\n// a 3F\nd 1M() {\n 5 2c = ".//k[@1p=\'1o\']"\n 5 1n = 3E.3D\n\n 5 k = g.27(2c, g, z, 1n, z).25;\n e (k) {\n k.I();\n }2b{\n // 2a 3C f 3B, 3A v f 3z 3y r V 14 3x I 29 3w.\n //5 26 = ".//k[@3v=\'28\'][@3u != \'3t\']"\n //5 1m = g.27(26, g, z, 1n, z).25;\n //e (1m){\n // 1m.I();\n //}\n }\n}\n\nd 1P(G, 1j, T,\n 1X) {\n /* 3s 3r r 3q a t 1G 3p q G.\n * 1j(b) -> 3o\n * 24 v 23 a K 22, a 3n 20 f 3m Q b.\n * 24 f 23 a B 22, b f 3l.\n * T(b, 3k) -> 3j\n * 1l 3: S (e K, 3i 21)\n * 15 1k t.\n * 1l 2: 21\n * 15 1k O.\n * 1l 1: 3h\n * 3g 3f r T H x 1Z q 1k O.\n * 3e:\n * - 3d q a t 20 3c x 3b q 3a 39\n * - t f 1Z q 38 u U b u 9 U O\n */\n 5 D = 0;\n 1i (D < G.h) {\n 5 n = [];\n 5 S = B;\n 1i ((!S) && D < G.h) {\n 5 F = G[D];\n e (1j(F)) {\n 5 1g = [F];\n 5 E = F;\n 5 1h = B;\n 1i ((!1h) && (E = E.37) != z) {\n 5 R = T(E, F)\n e ((R & 1) != 0)\n 1g.1Y(E);\n S = ((R & 4) != 0);\n 1h = ((R & 6) != 0);\n }\n n.1Y(1g);\n }\n D++;\n }\n /* 36 1f 35 a t Q 34 33 32. */\n e ((n.h > 1) ||\n (n.h == 1 && n[0].h > 1)) {\n 5 1e = n[0][0];\n 5 1W = 1e.31;\n 5 P = g.1d("t");\n 5 i;\n 5 j;\n P.30 = 1X;\n 1W.2Z(P, 1e);\n o (i = 0; i < n.h; i++) {\n 5 19 = g.1d("2Y");\n 5 1c = n[i];\n o (j = 0; j < 1c.h; j++) {\n 5 1b = g.1d("2X");\n 1b.1a(1c[j]);\n 19.1a(1b);\n }\n P.1a(19);\n }\n }\n }\n}\n\nd 16(18, 1V, 1U) {\n e (18 != z) {\n 5 17 = 18.2W(1V);\n 5 i;\n o (i = 0; i < 17.h; i++) {\n e (17[i] == 1U)\n p K;\n }\n }\n p B;\n}\n\nd 1O(b) {\n p (b.1T == "1S") &&\n 16(b.J, \'1R\', "1D");\n}\n\nd 1N(b, 2V) {\n e ((b.1T == "1S") &&\n 16(b.J, \'1R\', "2U"))\n p 7; /* 15 O, t N 2T b */\n p 0;\n}\n\nd 2S(1Q) {\n e (1Q == 1) {\n 1P(g.2R(\'2Q\'),\n 1O, 1N,\n "2P");\n }\n 1M();\n}\n\n// l d 11 x 1y r 2O 2N 2M q 14 k \n// N 1L 2L 2K C y\nd 2J(12, 1J, 1H){\n 5 1K = 12.2I;\n e(1K == 13){\n 5 1I = 2H(1J)\n 1I.y=1H;};\n}\n\n5 L=0;\nd 2G(m) {\n m=(m)?m:12;\n 5 w=(m.w)?m.w:m.2F;\n // 2E "Y" 1F 1G 2D\n // l 1F 11 x 2C 2B 1E 2A 1D 2z\n 5 M= w.J.2y(8);\n e(!m.2x) {\n L= M\n 1z = w.10;\n p B;\n }\n w.10=1;\n 5 1B=1C.2w(M , L);\n 5 1A=1C.2v(M , L);\n o(5 i=1B;i<=1A;i++) {\n g.2u("Y" + i ).10 = 1z;\n }\n p K;\n }\n\n5 1x = d() {\n // l 2t f 1y 2s o 2r 2q 2p.\n 5 Z = 2o.2n("k", "2m");\n o(i=0;i<=Z.h-1;i++) { Z[i].J = "Y" + i; }\n}\n\n2l(1x)\n\n\n',62,308,'|||||var||||the||element||function|if|is|document|length|||input|This|evt|row_list|for|return|in|to||table|of|it|target|be|action|null||false|form|element_index|row_item|row_begin|element_list|will|focus|id|true|old_index|target_index|and|row|fake_table|with|predicate_result|end_table|columnPredicate|first|have|act|License|checkbox|inputs|checked|can|event||an|End|matchChunk|id_chunks|string|fake_row|appendChild|fake_cell|row_element_list|createElement|first_element|not|item_list|end_line|while|rowPredicate|current|bit|first_text_input|FIRST_RESULT|autofocus|class|Software|Free|program|Public|General|GNU|or|indexAllCheckBoxesAtBTInstallationOnLoad|used|check_option|high|low|Math|left|by|part|from|method_name|main_form|main_form_id|key_code|modify|autoFocus|matchRightFieldset|matchLeftFieldset|buildTables|fix_height|_|FIELDSET|tagName|chunk_value|separator|container|tableClassName|push|put|line|end_row|value|returns|When|singleNodeValue|first_text_input_expr|evaluate|text|at|The|else|first_autofocus_expr|get|button|click|user|when|submitAction|Foundation|version|addLoadEvent|shift_check_support|getElementsByTagAndClassName|window|Installation|Template|Business|basically|Part|getElementById|max|min|shiftKey|substr|column|usual|easilly|reused|ID|remove|srcElement|shiftCheck|getElement|keyCode|submitFormOnEnter|main|respective|pressed|ENTER|catch|fake|fieldset|getElementsByTagName|fixLeftRightHeightAndFocus|use|right|ignored|split|td|tr|insertBefore|className|parentNode|cell|one|just|create|Do|nextSibling|place|DOM|existing|siblings|must|items|Hardcoded|passed|Element|use_element|imlies|bitfield|initial_element|skipped|started|new|bool|elements|build|code|Generic|field_your_search_text|name|type|everywhere|auto|annoying|too|because|disabled|following|FIRST_ORDERED_NODE_TYPE|XPathResult|view|title|generally|field|search|which|no|forms|clickSaveButton|back|usefull|actually|behaviour|original|reset|better|before|changed|may|As|save|called|submit|USA|1307|02111|MA|Boston|330|Suite|Place|Temple|59|Inc|write|this|along|copy|received|should|You|details|more|See|PURPOSE|PARTICULAR|FOR|FITNESS|MERCHANTABILITY|warranty|implied|even|without|WARRANTY|ANY|WITHOUT|but|useful|that|hope|distributed|later|any|option|your|either|published|as|terms|under|redistribute|you|Reserved|Rights|All|Contributors|SARL|Nexedi|2006|20xx|Copyright'.split('|'),0,{}))
##############################################################################
#
# Copyright (c) 2008 Nexedi SA and Contributors. All Rights Reserved.
# Lucas Carvalho <lucas@nexedi.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import unittest
from Products.ERP5Type.CSSPacker import compressCSS
from os.path import abspath, join, dirname
PREFIX = abspath(dirname(__file__))
class TestCSSPacker(unittest.TestCase):
def test_compressCSS(self):
script = open(join(PREFIX, 'input/input_erp5.css')).read()
result = compressCSS(script)
output = open(join(PREFIX, 'output/output_erp5.css')).read()
self.assertEquals(result, output)
def test_CSSStyleWithoutSemicolon(self):
result = compressCSS('.something {color: #FFFFF}')
self.assertEquals('.something{color:#FFFFF;}', result)
def test_CSSStyleAndClassWithSpaces(self):
css = '.something {color: #FFFFFF; border: 0px; }'
result = compressCSS(css)
self.assertEquals('.something{color:#FFFFFF;border:0px;}', result)
def test_CSSClassWithSpecialCharacter(self):
css = 'div#main_content input.button, input[type="submit"] { \
/* XXX Is this case happend in current web implementation ? */ \
background: #fff url(erp5-website-button.png) bottom repeat-x; \
}'
result = compressCSS(css)
expected_result = 'div#main_content input.button, \
input[type="submit"]{background:#fff url(erp5-website-button.png) bottom \
repeat-x;}'
self.assertEquals(result, expected_result)
if __name__ == '__main__':
unittest.main()
##############################################################################
#
# Copyright (c) 2008 Nexedi SA and Contributors. All Rights Reserved.
# Lucas Carvalho <lucas@nexedi.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import unittest
from Products.ERP5Type.JSPacker import compressJavaScript
from os.path import abspath, join, dirname
PREFIX = abspath(dirname(__file__))
class TestJSPacker(unittest.TestCase):
def test_compressJavaScript(self):
script = open(join(PREFIX, 'input/input_erp5.js')).read()
result = compressJavaScript(script)
output = open(join(PREFIX, 'output/output_erp5.js')).read()
self.assertEquals(result, output)
if __name__ == '__main__':
unittest.main()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment