Merge pull request #310 from kiwix/Support-subdirectories-in-articles

Support subdirectories in articles
This commit is contained in:
Mossroy 2017-12-17 13:28:24 +01:00 committed by GitHub
commit 1bc747cd10
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 26 additions and 39 deletions

View File

@ -83,8 +83,8 @@ var regexpPNG = new RegExp(/\.png$/i);
var regexpJS = new RegExp(/\.js/i);
var regexpCSS = new RegExp(/\.css$/i);
var regexpContentUrlWithNamespace = new RegExp(/\/(.)\/(.*[^\/]+)$/);
var regexpContentUrlWithoutNamespace = new RegExp(/^([^\/]+)$/);
// Pattern for ZIM file namespace - see http://www.openzim.org/wiki/ZIM_file_format#Namespaces
var regexpZIMUrlWithNamespace = new RegExp(/(?:^|\/)([-ABIJMUVWX])\/(.+)/);
var regexpDummyArticle = new RegExp(/dummyArticle\.html$/);
function fetchEventListener(event) {
@ -92,8 +92,7 @@ function fetchEventListener(event) {
console.log('ServiceWorker handling fetch event for : ' + event.request.url);
// TODO handle the dummy article more properly
if ((regexpContentUrlWithNamespace.test(event.request.url)
|| regexpContentUrlWithoutNamespace.test(event.request.url))
if (regexpZIMUrlWithNamespace.test(event.request.url)
&& !regexpDummyArticle.test(event.request.url)) {
console.log('Asking app.js for a content', event.request.url);
@ -102,17 +101,9 @@ function fetchEventListener(event) {
var title;
var titleWithNameSpace;
var contentType;
if (regexpContentUrlWithoutNamespace.test(event.request.url)) {
// When the request URL is in the same folder,
// it means it's a link to an article (namespace A)
var regexpResult = regexpContentUrlWithoutNamespace.exec(event.request.url);
nameSpace = 'A';
title = regexpResult[1];
} else {
var regexpResult = regexpContentUrlWithNamespace.exec(event.request.url);
var regexpResult = regexpZIMUrlWithNamespace.exec(event.request.url);
nameSpace = regexpResult[1];
title = regexpResult[2];
}
// The namespace defines the type of content. See http://www.openzim.org/wiki/ZIM_file_format#Namespaces
// TODO : read the contentType from the ZIM file instead of hard-coding it here

View File

@ -315,8 +315,8 @@ define(['jquery', 'zimArchive', 'zimDirEntry', 'util', 'utf8'],
assert.ok(dirEntry !== null, "Title found");
if (dirEntry !== null) {
assert.equal(dirEntry.namespace +"/"+ dirEntry.url, "A/Ray_Charles.html", "URL is correct.");
localZimArchive.readArticle(dirEntry, function(title, data) {
assert.equal(title, "Ray Charles", "Title is correct.");
localZimArchive.readArticle(dirEntry, function(dirEntry2, data) {
assert.equal(dirEntry2.title, "Ray Charles", "Title is correct.");
assert.equal(data.length, 157186, "Data length is correct.");
assert.equal(data.indexOf("the only true genius in show business"), 5535, "Specific substring at beginning found.");
assert.equal(data.indexOf("Random Access Memories"), 154107, "Specific substring at end found.");

View File

@ -7,6 +7,7 @@ and open the template in the editor.
<html>
<head>
<meta charset="utf-8">
<base href="A/">
<title>dummy Article</title>
</head>
<body>

View File

@ -260,7 +260,7 @@
<div id="readingArticle" style="display: none;" class="container">
Reading article <span id="articleName"></span> from archive... Please wait <img src="img/spinner.gif" alt="Please wait..." />
</div>
<iframe id="articleContent" src="A/dummyArticle.html" class="articleIFrame">&nbsp;</iframe>
<iframe id="articleContent" src="dummyArticle.html" class="articleIFrame">&nbsp;</iframe>
</article>
<footer>
<div id="navigationButtons" class="btn-toolbar">

View File

@ -699,7 +699,7 @@ define(['jquery', 'zimArchiveLoader', 'util', 'uiUtil', 'cookies','abstractFiles
$("#prefix").val("");
findDirEntryFromDirEntryIdAndLaunchArticleRead(dirEntryId);
var dirEntry = selectedArchive.parseDirEntryId(dirEntryId);
pushBrowserHistoryState(dirEntry.url);
pushBrowserHistoryState(dirEntry.namespace + "/" + dirEntry.url);
return false;
}
@ -784,6 +784,8 @@ define(['jquery', 'zimArchiveLoader', 'util', 'uiUtil', 'cookies','abstractFiles
// Compile some regular expressions needed to modify links
var regexpImageLink = /^.?\/?[^:]+:(.*)/;
var regexpPath = /^(.*\/)[^\/]+$/;
// Pattern for ZIM file namespace - see http://www.openzim.org/wiki/ZIM_file_format#Namespaces
var regexpZIMUrlWithNamespace = /(?:^|\/)([-ABIJMUVWX]\/.+)/;
// These regular expressions match both relative and absolute URLs
// Since late 2014, all ZIM files should use relative URLs
var regexpImageUrl = /^(?:\.\.\/|\/)+(I\/.*)$/;
@ -811,10 +813,17 @@ define(['jquery', 'zimArchiveLoader', 'util', 'uiUtil', 'cookies','abstractFiles
// to inject math images, and replace some links with javascript calls
if (contentInjectionMode === 'jquery') {
// Compute base URL
var urlPath = regexpPath.test(dirEntry.url) ? urlPath = dirEntry.url.match(regexpPath)[1] : "";
var baseUrl = dirEntry.namespace + "/" + urlPath;
// Create (or replace) the "base" tag with our base URL
$('#articleContent').contents().find('head').find("base").detach();
$('#articleContent').contents().find('head').append("<base href='" + baseUrl + "'>");
// Convert links into javascript calls
$('#articleContent').contents().find('body').find('a').each(function() {
// Store current link's url
var url = $(this).attr("href");
// Compute current link's url (with its namespace), if applicable
var url = regexpZIMUrlWithNamespace.test(this.href) ? this.href.match(regexpZIMUrlWithNamespace)[1] : $(this).attr("href");
if (url === null || url === undefined) {
return;
}
@ -849,14 +858,6 @@ define(['jquery', 'zimArchiveLoader', 'util', 'uiUtil', 'cookies','abstractFiles
// It's a link to another article
// Add an onclick event to go to this article
// instead of following the link
if (url.substring(0, 2) === "./") {
url = url.substring(2);
}
// Remove the initial slash if it's an absolute URL
else if (url.substring(0, 1) === "/") {
url = url.substring(1);
}
$(this).on('click', function(e) {
var decodedURL = decodeURIComponent(url);
pushBrowserHistoryState(decodedURL);
@ -1005,7 +1006,7 @@ define(['jquery', 'zimArchiveLoader', 'util', 'uiUtil', 'cookies','abstractFiles
else {
if (dirEntry.namespace === 'A') {
$("#articleName").html(dirEntry.title);
pushBrowserHistoryState(dirEntry.url);
pushBrowserHistoryState(dirEntry.namespace + "/" + dirEntry.url);
$("#readingArticle").show();
$('#articleContent').contents().find('body').html("");
readArticle(dirEntry);
@ -1028,7 +1029,7 @@ define(['jquery', 'zimArchiveLoader', 'util', 'uiUtil', 'cookies','abstractFiles
else {
if (dirEntry.namespace === 'A') {
$("#articleName").html(dirEntry.title);
pushBrowserHistoryState(dirEntry.url);
pushBrowserHistoryState(dirEntry.namespace + "/" + dirEntry.url);
$("#readingArticle").show();
$('#articleContent').contents().find('body').html("");
readArticle(dirEntry);

View File

@ -227,7 +227,7 @@ define(['zimfile', 'zimDirEntry', 'util', 'utf8'],
*/
ZIMArchive.prototype.readArticle = function(dirEntry, callback) {
dirEntry.readData().then(function(data) {
callback(dirEntry.title, utf8.parse(data));
callback(dirEntry, utf8.parse(data));
});
};
@ -243,12 +243,10 @@ define(['zimfile', 'zimDirEntry', 'util', 'utf8'],
*/
ZIMArchive.prototype.readBinaryFile = function(dirEntry, callback) {
return dirEntry.readData().then(function(data) {
callback(dirEntry.title, data);
callback(dirEntry, data);
});
};
var regexpTitleWithoutNameSpace = /^[^\/]+$/;
/**
* Searches a DirEntry (article / page) by its title.
* @param {String} title
@ -256,10 +254,6 @@ define(['zimfile', 'zimDirEntry', 'util', 'utf8'],
*/
ZIMArchive.prototype.getDirEntryByTitle = function(title) {
var that = this;
// If no namespace is mentioned, it's an article, and we have to add it
if (regexpTitleWithoutNameSpace.test(title)) {
title= "A/" + title;
}
return util.binarySearch(0, this._file.articleCount, function(i) {
return that._file.dirEntryByUrlIndex(i).then(function(dirEntry) {
var url = dirEntry.namespace + "/" + dirEntry.url;