Files
oddmuse/modules/webapp.pl
Aleks-Daniel Jakimenko-Aleksejev 89a23a6ac5 Full support for arrayref in $StyleSheet
2015-10-26 01:03:42 +02:00

202 lines
5.9 KiB
Perl

use strict;
use v5.10;
=head1 NAME
webapp - an Oddmuse module that provides offline wiki browsing
=head1 SYNOPSIS
This module makes a number of files available. These files make up a
web application which will then download the rest of the wiki. The
B<Administration> menu will contain a link to the web application.
=head1 INSTALLATION
Installing a module is easy: Create a modules subdirectory in your
data directory, and put the Perl file in there. It will be loaded
automatically.
=cut
AddModuleDescription('webapp.pl', 'Offline Extension');
our ($q, %IndexHash, $ScriptName, $FullUrl, $StyleSheet, $StyleSheetPage, $SurgeProtection, @MyAdminCode, @MyInitVariables, $LastUpdate);
push(@MyAdminCode, \&WebAppMenu);
sub WebAppMenu {
my ($id, $menuref, $restref) = @_;
push(@$menuref,
ScriptLink('webapp/index.html',
T('Web application for offline browsing'),
'webapp'));
}
push(@MyInitVariables, \&InitWebApp);
my $jquery = 'http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js';
sub InitWebApp {
if ($q->path_info =~ /^\/webapp'/) {
# HACK ALERT: In order to allow the app to cache all the pages, we
# need to disable surge protection for the offline pages.
$SurgeProtection = 0;
}
my $manifest = ScriptUrl('webapp/MANIFEST');
my $oddmuse = ScriptUrl('webapp/oddmuse.js');
if ($q->path_info eq '/webapp/index.html') {
# Switch to HTML5 add link to the manifest listing all the pages
print GetHttpHeader('text/html', $LastUpdate);
print <<EOT;
<!doctype html>
<html lang="en" manifest="$manifest">
<head>
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<meta charset="utf-8">
<title>HomePage</title>
<script type="text/javascript" charset="utf-8" src="$jquery" ></script>
<script type="text/javascript" charset="utf-8" src="$oddmuse" ></script>
</head>
<body>
<h1>HomePage</h1>
<p>Caching the local wiki!</p>
<p id="cache">Caching <span id="page">0</span>/<span id="total">0</span>.</p>
<p id="status">Enable Javascript and reload this page in order to get started.</p>
</body>
</html>
EOT
exit;
} elsif ($q->path_info eq '/webapp/MANIFEST') {
# List all the pages necessary for the offline application.
print GetHttpHeader('text/cache-manifest');
print "CACHE MANIFEST\n";
# index.html
print ScriptUrl('webapp/index.html') . "\n";
# CSS file
if ($StyleSheet) {
print ref $StyleSheet ? join("\n", @$StyleSheet) . "\n" : "$StyleSheet\n";
} elsif ($IndexHash{$StyleSheetPage}) {
print "$ScriptName?action=browse;id=" . UrlEncode($StyleSheetPage)
. ";raw=1;mime-type=text/css\n";
} else {
print "http://www.oddmuse.org/oddmuse.css\n";
}
# javascript
print "$jquery\n";
print "$oddmuse\n";
# default
print "NETWORK:\n";
print "*\n";
exit;
} elsif ($q->path_info eq '/webapp/oddmuse.js') {
print GetHttpHeader('application/javascript', $LastUpdate);
my $quoted_script = quotemeta($ScriptName);
print <<EOT;
var wiki = (function() {
var pages;
var log = function(msg) {
\$("#status").text(msg);
}
var log_html = function(msg) {
\$("#status").html(msg);
}
var log_node = function(msg) {
\$("#status").empty();
\$("#status").append(msg);
}
var get_pages = function(data) {
pages = data.split("\\n");
var count = 1;
pages.pop(); // after the last newline there is nothing
\$("#total").text(pages.length);
var get_page = function(i, id) {
if (id != "") {
var store_page = function(data) {
window.localStorage.setItem(id, data);
\$("#page").text(count++);
}
\$.get("$FullUrl",
{action: "browse", id: id},
store_page);
}
}
\$.each(pages, get_page);
window.localStorage.setItem(" pages", pages.join(" "));
}
var download = function() {
log("Getting list of pages...");
\$.get("$FullUrl",
{action: "index", raw: "1"},
get_pages);
log_html('<p><a href="javascript:wiki.list()">List</a> the pages in local storage.');
}
var initialize = function() {
pages = window.localStorage.getItem(" pages");
if (pages) {
pages = pages.split(" ");
log_html('<p>Found pages in local storage. <a href="javascript:wiki.list()">List</a> the pages in local storage. <a href="javascript:wiki.download()">Download</a> a fresh copy.');
} else {
download();
}
};
var list = function() {
var ul = document.createElement('ul');
\$.each(pages, function(i, id) {
var li = document.createElement('li');
var a = document.createElement('a');
\$(a).attr({href: "javascript:wiki.browse('" + id + "')"});
\$(a).text(id);
\$(li).append(a);
\$(ul).append(li);
});
log_node(ul);
}
var browse = function(id) {
var re = /$quoted_script\\/([^\\/?]+)/;
\$('*').html(window.localStorage.getItem(id));
\$('a[href^="$ScriptName"]').each(function(i, a) {
var match = re.exec(\$(a).attr('href'));
if (match) {
var id = unescape(match[1]);
if (pages.indexOf(id) >= 0) {
\$(a).attr('href', "javascript:wiki.browse('" + id + "')");
}
}
});
}
return {
initialize: initialize,
download: download,
list: list,
browse: browse,
};
}());
\$(document).ready(function(evt) {
wiki.initialize();
});
EOT
exit;
}
};
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2011 Alex Schroeder <alex@gnu.org>
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 3 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, see <http://www.gnu.org/licenses/>.
=cut