summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2010-11-25 17:22:58 +0100
committerYorhel <git@yorhel.nl>2010-11-25 17:38:16 +0100
commit625871cba8a2fe71c70b3d2946a5f37993d1f263 (patch)
tree1288db3b6ea43467251a6039a26e861326f0babe
parent7004c8352cda3c81e547aabc037fd9ec7f03172c (diff)
JS: Split script.js into a separate file for each language
This greatly reduces the size of the Javascript file. The compressed size has been reduced with about 9kB, and is now a total of 14kB for en.js. A nice property of this is that more translations can be added without increasing the JS size. While I was at it, I made jsgen.pl also replace mt() function calls in cases where an exact TL string was requested without any additional arguments and/or formatting codes. This helped reduce the compressed size by about 1kB. My aim is to keep *all* the JS code of VNDB smaller than the jQuery core library, as a general "fuck you" towards users of large and bloated JS libraries. We must keep the VNDB page loading times lower than that of other sites, after all!
-rw-r--r--.gitignore2
-rw-r--r--ChangeLog3
-rw-r--r--Makefile11
-rw-r--r--data/script.js10
-rw-r--r--lib/VNDB/Util/LayoutHTML.pm2
-rwxr-xr-xutil/jsgen.pl117
6 files changed, 79 insertions, 66 deletions
diff --git a/.gitignore b/.gitignore
index 94b0eee6..c4732a40 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,7 +2,7 @@
/data/multi.pid
/data/docs/8
/data/log/
-/static/f/script.js
+/static/f/js/
/static/feeds/
/static/s/*/style.css
/static/s/*/boxbg.png
diff --git a/ChangeLog b/ChangeLog
index 5087f702..9248b761 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,7 +2,8 @@
- Improved release filter selection interface
- Added Atom feeds for the recent announcements, changes and posts
(located in /www/feeds and updated every 15 min. by Multi::Feed)
- - Reverted to the old selection box date selector
+ - JS: Reverted to the old selection box date selector
+ - JS: Split script.js into a separate file for each language
- Improved performance of update_vnpopularity() on PostgreSQL 9.0
- Added WHEN clause to all SQL TRIGGERs for which it was useful
(this *requires* PostgreSQL 9.0 or up!)
diff --git a/Makefile b/Makefile
index 51ceb86f..8496bd9f 100644
--- a/Makefile
+++ b/Makefile
@@ -42,9 +42,9 @@
all: dirs js skins robots data/config.pl
-dirs: static/cv static/sf static/st data/log www www/feeds
+dirs: static/f/js static/cv static/sf static/st data/log www www/feeds
-js: static/f/script.js
+js: static/f/js/en.js
skins: static/s/*/style.css
@@ -54,10 +54,10 @@ static/cv static/sf static/st:
mkdir $@;
for i in $$(seq -w 0 1 99); do mkdir "$@/$$i"; done
-data/log www www/feeds:
+static/f/js data/log www www/feeds:
mkdir $@
-static/f/script.js: data/script.js data/lang.txt util/jsgen.pl data/config.pl data/global.pl
+static/f/js/en.js: data/script.js data/lang.txt util/jsgen.pl data/config.pl data/global.pl
util/jsgen.pl
static/s/%/style.css: static/s/%/conf util/skingen.pl data/style.css
@@ -68,7 +68,7 @@ static/s/%/style.css: static/s/%/conf util/skingen.pl data/style.css
echo 'Disallow: /' >> $@
chmod: all
- chmod a-x+rw static/f/script.js
+ chmod a+xrw static/f/js
chmod -R a-x+rwX static/{cv,sf,st}
chmod a-x+rw static/s/*/{style.css,boxbg.png}
@@ -149,6 +149,7 @@ update-2.13: all
$(multi-start)
update-2.14: all
+ rm static/s/script.js
$(multi-stop)
${runpsql} < util/updates/update_2.14.sql
$(multi-start)
diff --git a/data/script.js b/data/script.js
index 581b6494..696de64d 100644
--- a/data/script.js
+++ b/data/script.js
@@ -31,6 +31,10 @@
* l10n /<perl regex>/
* any keys matching that regex will be included.
*
+ * In the case of an mt('<key>') without any extra arguments, the entire
+ * function call may be replaced by the TL string. In such a case mt()
+ * behaves similar to a preprocessor macro in C.
+ *
* The "_lang_*" keys for all languages for which we have a translation are
* already included automatically.
*/
@@ -181,10 +185,9 @@ function shorten(v, l) {
* - Only supports [_n], ~[, ~]
* - When it finds [quant,_n,..], it will only return the first argument (and doesn't support ~ in an argument)
* assumes that a TL structure called 'L10N_STR' is defined in the header of this file */
-var mt_curlang = byName(byId('lang_select'), 'acronym')[0].className.substr(11, 2);
function mt() {
var key = arguments[0];
- var val = L10N_STR[key] ? L10N_STR[key][mt_curlang] || L10N_STR[key].en : key;
+ var val = L10N_STR[key] ? L10N_STR[key] : key;
for(var i=1; i<arguments.length; i++) {
var expr = '[_'+i+']';
while(val.indexOf(expr) >= 0)
@@ -2229,12 +2232,13 @@ if(byId('advselect') && byId('ti')) {
// Language selector
if(byId('lang_select')) {
var d = byId('lang_select');
+ var curlang = byName(d, 'acronym')[0].className.substr(11, 2);
ddInit(d, 'bottom', function(lnk) {
var lst = tag('ul', null);
for(var i=0; i<L10N_LANG.length; i++) {
var ln = L10N_LANG[i];
var icon = tag('acronym', {'class':'icons lang '+ln}, ' ');
- lst.appendChild(tag('li', {'class':'lang_selector'}, mt_curlang == ln
+ lst.appendChild(tag('li', {'class':'lang_selector'}, curlang == ln
? tag('i', icon, mt('_lang_'+ln))
: tag('a', {href:'/setlang?lang='+ln}, icon, L10N_STR['_lang_'+ln][ln]||mt('_lang_'+ln))
));
diff --git a/lib/VNDB/Util/LayoutHTML.pm b/lib/VNDB/Util/LayoutHTML.pm
index 8b2f9ef1..b5dc3e9c 100644
--- a/lib/VNDB/Util/LayoutHTML.pm
+++ b/lib/VNDB/Util/LayoutHTML.pm
@@ -155,7 +155,7 @@ sub htmlFooter {
a href => $self->{source_url}, mt '_footer_source';
end;
end; # /div maincontent
- script type => 'text/javascript', src => $self->{url_static}.'/f/script.js?'.$self->{version}, '';
+ script type => 'text/javascript', src => $self->{url_static}.'/f/js/'.$self->{l10n}->language_tag().'.js?'.$self->{version}, '';
end; # /body
end; # /html
diff --git a/util/jsgen.pl b/util/jsgen.pl
index 4d82bc95..fd216d7e 100755
--- a/util/jsgen.pl
+++ b/util/jsgen.pl
@@ -22,57 +22,57 @@ use LangFile;
use VNDB::L10N;
-sub l10n {
- # parse the .js code to find the l10n keys to use
- my $js = shift;
- my @keys;
- push @keys, $1 ? quotemeta($1) : qr/$2/ while($js =~ m{(?:mt\('([a-z0-9_]+)'[,\)]|l10n /([^/]+)/)}g);
- # also add the _lang_* for all languages for which we have a translation
- my $jskeys_lang = join '|', VNDB::L10N::languages();
- push @keys, qr/_lang_(?:$jskeys_lang)/;
- # fetch the corresponding text from lang.txt
- my %lang; # key1 => { lang1 => .., lang2 => .. }, key2 => { .. }
+my %lang; # lang1 => { key1 => .., key22 => .. }, lang2 => { .. }
+
+sub l10n_load {
+ # fetch all text from lang.txt
my $lang = LangFile->new(read => "$ROOT/data/lang.txt");
- my $cur; # 0 = none/excluded, 1 = TL lines
my $key;
while((my $l = $lang->read())) {
my $type = shift @$l;
- if($type eq 'key') {
- my $k = shift @$l;
- $cur = grep $k =~ /$_/, @keys;
- $key = $k;
- }
- if($type eq 'tl' && $cur) {
- my($lang, $sync, $val) = @$l;
- next if !$val;
- $lang{$key}{$lang} = $val;
- }
+ $key = shift @$l if $type eq 'key';
+ $lang{$l->[0]}{$key} = $l->[2] if $type eq 'tl';
}
+}
+
+
+sub l10n {
+ my($lang, $js) = @_;
- # generate JS code
+ # parse the .js code and replace mt()'s that can be modified in-place, otherwise add to the @keys
+ my @keys;
+ $js =~ s{(?:mt\('([a-z0-9_]+)'([,\)])|l10n /([^/]+)/)}#
+ my($k, $s, $q) = ($1, $2, $3);
+ my $v = $k ? $lang{$lang}{$k} || $lang{'en'}{$k} : '';
+ if($q) { $q ne '<perl regex>' && push @keys, qr/$q/; '' }
+ elsif($s eq ')' && $v && $v !~ /[\~\[\]]/) {
+ $v =~ s/"/\\"/g;
+ $v =~ s/\n/\\n/g;
+ qq{"$v"}
+ } else {
+ push @keys, quotemeta($k);
+ "mt('$k'$s"
+ }
+ #eg;
+ # also add the _lang_* for all languages for which we have a translation
+ my $jskeys_lang = join '|', VNDB::L10N::languages();
+ push @keys, qr/_lang_(?:$jskeys_lang)/;
+
+ # generate header
my $r = "L10N_STR = {\n";
my $first = 1;
- for my $key (sort keys %lang) {
+ for my $key (sort keys %{$lang{$lang}}) {
+ next if !grep $key =~ /$_/, @keys;
$r .= ",\n" if !$first;
$first = 0;
- $r .= sprintf qq| %s: {\n|, $key !~ /^[a-z0-9_]+$/ ? "'$key'" : $key;;
- my $firstk = 1;
- for (sort keys %{$lang{$key}}) {
- $r .= ",\n" if !$firstk;
- $firstk = 0;
- my $lang = $_;
- $lang = qq{"$lang"} if $lang =~ /^(?:as|do|if|in|is)$/; # reserved two-char words
- my $val = $lang{$key}{$_};
- $val =~ s/"/\\"/g;
- $val =~ s/\n/\\n/g;
- $r .= sprintf qq| %s: "%s"|, $lang, $val;
- }
- $r .= "\n }";
+ my $val = $lang{$lang}{$key} || $lang{'en'}{$key};
+ $val =~ s/"/\\"/g;
+ $val =~ s/\n/\\n/g;
+ $r .= sprintf qq| %s: "%s"|, $key !~ /^[a-z0-9_]+$/ ? "'$key'" : $key, $val;
}
- $r .= "\n};\n";
- $r .= 'L10N_LANG = [ '.join(', ', map qq{"$_"}, VNDB::L10N::languages()).' ];';
- return "$r\n";
+ $r .= "\n};";
+ return ("$r\n", $js);
}
@@ -98,24 +98,31 @@ sub resolutions {
sub jsgen {
- # JavaScript::Minifier::XS doesn't correctly handle perl's unicode,
- # so just do everything in raw bytes instead.
- open my $JS, '<', "$ROOT/data/script.js" or die $!;
+ l10n_load();
+ my $common = '';
+ $common .= resolutions();
+ $common .= sprintf "rlst_rstat = [ %s ];\n", join ', ', map qq{"$_"}, @{$S{rlst_rstat}};
+ $common .= sprintf "rlst_vstat = [ %s ];\n", join ', ', map qq{"$_"}, @{$S{rlst_vstat}};
+ $common .= sprintf "cookie_prefix = '%s';\n", $S{cookie_prefix};
+ $common .= sprintf "age_ratings = [ %s ];\n", join ',', map !defined $_ ? -1 : $_, @{$S{age_ratings}};
+ $common .= sprintf "languages = [ %s ];\n", join ', ', map qq{"$_"}, @{$S{languages}};
+ $common .= sprintf "platforms = [ %s ];\n", join ', ', map qq{"$_"}, @{$S{platforms}};
+ $common .= sprintf "media = [ %s ];\n", join ', ', map qq{"$_"}, sort keys %{$S{media}};
+ $common .= sprintf "release_types = [ %s ];\n", join ', ', map qq{"$_"}, sort @{$S{release_types}};
+ $common .= sprintf "L10N_LANG = [ %s ];\n", join(', ', map qq{"$_"}, VNDB::L10N::languages());
+
+ open my $JS, '<:utf8', "$ROOT/data/script.js" or die $!;
my $js .= join '', <$JS>;
close $JS;
- my $head = encode_utf8(l10n($js)) . "\n";
- $head .= sprintf "rlst_rstat = [ %s ];\n", join ', ', map qq{"$_"}, @{$S{rlst_rstat}};
- $head .= sprintf "rlst_vstat = [ %s ];\n", join ', ', map qq{"$_"}, @{$S{rlst_vstat}};
- $head .= sprintf "cookie_prefix = '%s';\n", $S{cookie_prefix};
- $head .= sprintf "age_ratings = [ %s ];\n", join ',', map !defined $_ ? -1 : $_, @{$S{age_ratings}};
- $head .= sprintf "languages = [ %s ];\n", join ', ', map qq{"$_"}, @{$S{languages}};
- $head .= sprintf "platforms = [ %s ];\n", join ', ', map qq{"$_"}, @{$S{platforms}};
- $head .= sprintf "media = [ %s ];\n", join ', ', map qq{"$_"}, sort keys %{$S{media}};
- $head .= sprintf "release_types = [ %s ];\n", join ', ', map qq{"$_"}, sort @{$S{release_types}};
- $head .= resolutions();
- open my $NEWJS, '>', "$ROOT/static/f/script.js" or die $!;
- print $NEWJS $JavaScript::Minifier::XS::VERSION ? JavaScript::Minifier::XS::minify($head.$js) : $head.$js;
- close $NEWJS;
+
+ for my $l (VNDB::L10N::languages()) {
+ my($head, $body) = l10n($l, $js);
+ # JavaScript::Minifier::XS doesn't correctly handle perl's unicode, so manually encode
+ my $content = encode_utf8($head . $common . $body);
+ open my $NEWJS, '>', "$ROOT/static/f/js/$l.js" or die $!;
+ print $NEWJS $JavaScript::Minifier::XS::VERSION ? JavaScript::Minifier::XS::minify($content) : $content;
+ close $NEWJS;
+ }
}
jsgen;