Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Item14185: improved cache maintenance
- add a rest handler to purge the cache occasionally
- update cache files when source css/js is newer
- do not remove type info on script, link and style elems
- do not optimize javascript by default, PatternSkin doesn't cope well with it yet
  • Loading branch information
MichaelDaum committed Sep 9, 2016
1 parent 1d54d5b commit 4030deb
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 30 deletions.
14 changes: 7 additions & 7 deletions .gitignore
@@ -1,8 +1,8 @@
*.swp
PageOptimizerPlugin.md5
PageOptimizerPlugin.sha1
PageOptimizerPlugin.tgz
PageOptimizerPlugin.txt
PageOptimizerPlugin.zip
PageOptimizerPlugin_installer
PageOptimizerPlugin_installer.pl
/PageOptimizerPlugin.md5
/PageOptimizerPlugin.sha1
/PageOptimizerPlugin.tgz
/PageOptimizerPlugin.txt
/PageOptimizerPlugin.zip
/PageOptimizerPlugin_installer
/PageOptimizerPlugin_installer.pl
1 change: 1 addition & 0 deletions data/System/PageOptimizerPlugin.txt
Expand Up @@ -69,6 +69,7 @@ the =refresh= url parameter:
%$DEPENDENCIES%

---++ Change History
| 09 Sep 2016: | improved cache handling, i.e. added a rest handler to purge the cache occasionally |
| 13 Jun 2016: | fixed compatibility with <nop>AngularPlugin/AngularSkin; performance improvements |
| 23 Feb 2015: | remove some bogus non-macros if left over, such as REVISIONS, REVTITLE, REVARG, QUERYPARAMSTRING |
| 04 Apr 2014: | flag rest handlers that don't require authentication |
Expand Down
24 changes: 11 additions & 13 deletions lib/Foswiki/Plugins/PageOptimizerPlugin.pm
Expand Up @@ -24,8 +24,8 @@ use Digest::MD5 ();
use URI ();
use Compress::Zlib ();

our $VERSION = '2.00';
our $RELEASE = '10 Jun 2016';
our $VERSION = '2.10';
our $RELEASE = '09 Sep 2016';
our $SHORTDESCRIPTION = 'Optimize html markup, as well as js and css';
our $NO_PREFS_IN_TOPIC = 1;
our $core;
Expand All @@ -42,6 +42,12 @@ sub initPlugin {
http_allow => 'GET',
);

Foswiki::Func::registerRESTHandler('purgeCache', sub { return getCore()->purgeCache(@_); },
authenticate => 0,
validate => 0,
http_allow => 'GET,POST',
);

return 1;
}

