2015-03-27 03:01:01 +02:00
use strict ;
2015-08-18 10:48:03 +02:00
use v5 .10 ;
2015-03-27 03:01:01 +02:00
2011-12-31 03:04:35 +00:00
= 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
2014-08-22 08:49:40 +02:00
AddModuleDescription ( 'webapp.pl' , 'Offline Extension' ) ;
2011-12-31 03:04:35 +00:00
2015-04-10 13:31:28 +03:00
our ( $ q , % IndexHash , $ ScriptName , $ FullUrl , $ StyleSheet , $ StyleSheetPage , $ SurgeProtection , @ MyAdminCode , @ MyInitVariables , $ LastUpdate ) ;
2015-03-27 03:01:01 +02:00
2011-12-31 03:04:35 +00:00
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</s pan > . </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 ) {
2015-10-26 01:03:42 +02:00
print ref $ StyleSheet ? join ( "\n" , @$ StyleSheet ) . "\n" : "$StyleSheet\n" ;
2011-12-31 03:04:35 +00:00
} 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 ) ;
2012-01-31 11:10:40 +00:00
my $ quoted_script = quotemeta ( $ ScriptName ) ;
2011-12-31 03:04:35 +00:00
print << EOT ;
var wiki = ( function ( ) {
var pages ;
var log = function ( msg ) {
2012-01-31 11:10:40 +00:00
\ $( "#status" ) . text ( msg ) ;
2011-12-31 03:04:35 +00:00
}
var log_html = function ( msg ) {
2012-01-31 11:10:40 +00:00
\ $( "#status" ) . html ( msg ) ;
2011-12-31 03:04:35 +00:00
}
var log_node = function ( msg ) {
2012-01-31 11:10:40 +00:00
\ $( "#status" ) . empty ( ) ;
\ $( "#status" ) . append ( msg ) ;
2011-12-31 03:04:35 +00:00
}
var get_pages = function ( data ) {
2012-01-31 11:10:40 +00:00
pages = data . split ( "\\n" ) ;
2011-12-31 03:04:35 +00:00
var count = 1 ;
pages . pop ( ) ; // after the last newline there is nothing
2012-01-31 11:10:40 +00:00
\ $( "#total" ) . text ( pages . length ) ;
2011-12-31 03:04:35 +00:00
var get_page = function ( i , id ) {
if ( id != "" ) {
var store_page = function ( data ) {
window . localStorage . setItem ( id , data ) ;
2012-01-31 11:10:40 +00:00
\ $( "#page" ) . text ( count + + ) ;
2011-12-31 03:04:35 +00:00
}
2012-01-31 11:10:40 +00:00
\ $ . get ( "$FullUrl" ,
2011-12-31 03:04:35 +00:00
{ action: "browse" , id: id } ,
store_page ) ;
}
}
2012-01-31 11:10:40 +00:00
\ $ . each ( pages , get_page ) ;
2011-12-31 03:04:35 +00:00
window . localStorage . setItem ( " pages" , pages . join ( " " ) ) ;
}
var download = function ( ) {
log ( "Getting list of pages..." ) ;
2012-01-31 11:10:40 +00:00
\ $ . get ( "$FullUrl" ,
2011-12-31 03:04:35 +00:00
{ action: "index" , raw: "1" } ,
get_pages ) ;
log_html ( '<p><a href="javascript:wiki.list()">List</a> the pages in local storage.' ) ;
}
var initialize = function ( ) {
2012-01-31 11:10:40 +00:00
pages = window . localStorage . getItem ( " pages" ) ;
2011-12-31 03:04:35 +00:00
if ( pages ) {
2012-01-31 11:10:40 +00:00
pages = pages . split ( " " ) ;
2011-12-31 03:04:35 +00:00
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' ) ;
2012-01-31 11:10:40 +00:00
\ $ . each ( pages , function ( i , id ) {
2011-12-31 03:04:35 +00:00
var li = document . createElement ( 'li' ) ;
var a = document . createElement ( 'a' ) ;
2012-01-31 11:10:40 +00:00
\ $ ( a ) . attr ( { href: "javascript:wiki.browse('" + id + "')" } ) ;
\ $ ( a ) . text ( id ) ;
\ $ ( li ) . append ( a ) ;
\ $ ( ul ) . append ( li ) ;
2011-12-31 03:04:35 +00:00
} ) ;
log_node ( ul ) ;
}
var browse = function ( id ) {
2012-01-31 11:10:40 +00:00
var re = /$quoted_script\\/ ( [ ^ \ \ /?]+)/ ;
\ $( '*' ) . html ( window . localStorage . getItem ( id ) ) ;
\ $( 'a[href^="$ScriptName"]' ) . each ( function ( i , a ) {
var match = re . exec ( \ $ ( a ) . attr ( 'href' ) ) ;
2011-12-31 03:04:35 +00:00
if ( match ) {
var id = unescape ( match [ 1 ] ) ;
if ( pages . indexOf ( id ) >= 0 ) {
2012-01-31 11:10:40 +00:00
\ $ ( a ) . attr ( 'href' , "javascript:wiki.browse('" + id + "')" ) ;
2011-12-31 03:04:35 +00:00
}
}
} ) ;
}
return {
initialize: initialize ,
download: download ,
list: list ,
browse: browse ,
} ;
} ( ) ) ;
2012-01-31 11:10:40 +00:00
\ $ ( document ) . ready ( function ( evt ) {
2011-12-31 03:04:35 +00:00
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