* Speeds up Dragonfly load times (a lot).
This commit is contained in:
+48
-45
@@ -208,34 +208,35 @@ dist_img_DATA := \
|
||||
|
||||
jsdir = $(htdocsdir)/js
|
||||
|
||||
# These *must* be in the order in which they get loaded in the browser
|
||||
dist_js_DATA := \
|
||||
src/www/js/Dragonfly.js \
|
||||
src/www/js/Format.js \
|
||||
src/www/js/Gettext.js \
|
||||
src/www/js/Cookie.js \
|
||||
src/www/js/Location.js \
|
||||
src/www/js/Login.js \
|
||||
src/www/js/Util.js \
|
||||
src/www/js/Widgets.js \
|
||||
src/www/js/ValidatingEntry.js \
|
||||
src/www/js/Preferences.js \
|
||||
src/www/js/AddressBook.js \
|
||||
src/www/js/CalendarDrag.js \
|
||||
src/www/js/CalendarEditor.js \
|
||||
src/www/js/Calendar.js \
|
||||
src/www/js/CalendarLayout.js \
|
||||
src/www/js/CalendarView.js \
|
||||
src/www/js/CalendarWidgets.js \
|
||||
src/www/js/Composer.js \
|
||||
src/www/js/Cookie.js \
|
||||
src/www/js/Dragonfly.js \
|
||||
src/www/js/Format.js \
|
||||
src/www/js/Gettext.js \
|
||||
src/www/js/BongoCalendar.js \
|
||||
src/www/js/JCal.js \
|
||||
src/www/js/Location.js \
|
||||
src/www/js/Login.js \
|
||||
src/www/js/MailConversationView.js \
|
||||
src/www/js/Mail.js \
|
||||
src/www/js/MailListView.js \
|
||||
src/www/js/MailWidgets.js \
|
||||
src/www/js/Calendar.js \
|
||||
src/www/js/BongoCalendar.js \
|
||||
src/www/js/CalendarEditor.js \
|
||||
src/www/js/OccurrenceEditor.js \
|
||||
src/www/js/Preferences.js \
|
||||
src/www/js/Search.js \
|
||||
src/www/js/CalendarView.js \
|
||||
src/www/js/CalendarLayout.js \
|
||||
src/www/js/CalendarDrag.js \
|
||||
src/www/js/CalendarWidgets.js \
|
||||
src/www/js/Summary.js \
|
||||
src/www/js/Util.js \
|
||||
src/www/js/ValidatingEntry.js \
|
||||
src/www/js/Widgets.js \
|
||||
src/www/js/Search.js \
|
||||
src/www/js/Mail.js \
|
||||
src/www/js/MailWidgets.js \
|
||||
src/www/js/Composer.js \
|
||||
src/www/js/MailConversationView.js \
|
||||
src/www/js/MailListView.js \
|
||||
src/www/js/Browser.js \
|
||||
src/www/js/BrowserCheck.js
|
||||
|
||||
@@ -246,37 +247,38 @@ dist_prototype_DATA := \
|
||||
|
||||
mochidir = $(jsdir)/lib/MochiKit
|
||||
|
||||
# These *must* be in the order in which they get loaded in the browser/MochiKit
|
||||
dist_mochi_DATA := \
|
||||
src/www/js/lib/MochiKit/Base.js \
|
||||
src/www/js/lib/MochiKit/Iter.js \
|
||||
src/www/js/lib/MochiKit/Logging.js \
|
||||
src/www/js/lib/MochiKit/DateTime.js \
|
||||
src/www/js/lib/MochiKit/Format.js \
|
||||
src/www/js/lib/MochiKit/Async.js \
|
||||
src/www/js/lib/MochiKit/Base.js \
|
||||
src/www/js/lib/MochiKit/Color.js \
|
||||
src/www/js/lib/MochiKit/DateTime.js \
|
||||
src/www/js/lib/MochiKit/DOM.js \
|
||||
src/www/js/lib/MochiKit/Format.js \
|
||||
src/www/js/lib/MochiKit/Iter.js \
|
||||
src/www/js/lib/MochiKit/interpreter.js \
|
||||
src/www/js/lib/MochiKit/Logging.js \
|
||||
src/www/js/lib/MochiKit/LoggingPane.js \
|
||||
src/www/js/lib/MochiKit/MochiKit.js \
|
||||
src/www/js/lib/MochiKit/MochiKit-packed.js \
|
||||
src/www/js/lib/MochiKit/MockDOM.js \
|
||||
src/www/js/lib/MochiKit/__package__.js \
|
||||
src/www/js/lib/MochiKit/Color.js \
|
||||
src/www/js/lib/MochiKit/Signal.js \
|
||||
src/www/js/lib/MochiKit/SimpleTest.js \
|
||||
src/www/js/lib/MochiKit/Test.js \
|
||||
src/www/js/lib/MochiKit/TestRunner.js \
|
||||
src/www/js/lib/MochiKit/Visual.js
|
||||
src/www/js/lib/MochiKit/Visual.js \
|
||||
src/www/js/lib/MochiKit/MochiKit.js \
|
||||
src/www/js/lib/MochiKit/interpreter.js
|
||||
|
||||
scriptaculousdir = $(jsdir)/lib/script.aculo.us
|
||||
|
||||
dist_scriptaculous_DATA := \
|
||||
src/www/js/lib/script.aculo.us/builder.js \
|
||||
src/www/js/lib/script.aculo.us/controls.js \
|
||||
src/www/js/lib/script.aculo.us/dragdrop.js \
|
||||
src/www/js/lib/script.aculo.us/effects.js \
|
||||
src/www/js/lib/script.aculo.us/scriptaculous.js \
|
||||
src/www/js/lib/script.aculo.us/slider.js \
|
||||
src/www/js/lib/script.aculo.us/unittest.js
|
||||
src/www/js/lib/script.aculo.us/effects.js
|
||||
|
||||
finaljsdir = $(jsdir)
|
||||
|
||||
dist_finaljs_DATA = \
|
||||
src/www/js/final.js
|
||||
|
||||
compress_script := $(top_srcdir)/src/www/compress.py
|
||||
|
||||
src/www/js/final.js:
|
||||
$(compress_script) $(dist_js_DATA) -o src/www/js/compiled.js -m -l 1 && \
|
||||
$(compress_script) $(dist_prototype_DATA) $(dist_scriptaculous_DATA) $(dist_mochi_DATA) src/www/js/compiled.js -o src/www/js/final.js -q -l 0
|
||||
|
||||
install-data-local:: install-dist_htdocsDATA
|
||||
ln -sf dragonfly.html "$(DESTDIR)$(htdocsdir)/index.html"
|
||||
@@ -362,7 +364,8 @@ sbin_SCRIPTS += \
|
||||
src/www/bongo-standalone
|
||||
|
||||
dist_noinst_SCRIPTS += \
|
||||
src/www/l10n/props2json
|
||||
src/www/l10n/props2json \
|
||||
src/www/compress.py
|
||||
|
||||
templatesdir = $(pkgdatadir)/templates
|
||||
|
||||
|
||||
Executable
+149
@@ -0,0 +1,149 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Compresses Javascript/CSS.
|
||||
|
||||
import re, sys, os
|
||||
from optparse import OptionParser
|
||||
|
||||
class JavascriptCompressor(object):
|
||||
|
||||
def __init__(self, compressionLevel=2, removeLineBreaks=False):
|
||||
self.compressionLevel = compressionLevel
|
||||
self.removeLineBreaks = removeLineBreaks
|
||||
|
||||
# a bunch of regexes used in compression
|
||||
# first, exempt string literals from compression by transient substitution
|
||||
findLiterals = re.compile(r'(\'.*?(?<=[^\\])\')|(\".*?(?<=[^\\])\")')
|
||||
stringMarker = '@s@t@r@'
|
||||
backSubst = re.compile(stringMarker) # put the string literals back in
|
||||
|
||||
mlc = re.compile(r'/\*.*?\*\/', re.DOTALL) # remove multiline comments
|
||||
slc = re.compile('\/\/.*') # remove single line comments
|
||||
|
||||
collapseWs = re.compile('(?<=\S)[ \t]+') # collapse successive non-leading white space characters into one
|
||||
squeeze = re.compile(
|
||||
'''
|
||||
\s+(?=[\}\]\)]) | # remove whitespace including linebreaks preceding closing brackets or braces
|
||||
(?<=[\{\;\,\(])\s+ | # ... or following such
|
||||
[ \t]+(?=\W) | # remove spaces or tabs preceding non-word characters
|
||||
(?<=\W)[ \t]+ # ... or following such. This also will remove leading whitespace
|
||||
'''
|
||||
, re.DOTALL | re.VERBOSE)
|
||||
|
||||
def compress(self, script):
|
||||
'''
|
||||
perform compression and return compressed script
|
||||
'''
|
||||
if not self.compressionLevel:
|
||||
return script
|
||||
|
||||
# first, substitute string literals by placeholders to prevent the regexes messing with them
|
||||
literals = []
|
||||
|
||||
def insertMarker(mo):
|
||||
literals.append(mo.group())
|
||||
return self.stringMarker
|
||||
|
||||
script = self.findLiterals.sub(insertMarker, script)
|
||||
|
||||
# now, to the literal-free carcass, apply some kludgy regexes for deflation...
|
||||
script = self.slc.sub('', script) # remove single line comments
|
||||
script = self.mlc.sub('\n', script) # replace multiline comments by newlines
|
||||
script = self.collapseWs.sub(' ', script) # collapse multiple whitespace characters
|
||||
|
||||
# remove empty lines and trailing whitespace
|
||||
script = '\n'.join([l.rstrip() for l in script.splitlines() if l.strip()])
|
||||
|
||||
if self.compressionLevel > 1:
|
||||
script = self.squeeze.sub('', script) # squeeze out any dispensible white space
|
||||
|
||||
if self.removeLineBreaks:
|
||||
script = script.replace('\n', '') # get rid of any new lines
|
||||
|
||||
# now back-substitute the string literals
|
||||
literals.reverse()
|
||||
script = self.backSubst.sub(lambda mo: literals.pop(), script)
|
||||
|
||||
return script
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = OptionParser(version="%prog 1.0");
|
||||
parser.add_option('-n', '--nolinebreaks',
|
||||
dest='linebreaks',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help="remove all line breaks in the resulting file [default: %default]")
|
||||
parser.add_option('-q', '--quiet',
|
||||
dest='quiet',
|
||||
action='store_true',
|
||||
default=False,
|
||||
help="be vewwy quiet!")
|
||||
parser.add_option('-m', '--measure',
|
||||
dest='measure',
|
||||
default=False,
|
||||
action='store_true',
|
||||
help="print compression statistics")
|
||||
|
||||
|
||||
parser.add_option('-o', '--output',
|
||||
dest='output',
|
||||
help="file to save resulting compressed javascript file(s) to")
|
||||
parser.add_option('-l', '--level',
|
||||
dest='compression',
|
||||
default=1,
|
||||
type='int',
|
||||
help="level of compression (0 is none, 2 is maximum) [default: %default]")
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
if options.compression > 2 or options.compression < 0:
|
||||
print "Level of compression must be not be less than zero or more than two."
|
||||
sys.exit(1)
|
||||
|
||||
if options.output and os.path.exists(options.output):
|
||||
if options.quiet:
|
||||
print "Warning: output file already exists - overwriting."
|
||||
os.remove(options.output)
|
||||
|
||||
lengthBefore = 0
|
||||
lengthAfter = 0
|
||||
c = JavascriptCompressor(compressionLevel=options.compression, removeLineBreaks=options.linebreaks)
|
||||
|
||||
for arg in args:
|
||||
fn = arg
|
||||
if not options.quiet:
|
||||
print "Compressing " + fn + "..."
|
||||
try:
|
||||
f = open(fn)
|
||||
destfn = fn + '.compressed'
|
||||
writemode = 'w'
|
||||
if options.output:
|
||||
destfn = options.output
|
||||
writemode = 'a'
|
||||
r = open(destfn, writemode)
|
||||
try:
|
||||
data = f.read()
|
||||
lengthBefore += float(len(data))
|
||||
cpr = c.compress(data)
|
||||
lengthAfter += float(len(cpr))
|
||||
r.write(cpr)
|
||||
r.close()
|
||||
finally:
|
||||
f.close()
|
||||
r.close()
|
||||
except:
|
||||
if not options.quiet:
|
||||
print "Warning: failed to compress file " + fn + "."
|
||||
|
||||
if not options.quiet:
|
||||
if options.measure:
|
||||
# Print stats.
|
||||
squeezeRate = int(100*(1-(lengthAfter/lengthBefore)))
|
||||
kbsize = round((lengthBefore - lengthAfter) / 1024, 2)
|
||||
print
|
||||
print "Complete! (overall size reduction of %s" % squeezeRate + "% - " + str(kbsize) + "KB)"
|
||||
elif lengthAfter != 0 and lengthBefore != 0:
|
||||
print
|
||||
print "Complete!"
|
||||
else:
|
||||
print "Error: no input files specified."
|
||||
+2
-49
@@ -15,12 +15,8 @@
|
||||
@import url(css/contacts.css);
|
||||
@import url(css/calendar.css);
|
||||
@import url(css/summary.css);
|
||||
@import url(css/modal.css);
|
||||
@import url(css/tabs.css);
|
||||
</style>
|
||||
<style type="text/css" media="print">
|
||||
@import url(css/print.css);
|
||||
</style>
|
||||
<style type="text/css" media="print">@import url(css/print.css);</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Javascript Warning -->
|
||||
@@ -37,50 +33,7 @@
|
||||
document.write ('<h1 id="loading">Loading...</h1>');
|
||||
// -->
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" src="js/lib/prototype/prototype.js"></script>
|
||||
|
||||
<script type="text/javascript" src="js/lib/script.aculo.us/effects.js"></script>
|
||||
<script type="text/javascript" src="js/lib/script.aculo.us/controls.js"></script>
|
||||
|
||||
<script type="text/javascript" src="js/lib/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="js/lib/MochiKit/interpreter.js"></script>
|
||||
|
||||
<script type="text/javascript" src="js/Dragonfly.js"></script>
|
||||
|
||||
<script type="text/javascript" src="js/Format.js"></script>
|
||||
<script type="text/javascript" src="js/Gettext.js"></script>
|
||||
|
||||
<script type="text/javascript" src="js/Cookie.js"></script>
|
||||
<script type="text/javascript" src="js/Location.js"></script>
|
||||
<script type="text/javascript" src="js/Login.js"></script>
|
||||
<script type="text/javascript" src="js/Util.js"></script>
|
||||
<script type="text/javascript" src="js/Widgets.js"></script>
|
||||
<script type="text/javascript" src="js/ValidatingEntry.js"></script>
|
||||
|
||||
<script type="text/javascript" src="js/Preferences.js"></script>
|
||||
<script type="text/javascript" src="js/Modal.js"></script>
|
||||
|
||||
<script type="text/javascript" src="js/AddressBook.js"></script>
|
||||
|
||||
<script type="text/javascript" src="js/JCal.js"></script>
|
||||
<script type="text/javascript" src="js/Calendar.js"></script>
|
||||
<script type="text/javascript" src="js/BongoCalendar.js"></script>
|
||||
<script type="text/javascript" src="js/CalendarEditor.js"></script>
|
||||
<script type="text/javascript" src="js/OccurrenceEditor.js"></script>
|
||||
<script type="text/javascript" src="js/CalendarView.js"></script>
|
||||
<script type="text/javascript" src="js/CalendarLayout.js"></script>
|
||||
<script type="text/javascript" src="js/CalendarDrag.js"></script>
|
||||
<script type="text/javascript" src="js/CalendarWidgets.js"></script>
|
||||
|
||||
<script type="text/javascript" src="js/Summary.js"></script>
|
||||
<script type="text/javascript" src="js/Search.js"></script>
|
||||
|
||||
<script type="text/javascript" src="js/Mail.js"></script>
|
||||
<script type="text/javascript" src="js/MailWidgets.js"></script>
|
||||
<script type="text/javascript" src="js/Composer.js"></script>
|
||||
<script type="text/javascript" src="js/MailConversationView.js"></script>
|
||||
<script type="text/javascript" src="js/MailListView.js"></script>
|
||||
<script type="text/javascript" src="js/final.js"></script>
|
||||
|
||||
<script language="javascript">
|
||||
<!--
|
||||
|
||||
@@ -444,4 +444,4 @@ Dragonfly.Calendar.monthDragMove = function (occurrence, pos, origin)
|
||||
var state = Dragonfly.Calendar.dragstate;
|
||||
state.buble.style.left = (pos.x - origin.x) + 'px';
|
||||
state.buble.style.top = (pos.y - origin.y) + 'px';
|
||||
}
|
||||
};
|
||||
|
||||
@@ -916,6 +916,7 @@ Dragonfly.translateElements = function ()
|
||||
Dragonfly.start = function ()
|
||||
{
|
||||
var d = Dragonfly;
|
||||
|
||||
var p = d.Preferences;
|
||||
var c = d.Calendar;
|
||||
|
||||
|
||||
+2
-2
@@ -51,10 +51,10 @@ Dragonfly.login = function (user)
|
||||
if (!d.authToken) {
|
||||
d.authToken = btoa (user + ':');
|
||||
}
|
||||
|
||||
|
||||
d.setLoginMessage (_('loggingInMessage'));
|
||||
d.setLoginDisabled (true);
|
||||
|
||||
|
||||
p.load().addCallbacks (
|
||||
function (prefs) {
|
||||
return loginSucceeded ();
|
||||
|
||||
@@ -136,7 +136,7 @@ Dragonfly.Preferences.reset = function()
|
||||
var p = Dragonfly.Preferences;
|
||||
p.prefs = deepclone (p.defaultPrefs);
|
||||
p.save();
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Dragonfly.Preferences._lookup (obj, path)
|
||||
@@ -159,7 +159,7 @@ Dragonfly.Preferences._lookup = function (obj, path)
|
||||
} catch (e) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Dragonfly.Preferences.get (key)
|
||||
@@ -194,7 +194,7 @@ Dragonfly.Preferences.get = function (key)
|
||||
}
|
||||
|
||||
throw new Error ('Invalid Preference Key ' + key);
|
||||
}
|
||||
};
|
||||
|
||||
Dragonfly.Preferences.set = function (key, value)
|
||||
{
|
||||
@@ -207,7 +207,7 @@ Dragonfly.Preferences.set = function (key, value)
|
||||
return p.save();
|
||||
}
|
||||
throw new Error ('Invalid Preference Key ' + key);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
The Preferences editor (the UI component)
|
||||
@@ -303,7 +303,7 @@ Dragonfly.Preferences.Editor.build = function (loc)
|
||||
}
|
||||
|
||||
logDebug('We just got built.');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Dragonfly.Preferences.Editor.save = function ()
|
||||
@@ -315,7 +315,7 @@ Dragonfly.Preferences.Editor.save = function ()
|
||||
d.Preferences.save();
|
||||
|
||||
this.dispose();
|
||||
}
|
||||
};
|
||||
|
||||
Dragonfly.Preferences.Editor.dispose = function ()
|
||||
{
|
||||
@@ -324,7 +324,7 @@ Dragonfly.Preferences.Editor.dispose = function ()
|
||||
// Send user back to summary.
|
||||
var loc = new d.Location({tab: 'summary'});
|
||||
d.go('#' + loc);
|
||||
}
|
||||
};
|
||||
|
||||
Dragonfly.Preferences.Editor.load = function (loc, jsob)
|
||||
{
|
||||
@@ -336,7 +336,7 @@ Dragonfly.Preferences.Editor.load = function (loc, jsob)
|
||||
$('from').value = jsob.mail.from;
|
||||
|
||||
logDebug('We just loaded.');
|
||||
}
|
||||
};
|
||||
|
||||
Dragonfly.Preferences.Editor.buildInterface = function (children, actions, observer)
|
||||
{
|
||||
@@ -360,4 +360,4 @@ Dragonfly.Preferences.Editor.buildInterface = function (children, actions, obser
|
||||
Event.observe (ids[i], 'click', bind (clickHandler, observer || this));
|
||||
logDebug('Done!');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user