Expand Down Expand Up @@ -69,6 +75,9 @@ sub getStats {
sub finishPlugin {
$core->finish if defined $core;
$stats->finish if defined $stats;

undef $core;
undef $stats;
}

###############################################################################
Expand Down Expand Up @@ -101,10 +110,6 @@ sub completePageHandler {
$text =~ s/\%\{(<pre[^>]*>)\}&#37;\s*/$1/g;
$text =~ s/\s*&#37;\{(<\/pre>)\}\%/$1/g;

$text =~ s/<script +type=["']text\/javascript["']/<script/g;
$text =~ s/<style +type=["']text\/css["']/<style/g;
$text =~ s/<link (.*?rel=["']stylesheet["'].*?)\/>/_processLinkStyle($1)/ge;

# make empty table cells really empty
$text =~ s/(<td[^>]*>)\s+(<\/td>)/$1$2/gs;

Expand Down Expand Up @@ -146,11 +151,4 @@ sub _processCite {
return "<div class='$class'>".$block."</div>";
}

###############################################################################
sub _processLinkStyle {
my $args = shift;
$args =~ s/type=["'].*?["']//g;
return "<link $args/>";
}

1;
14 changes: 12 additions & 2 deletions lib/Foswiki/Plugins/PageOptimizerPlugin/Config.spec
Expand Up @@ -9,7 +9,7 @@ $Foswiki::cfg{PageOptimizerPlugin}{CleanUpHTML} = 1;

# **BOOLEAN**
# If enabled, all JavaScript files will be combined and cached into one file.
$Foswiki::cfg{PageOptimizerPlugin}{OptimizeJavaScript} = 1;
$Foswiki::cfg{PageOptimizerPlugin}{OptimizeJavaScript} = 0;

# **BOOLEAN**
# If enabled, all stylesheets will be combined and cached into one file.
Expand All @@ -28,11 +28,21 @@ $Foswiki::cfg{PageOptimizerPlugin}{GatherStatistics} = 0;
# This regular expression lets you specify a pattern matching JavaScript files to
# be excluded from caching. For instance, TinyMCEPlugin is known to break when
# processed by the optimizer.
$Foswiki::cfg{PageOptimizerPlugin}{ExcludeJavaScript} = 'TinyMCEPlugin';
$Foswiki::cfg{PageOptimizerPlugin}{ExcludeJavaScript} = 'TinyMCEPlugin|hyphenator';

# **REGEX**
# This regular expression lets you specify a pattern matching style sheets to
# be excluded from caching.
$Foswiki::cfg{PageOptimizerPlugin}{ExcludeCss} = '';

# **URLPATH CHECK="emptyok undefok"**
# Url path where optimized javascript and css is located. Note this has to match
# the PATH parameter below.
$Foswiki::cfg{PageOptimizerPlugin}{CachePath} = '';

# **PATH CHECK="emptyok undefok"**
# File path where optimized javascript and css is stored. Note this has to
# match the URL parameter above.
$Foswiki::cfg{PageOptimizerPlugin}{CacheDir} = '';

1;
56 changes: 48 additions & 8 deletions lib/Foswiki/Plugins/PageOptimizerPlugin/Core.pm
Expand Up @@ -69,8 +69,13 @@ sub optimizeJavaScript {
# collect all javascript
my @jsUrls = ();
my $excludePattern = '';
$excludePattern = '(?!.*(?:'.$Foswiki::cfg{PageOptimizerPlugin}{ExcludeJavaScript}.'))'
if defined $Foswiki::cfg{PageOptimizerPlugin}{ExcludeJavaScript};

# if we defined JQueryVersionForOldIEs then the jQuery core lib has to be excluded from the process
if (defined $Foswiki::cfg{PageOptimizerPlugin}{ExcludeJavaScript} || $Foswiki::cfg{JQueryPlugin}{JQueryVersionForOldIEs}) {
$excludePattern = '(?!.*(?:' . $Foswiki::cfg{PageOptimizerPlugin}{ExcludeJavaScript} . ($Foswiki::cfg{JQueryPlugin}{JQueryVersionForOldIEs} ? '|jquery\-\d\.\d' : '') . '))';
}

#_writeDebug("excludePattern=$excludePattern");

my %classes = ();
$classes{"script"} = 1;
Expand All @@ -96,7 +101,19 @@ sub optimizeJavaScript {
my $query = Foswiki::Func::getCgiQuery();
my $refresh = $query->param("refresh") || '';

if ($refresh =~ /\b(on|all|cache|js)\b/ || !-f $cacheFileName) {
my $cacheFileTime = _getModificationTime($cacheFileName);
my $needsUpdate = 0;
foreach my $url (@jsUrls) {
my $fileName = _url2FileName($url);
my $fileTime = _getModificationTime($fileName);
if ($cacheFileTime < $fileTime) {
$needsUpdate = 1;
_writeDebug("$fileName has been updated ... refreshing cache file");
last;
}
}

if ($needsUpdate || $refresh =~ /\b(on|all|cache|js)\b/ || !-f $cacheFileName) {
# TODO: compare timestamps of files
_writeDebug("creating cache at $cacheFileName");

Expand Down Expand Up @@ -144,15 +161,15 @@ sub optimizeJavaScript {
return $text;
}

###############################
###############################################################################
sub optimizeStylesheets {
my ($this, $text) = @_;

# collect all css
$this->{_cssUrls} = [];
my %classes = ();

while ($text =~ s/((?:<(link) (?:class=["']([^"']+)["'])?.*?rel=["']stylesheet["']\s+href=["'](\/[^"']+)["']\s+media=["']all["'][^\/>]*?\/?>)|(?:<(style)\s+.*?media=["']all["'][^>]*?>(.*?)<\/style>))/$this->_gatherCssUrls($2||$5, $4||$6)||$1/e) {
while ($text =~ s/((?:<(link) (?:class=["']([^"']+)["'])?.*?rel=["']stylesheet["']\s+href=["'](\/[^"']+)["'].*media=["']all["'](?:\s+type=["']text\/css["'])?[^\/>]*?\/?>)|(?:<(style)\s+.*?media=["']all["'][^>]*?>(.*?)<\/style>))/$this->_gatherCssUrls($2||$5, $4||$6)||$1/e) {
if ($3) {
$classes{$_} = 1 foreach split(/ /, $3);
}
Expand All @@ -165,8 +182,19 @@ sub optimizeStylesheets {
my $query = Foswiki::Func::getCgiQuery();
my $refresh = $query->param("refresh") || '';

if ($refresh =~ /\b(on|all|cache|css)\b/ || !-f $cacheFileName) {
# TODO: compare timestamps of files
my $cacheFileTime = _getModificationTime($cacheFileName);
my $needsUpdate = 0;
foreach my $url (@{$this->{_cssUrls}}) {
my $fileName = _url2FileName($url);
my $fileTime = _getModificationTime($fileName);
if ($cacheFileTime < $fileTime) {
$needsUpdate = 1;
_writeDebug("$fileName has been updated ... refreshing cache file");
last;
}
}

if ($needsUpdate || $refresh =~ /\b(on|all|cache|css)\b/ || !-f $cacheFileName) {
_writeDebug("creating cache at $cacheFileName");

my $cachedData = '';
Expand Down Expand Up @@ -194,6 +222,16 @@ sub optimizeStylesheets {
return $text;
}

###############################
sub _getModificationTime {
my ($file) = @_;

return 0 unless $file;

my @stat = stat($file);
return $stat[9] || $stat[10] || 0;
}

###############################
sub _gatherCssUrls {
my ($this, $type, $data) = @_;
Expand Down Expand Up @@ -259,8 +297,10 @@ sub purgeCache {
my @files = map { Foswiki::Sandbox::normalizeFileName($this->{cacheDir} . $_) } grep { !/^(\.|README)/ } readdir $dh;
closedir $dh;

#_writeDebug("cleaning up @files");
_writeDebug("cleaning up ".scalar(@files)." files");
unlink @files;

return;
}

###############################
Expand Down

0 comments on commit 4030deb

Please sign in to comment.