Bug 977969: concatenate and slightly minify css files
r=gerv, a=glob git-svn-id: svn://10.0.0.236/trunk@265401 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
932733988c
commit
052c48cbdf
@ -1 +1 @@
|
|||||||
9031
|
9032
|
||||||
1
mozilla/webtools/bugzilla/.gitignore
vendored
1
mozilla/webtools/bugzilla/.gitignore
vendored
@ -10,5 +10,6 @@
|
|||||||
/localconfig
|
/localconfig
|
||||||
/index.html
|
/index.html
|
||||||
|
|
||||||
|
/skins/assets
|
||||||
/skins/contrib/Dusk/admin.css
|
/skins/contrib/Dusk/admin.css
|
||||||
/skins/contrib/Dusk/bug.css
|
/skins/contrib/Dusk/bug.css
|
||||||
|
|||||||
@ -1 +1 @@
|
|||||||
fca0b6cb7133f458352bd8547195f7f0822766f8
|
6d3857e31ab6d39625c2b5703a876d0b13930c18
|
||||||
@ -199,6 +199,8 @@ sub FILESYSTEM {
|
|||||||
dirs => DIR_CGI_WRITE | DIR_ALSO_WS_SERVE },
|
dirs => DIR_CGI_WRITE | DIR_ALSO_WS_SERVE },
|
||||||
"$datadir/db" => { files => CGI_WRITE,
|
"$datadir/db" => { files => CGI_WRITE,
|
||||||
dirs => DIR_CGI_WRITE },
|
dirs => DIR_CGI_WRITE },
|
||||||
|
"$skinsdir/assets" => { files => WS_SERVE,
|
||||||
|
dirs => DIR_CGI_OVERWRITE | DIR_ALSO_WS_SERVE },
|
||||||
|
|
||||||
# Readable directories
|
# Readable directories
|
||||||
"$datadir/mining" => { files => CGI_READ,
|
"$datadir/mining" => { files => CGI_READ,
|
||||||
@ -269,6 +271,7 @@ sub FILESYSTEM {
|
|||||||
$attachdir => DIR_CGI_WRITE,
|
$attachdir => DIR_CGI_WRITE,
|
||||||
$graphsdir => DIR_CGI_WRITE | DIR_ALSO_WS_SERVE,
|
$graphsdir => DIR_CGI_WRITE | DIR_ALSO_WS_SERVE,
|
||||||
$webdotdir => DIR_CGI_WRITE | DIR_ALSO_WS_SERVE,
|
$webdotdir => DIR_CGI_WRITE | DIR_ALSO_WS_SERVE,
|
||||||
|
"$skinsdir/assets" => DIR_CGI_WRITE | DIR_ALSO_WS_SERVE,
|
||||||
# Directories that contain content served directly by the web server.
|
# Directories that contain content served directly by the web server.
|
||||||
"$skinsdir/custom" => DIR_WS_SERVE,
|
"$skinsdir/custom" => DIR_WS_SERVE,
|
||||||
"$skinsdir/contrib" => DIR_WS_SERVE,
|
"$skinsdir/contrib" => DIR_WS_SERVE,
|
||||||
@ -475,6 +478,7 @@ EOT
|
|||||||
|
|
||||||
_remove_empty_css_files();
|
_remove_empty_css_files();
|
||||||
_convert_single_file_skins();
|
_convert_single_file_skins();
|
||||||
|
_remove_dynamic_css_files();
|
||||||
}
|
}
|
||||||
|
|
||||||
sub _remove_empty_css_files {
|
sub _remove_empty_css_files {
|
||||||
@ -519,6 +523,14 @@ sub _convert_single_file_skins {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# delete all automatically generated css files to force recreation at the next
|
||||||
|
# request.
|
||||||
|
sub _remove_dynamic_css_files {
|
||||||
|
foreach my $file (glob(bz_locations()->{skinsdir} . '/assets/*.css')) {
|
||||||
|
unlink($file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sub create_htaccess {
|
sub create_htaccess {
|
||||||
_create_files(%{FILESYSTEM()->{htaccess}});
|
_create_files(%{FILESYSTEM()->{htaccess}});
|
||||||
|
|
||||||
|
|||||||
@ -26,9 +26,11 @@ use Bugzilla::Token;
|
|||||||
use Cwd qw(abs_path);
|
use Cwd qw(abs_path);
|
||||||
use MIME::Base64;
|
use MIME::Base64;
|
||||||
use Date::Format ();
|
use Date::Format ();
|
||||||
|
use Digest::MD5 qw(md5_hex);
|
||||||
use File::Basename qw(basename dirname);
|
use File::Basename qw(basename dirname);
|
||||||
use File::Find;
|
use File::Find;
|
||||||
use File::Path qw(rmtree mkpath);
|
use File::Path qw(rmtree mkpath);
|
||||||
|
use File::Slurp;
|
||||||
use File::Spec;
|
use File::Spec;
|
||||||
use IO::Dir;
|
use IO::Dir;
|
||||||
use List::MoreUtils qw(firstidx);
|
use List::MoreUtils qw(firstidx);
|
||||||
@ -422,10 +424,12 @@ sub mtime_filter {
|
|||||||
|
|
||||||
# Set up the skin CSS cascade:
|
# Set up the skin CSS cascade:
|
||||||
#
|
#
|
||||||
# 1. YUI CSS
|
# 1. standard/global.css
|
||||||
# 2. Standard Bugzilla stylesheet set (persistent)
|
# 2. YUI CSS
|
||||||
# 3. Third-party "skin" stylesheet set, per user prefs (persistent)
|
# 3. Standard Bugzilla stylesheet set
|
||||||
# 4. Custom Bugzilla stylesheet set (persistent)
|
# 4. Third-party "skin" stylesheet set, per user prefs
|
||||||
|
# 5. Inline css passed to global/header.html.tmpl
|
||||||
|
# 6. Custom Bugzilla stylesheet set
|
||||||
|
|
||||||
sub css_files {
|
sub css_files {
|
||||||
my ($style_urls, $yui, $yui_css) = @_;
|
my ($style_urls, $yui, $yui_css) = @_;
|
||||||
@ -448,7 +452,12 @@ sub css_files {
|
|||||||
push(@{ $by_type{$key} }, $set->{$key});
|
push(@{ $by_type{$key} }, $set->{$key});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# build unified
|
||||||
|
$by_type{unified_standard_skin} = _concatenate_css($by_type{standard},
|
||||||
|
$by_type{skin});
|
||||||
|
$by_type{unified_custom} = _concatenate_css($by_type{custom});
|
||||||
|
|
||||||
return \%by_type;
|
return \%by_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -456,30 +465,85 @@ sub _css_link_set {
|
|||||||
my ($file_name) = @_;
|
my ($file_name) = @_;
|
||||||
|
|
||||||
my %set = (standard => mtime_filter($file_name));
|
my %set = (standard => mtime_filter($file_name));
|
||||||
|
|
||||||
# We use (^|/) to allow Extensions to use the skins system if they
|
# We use (?:^|/) to allow Extensions to use the skins system if they want.
|
||||||
# want.
|
if ($file_name !~ m{(?:^|/)skins/standard/}) {
|
||||||
if ($file_name !~ m{(^|/)skins/standard/}) {
|
|
||||||
return \%set;
|
return \%set;
|
||||||
}
|
}
|
||||||
|
|
||||||
my $skin = Bugzilla->user->settings->{skin}->{value};
|
my $skin = Bugzilla->user->settings->{skin}->{value};
|
||||||
my $cgi_path = bz_locations()->{'cgi_path'};
|
my $cgi_path = bz_locations()->{'cgi_path'};
|
||||||
my $skin_file_name = $file_name;
|
my $skin_file_name = $file_name;
|
||||||
$skin_file_name =~ s{(^|/)skins/standard/}{skins/contrib/$skin/};
|
$skin_file_name =~ s{(?:^|/)skins/standard/}{skins/contrib/$skin/};
|
||||||
if (my $mtime = _mtime("$cgi_path/$skin_file_name")) {
|
if (my $mtime = _mtime("$cgi_path/$skin_file_name")) {
|
||||||
$set{skin} = mtime_filter($skin_file_name, $mtime);
|
$set{skin} = mtime_filter($skin_file_name, $mtime);
|
||||||
}
|
}
|
||||||
|
|
||||||
my $custom_file_name = $file_name;
|
my $custom_file_name = $file_name;
|
||||||
$custom_file_name =~ s{(^|/)skins/standard/}{skins/custom/};
|
$custom_file_name =~ s{(?:^|/)skins/standard/}{skins/custom/};
|
||||||
if (my $custom_mtime = _mtime("$cgi_path/$custom_file_name")) {
|
if (my $custom_mtime = _mtime("$cgi_path/$custom_file_name")) {
|
||||||
$set{custom} = mtime_filter($custom_file_name, $custom_mtime);
|
$set{custom} = mtime_filter($custom_file_name, $custom_mtime);
|
||||||
}
|
}
|
||||||
|
|
||||||
return \%set;
|
return \%set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub _concatenate_css {
|
||||||
|
my @sources = map { @$_ } @_;
|
||||||
|
return unless @sources;
|
||||||
|
|
||||||
|
my %files =
|
||||||
|
map {
|
||||||
|
(my $file = $_) =~ s/(^[^\?]+).+/$1/;
|
||||||
|
$_ => $file;
|
||||||
|
} @sources;
|
||||||
|
|
||||||
|
my $cgi_path = bz_locations()->{cgi_path};
|
||||||
|
my $skins_path = bz_locations()->{skinsdir};
|
||||||
|
|
||||||
|
# build minified files
|
||||||
|
my @minified;
|
||||||
|
foreach my $source (@sources) {
|
||||||
|
next unless -e "$cgi_path/$files{$source}";
|
||||||
|
my $file = $skins_path . '/assets/' . md5_hex($source) . '.css';
|
||||||
|
if (!-e $file) {
|
||||||
|
my $content = read_file("$cgi_path/$files{$source}");
|
||||||
|
|
||||||
|
# minify
|
||||||
|
$content =~ s{/\*.*?\*/}{}sg; # comments
|
||||||
|
$content =~ s{(^\s+|\s+$)}{}mg; # leading/trailing whitespace
|
||||||
|
$content =~ s{\n}{}g; # single line
|
||||||
|
|
||||||
|
# rewrite urls
|
||||||
|
$content =~ s{url\(([^\)]+)\)}{_css_url_rewrite($source, $1)}eig;
|
||||||
|
|
||||||
|
write_file($file, "/* $files{$source} */\n" . $content . "\n");
|
||||||
|
}
|
||||||
|
push @minified, $file;
|
||||||
|
}
|
||||||
|
|
||||||
|
# concat files
|
||||||
|
my $file = $skins_path . '/assets/' . md5_hex(join(' ', @sources)) . '.css';
|
||||||
|
if (!-e $file) {
|
||||||
|
my $content = '';
|
||||||
|
foreach my $source (@minified) {
|
||||||
|
$content .= read_file($source);
|
||||||
|
}
|
||||||
|
write_file($file, $content);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mtime_filter($file);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub _css_url_rewrite {
|
||||||
|
my ($source, $url) = @_;
|
||||||
|
# rewrite relative urls as the unified stylesheet lives in a different
|
||||||
|
# directory from the source
|
||||||
|
$url =~ s/(^['"]|['"]$)//g;
|
||||||
|
return $url if substr($url, 0, 1) eq '/';
|
||||||
|
return 'url(../../' . dirname($source) . '/' . $url . ')';
|
||||||
|
}
|
||||||
|
|
||||||
# YUI dependency resolution
|
# YUI dependency resolution
|
||||||
sub yui_resolve_deps {
|
sub yui_resolve_deps {
|
||||||
my ($yui, $yui_deps) = @_;
|
my ($yui, $yui_deps) = @_;
|
||||||
|
|||||||
@ -1,20 +1,21 @@
|
|||||||
There are three directories here, standard/, custom/, and contrib/.
|
There are four directories here, standard/, custom/, contrib/, and assets/.
|
||||||
|
|
||||||
standard/ holds the standard stylesheets. These are used no matter
|
standard/ holds the standard stylesheets. These are used no matter what skin
|
||||||
what skin the user selects. If the user selects the "Classic" skin,
|
the user selects. If the user selects the "Classic" skin, then *only* the
|
||||||
then *only* the standard/ stylesheets are used.
|
standard/ stylesheets are used.
|
||||||
|
|
||||||
contrib/ holds "skins" that the user can select in their preferences.
|
contrib/ holds "skins" that the user can select in their preferences. skins
|
||||||
skins are in directories, and they contain files with the same names
|
are in directories, and they contain files with the same names as the files in
|
||||||
as the files in skins/standard/. Simply putting a new directory
|
skins/standard/. Simply putting a new directory into the contrib/ directory
|
||||||
into the contrib/ directory adds a new skin as an option in users'
|
adds a new skin as an option in users' preferences.
|
||||||
preferences.
|
|
||||||
|
|
||||||
custom/ allows you to locally override the standard/ and contrib/ CSS.
|
custom/ allows you to locally override the standard/ and contrib/ CSS. If you
|
||||||
If you put files into the custom/ directory with the same names as the CSS
|
put files into the custom/ directory with the same names as the CSS files in
|
||||||
files in skins/standard/, you can override the standard/ and contrib/
|
skins/standard/, you can override the standard/ and contrib/ CSS. For example,
|
||||||
CSS. For example, if you want to override some CSS in
|
if you want to override some CSS in skins/standard/global.css, then you should
|
||||||
skins/standard/global.css, then you should create a file called "global.css"
|
create a file called "global.css" in custom/ and put some CSS in it. The CSS
|
||||||
in custom/ and put some CSS in it. The CSS you put into files in custom/ will
|
you put into files in custom/ will be used *in addition* to the CSS in
|
||||||
be used *in addition* to the CSS in skins/standard/ or the CSS in
|
skins/standard/ or the CSS in skins/contrib/. It will apply to every skin.
|
||||||
skins/contrib/. It will apply to every skin.
|
|
||||||
|
assets/ holds the minified and concatenated files which are created by
|
||||||
|
checksetup.pl and Bugzilla::Template. Do not edit the files in this directory.
|
||||||
|
|||||||
@ -90,35 +90,20 @@
|
|||||||
[% PROCESS 'global/setting-descs.none.tmpl' %]
|
[% PROCESS 'global/setting-descs.none.tmpl' %]
|
||||||
|
|
||||||
[% SET yui = yui_resolve_deps(yui, yui_deps) %]
|
[% SET yui = yui_resolve_deps(yui, yui_deps) %]
|
||||||
|
|
||||||
[% SET css_sets = css_files(style_urls, yui, yui_css) %]
|
[% SET css_sets = css_files(style_urls, yui, yui_css) %]
|
||||||
|
<link href="[% css_sets.unified_standard_skin FILTER html %]"
|
||||||
|
rel="stylesheet" type="text/css">
|
||||||
|
|
||||||
[%# CSS cascade, parts 1 & 2: YUI & Standard Bugzilla stylesheet set (persistent).
|
|
||||||
# Always present. %]
|
|
||||||
<link href="[% 'skins/standard/global.css' FILTER mtime FILTER html %]"
|
|
||||||
rel="alternate stylesheet"
|
|
||||||
title="[% setting_descs.standard FILTER html %]">
|
|
||||||
[% FOREACH style_url = css_sets.standard %]
|
|
||||||
[% PROCESS format_css_link css_set_name = 'standard' %]
|
|
||||||
[% END %]
|
|
||||||
|
|
||||||
[%# CSS cascade, part 3: Third-party stylesheet set, per user prefs. %]
|
|
||||||
[% FOREACH style_url = css_sets.skin %]
|
|
||||||
[% PROCESS format_css_link css_set_name = user.settings.skin.value %]
|
|
||||||
[% END %]
|
|
||||||
|
|
||||||
[%# CSS cascade, part 4: page-specific styles. %]
|
|
||||||
[% IF style %]
|
[% IF style %]
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
[% style %]
|
[% style %]
|
||||||
</style>
|
</style>
|
||||||
[% END %]
|
[% END %]
|
||||||
|
|
||||||
[%# CSS cascade, part 5: Custom Bugzilla stylesheet set (persistent).
|
[% IF css_sets.unified_custom %]
|
||||||
# Always present. Site administrators may override all other style
|
<link href="[% css_sets.unified_custom FILTER html %]"
|
||||||
# definitions, including skins, using custom stylesheets.
|
rel="stylesheet" type="text/css">
|
||||||
#%]
|
|
||||||
[% FOREACH style_url = css_sets.custom %]
|
|
||||||
[% PROCESS format_css_link css_set_name = 'standard' %]
|
|
||||||
[% END %]
|
[% END %]
|
||||||
|
|
||||||
[%# YUI Scripts %]
|
[%# YUI Scripts %]
|
||||||
@ -265,19 +250,6 @@
|
|||||||
<div id="message">[% message %]</div>
|
<div id="message">[% message %]</div>
|
||||||
[% END %]
|
[% END %]
|
||||||
|
|
||||||
[% BLOCK format_css_link %]
|
|
||||||
[% IF css_set_name == 'standard' %]
|
|
||||||
[% SET css_title_link = '' %]
|
|
||||||
[% ELSE %]
|
|
||||||
[% css_title_link = BLOCK ~%]
|
|
||||||
title="[% setting_descs.${user.settings.skin.value} || user.settings.skin.value FILTER html %]"
|
|
||||||
[% END %]
|
|
||||||
[% END %]
|
|
||||||
|
|
||||||
<link href="[% style_url FILTER html %]" rel="stylesheet"
|
|
||||||
type="text/css" [% css_title_link FILTER none %]>
|
|
||||||
[% END %]
|
|
||||||
|
|
||||||
[% BLOCK format_js_link %]
|
[% BLOCK format_js_link %]
|
||||||
<script type="text/javascript" src="[% javascript_url FILTER mtime FILTER html %]"></script>
|
<script type="text/javascript" src="[% javascript_url FILTER mtime FILTER html %]"></script>
|
||||||
[% END %]
|
[% END %]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user