From 71b1b2a9b5fa60d53a20fe2d1a14d40cc96112ce Mon Sep 17 00:00:00 2001 From: mossroy Date: Thu, 7 Jan 2016 18:39:07 +0100 Subject: [PATCH] Fix to reflect the need of the namespace to read in the ZIM backend. --- service-worker.js | 2 +- www/js/app.js | 246 +++++++++++++++++++-------------------- www/js/lib/zimArchive.js | 6 + 3 files changed, 127 insertions(+), 127 deletions(-) diff --git a/service-worker.js b/service-worker.js index b3891f92..f41438d6 100644 --- a/service-worker.js +++ b/service-worker.js @@ -75,7 +75,7 @@ function(util) { var regexpCSS = new RegExp(/\.css$/i); var regexpContentUrlWithNamespace = new RegExp(/\/(.)\/(.*[^\/]+)$/); - var regexpContentUrlWithoutNamespace = new RegExp(/^(.*[^\/]+)$/); + var regexpContentUrlWithoutNamespace = new RegExp(/^([^\/]+)$/); var regexpDummyArticle = new RegExp(/dummyArticle\.html$/); function fetchEventListener(event) { diff --git a/www/js/app.js b/www/js/app.js index 40adf494..d38e9ca1 100644 --- a/www/js/app.js +++ b/www/js/app.js @@ -884,8 +884,8 @@ define(['jquery', 'abstractBackend', 'util', 'cookies','geometry','osabstraction var regexpImageLink = /^.?\/?[^:]+:(.*)/; var regexpMathImageUrl = /^\/math.*\/([0-9a-f]{32})\.png$/; var regexpPath = /^(.*\/)[^\/]+$/; - var regexpImageUrl = /^\.\.\/I\/(.*)$/; - var regexpMetadataUrl = /^\.\.\/-\/(.*)$/; + var regexpImageUrl = /^\.\.\/(I\/.*)$/; + var regexpMetadataUrl = /^\.\.\/(-\/.*)$/; /** * Display the the given HTML article in the web page, @@ -900,145 +900,139 @@ define(['jquery', 'abstractBackend', 'util', 'cookies','geometry','osabstraction // Scroll the iframe to its top $("#articleContent").contents().scrollTop(0); + // Apply Mediawiki CSS only when it's an Evopedia archive + if (selectedArchive.needsWikimediaCSS() === true) { + $('#articleContent').contents().find('head').empty(); + var currentHref = $(location).attr('href'); + var currentPath = regexpPath.exec(currentHref)[1]; + $('#articleContent').contents().find('head').append(""); + } + // Display the article inside the web page. - var articleContentIFrame = document.getElementById('articleContent'); - articleContentIFrame = (articleContentIFrame.contentWindow) ? articleContentIFrame.contentWindow : (articleContentIFrame.contentDocument.document) ? articleContentIFrame.contentDocument.document : articleContentIFrame.contentDocument; - articleContentIFrame.document.open(); - articleContentIFrame.document.write(htmlArticle); - articleContentIFrame.document.close(); + $('#articleContent').contents().find('body').html(htmlArticle); - // When the IFrame content is loaded, we can parse it - $('iframe#articleContent').load(function() { - // Apply Mediawiki CSS only when it's an Evopedia archive - if (selectedArchive.needsWikimediaCSS() === true) { - var currentHref = $(location).attr('href'); - var currentPath = regexpPath.exec(currentHref)[1]; - $('#articleContent').contents().find('head').append(""); - } + + // If the ServiceWorker is not useable, we need to fallback to parse the DOM + // to inject math images, and replace some links with javascript calls + if (contentInjectionMode === 'jquery') { - // If the ServiceWorker is not useable, we need to fallback to parse the DOM - // to inject math images, and replace some links with javascript calls - if (contentInjectionMode === 'jquery') { + // Convert links into javascript calls + $('#articleContent').contents().find('body').find('a').each(function() { + // Store current link's url + var url = $(this).attr("href"); + if (url === null || url === undefined) { + return; + } + var lowerCaseUrl = url.toLowerCase(); + var cssClass = $(this).attr("class"); - // Convert links into javascript calls - $('#articleContent').contents().find('body').find('a').each(function() { - // Store current link's url - var url = $(this).attr("href"); - if (url === null || url === undefined) { - return; + if (cssClass === "new") { + // It's a link to a missing article : display a message + $(this).on('click', function(e) { + alert("Missing article in Wikipedia"); + return false; + }); + } + else if (url.slice(0, 1) === "#") { + // It's an anchor link : do nothing + } + else if (url.substring(0, 4) === "http") { + // It's an external link : open in a new tab + $(this).attr("target", "_blank"); + } + else if (url.match(regexpOtherLanguage)) { + // It's a link to another language : change the URL to the online version of wikipedia + // The regular expression extracts $1 as the language, and $2 as the title name + var onlineWikipediaUrl = url.replace(regexpOtherLanguage, "https://$1.wikipedia.org/wiki/$2"); + $(this).attr("href", onlineWikipediaUrl); + // Open in a new tab + $(this).attr("target", "_blank"); + } + else if (url.match(regexpImageLink) + && (util.endsWith(lowerCaseUrl, ".png") + || util.endsWith(lowerCaseUrl, ".svg") + || util.endsWith(lowerCaseUrl, ".jpg") + || util.endsWith(lowerCaseUrl, ".jpeg"))) { + // It's a link to a file of wikipedia : change the URL to the online version and open in a new tab + var onlineWikipediaUrl = url.replace(regexpImageLink, "https://" + selectedArchive._language + ".wikipedia.org/wiki/File:$1"); + $(this).attr("href", onlineWikipediaUrl); + $(this).attr("target", "_blank"); + } + else { + // It's a link to another article + // Add an onclick event to go to this article + // instead of following the link + if (url.length>=2 && url.substring(0, 2) === "./") { + url = url.substring(2); } - var lowerCaseUrl = url.toLowerCase(); - var cssClass = $(this).attr("class"); + $(this).on('click', function(e) { + var titleName = decodeURIComponent(url); + pushBrowserHistoryState(titleName); + goToArticle(titleName); + return false; + }); + } + }); - if (cssClass === "new") { - // It's a link to a missing article : display a message - $(this).on('click', function(e) { - alert("Missing article in Wikipedia"); - return false; - }); - } - else if (url.slice(0, 1) === "#") { - // It's an anchor link : do nothing - } - else if (url.substring(0, 4) === "http") { - // It's an external link : open in a new tab - $(this).attr("target", "_blank"); - } - else if (url.match(regexpOtherLanguage)) { - // It's a link to another language : change the URL to the online version of wikipedia - // The regular expression extracts $1 as the language, and $2 as the title name - var onlineWikipediaUrl = url.replace(regexpOtherLanguage, "https://$1.wikipedia.org/wiki/$2"); - $(this).attr("href", onlineWikipediaUrl); - // Open in a new tab - $(this).attr("target", "_blank"); - } - else if (url.match(regexpImageLink) - && (util.endsWith(lowerCaseUrl, ".png") - || util.endsWith(lowerCaseUrl, ".svg") - || util.endsWith(lowerCaseUrl, ".jpg") - || util.endsWith(lowerCaseUrl, ".jpeg"))) { - // It's a link to a file of wikipedia : change the URL to the online version and open in a new tab - var onlineWikipediaUrl = url.replace(regexpImageLink, "https://" + selectedArchive._language + ".wikipedia.org/wiki/File:$1"); - $(this).attr("href", onlineWikipediaUrl); - $(this).attr("target", "_blank"); - } - else { - // It's a link to another article - // Add an onclick event to go to this article - // instead of following the link - if (url.length>=2 && url.substring(0, 2) === "./") { - url = url.substring(2); - } - $(this).on('click', function(e) { - var titleName = decodeURIComponent(url); - pushBrowserHistoryState(titleName); - goToArticle(titleName); - return false; - }); - } - }); - - // Load images - $('#articleContent').contents().find('body').find('img').each(function() { - var image = $(this); - var m = image.attr("src").match(regexpMathImageUrl); - if (m) { - // It's a math image (Evopedia archive) - selectedArchive.loadMathImage(m[1], function(data) { - image.attr("src", 'data:image/png;base64,' + data); - }); - } else { - // It's a standard image contained in the ZIM file - var imageMatch = image.attr("src").match(regexpImageUrl); - if (imageMatch) { - selectedArchive.getTitleByName(imageMatch[1]).then(function(title) { - selectedArchive.readBinaryFile(title, function (readableTitleName, content) { - // TODO : add the complete MIME-type of the image (as read from the ZIM file) - image.attr("src", 'data:image;base64,' + util.uint8ArrayToBase64(content)); - }); - }).fail(function () { - console.error("could not find title for image:" + imageMatch[1]); - }); - } - } - }); - - // Load CSS content - $('#articleContent').contents().find('body').find('link[rel=stylesheet]').each(function() { - var link = $(this); - var hrefMatch = link.attr("href").match(regexpMetadataUrl); - if (hrefMatch) { - // It's a CSS file contained in the ZIM file - selectedArchive.getTitleByName(hrefMatch[1]).then(function(title) { + // Load images + $('#articleContent').contents().find('body').find('img').each(function() { + var image = $(this); + var m = image.attr("src").match(regexpMathImageUrl); + if (m) { + // It's a math image (Evopedia archive) + selectedArchive.loadMathImage(m[1], function(data) { + image.attr("src", 'data:image/png;base64,' + data); + }); + } else { + // It's a standard image contained in the ZIM file + var imageMatch = image.attr("src").match(regexpImageUrl); + if (imageMatch) { + selectedArchive.getTitleByName(imageMatch[1]).then(function(title) { selectedArchive.readBinaryFile(title, function (readableTitleName, content) { - link.attr("href", 'data:text/css;charset=UTF-8,' + encodeURIComponent(util.uintToString(content))); + // TODO : add the complete MIME-type of the image (as read from the ZIM file) + image.attr("src", 'data:image;base64,' + util.uint8ArrayToBase64(content)); }); }).fail(function () { - console.error("could not find title for CSS : " + hrefMatch[1]); + console.error("could not find title for image:" + imageMatch[1]); }); } - }); + } + }); - // Load Javascript content - $('#articleContent').contents().find('body').find('script').each(function() { - var script = $(this); - var srcMatch = script.attr("src").match(regexpMetadataUrl); - // TODO check that the type of the script is text/javascript or application/javascript - if (srcMatch) { - // It's a Javascript file contained in the ZIM file - selectedArchive.getTitleByName(srcMatch[1]).then(function(title) { - selectedArchive.readBinaryFile(title, function (readableTitleName, content) { - script.attr("src", 'data:text/javascript;charset=UTF-8,' + encodeURIComponent(util.uintToString(content))); - }); - }).fail(function () { - console.error("could not find title for javascript : " + srcMatch[1]); + // Load CSS content + $('#articleContent').contents().find('body').find('link[rel=stylesheet]').each(function() { + var link = $(this); + var hrefMatch = link.attr("href").match(regexpMetadataUrl); + if (hrefMatch) { + // It's a CSS file contained in the ZIM file + selectedArchive.getTitleByName(hrefMatch[1]).then(function(title) { + selectedArchive.readBinaryFile(title, function (readableTitleName, content) { + link.attr("href", 'data:text/css;charset=UTF-8,' + encodeURIComponent(util.uintToString(content))); }); - } - }); + }).fail(function () { + console.error("could not find title for CSS : " + hrefMatch[1]); + }); + } + }); - } + // Load Javascript content + $('#articleContent').contents().find('body').find('script').each(function() { + var script = $(this); + var srcMatch = script.attr("src").match(regexpMetadataUrl); + // TODO check that the type of the script is text/javascript or application/javascript + if (srcMatch) { + // It's a Javascript file contained in the ZIM file + selectedArchive.getTitleByName(srcMatch[1]).then(function(title) { + selectedArchive.readBinaryFile(title, function (readableTitleName, content) { + script.attr("src", 'data:text/javascript;charset=UTF-8,' + encodeURIComponent(util.uintToString(content))); + }); + }).fail(function () { + console.error("could not find title for javascript : " + srcMatch[1]); + }); + } + }); - }); + } } /** diff --git a/www/js/lib/zimArchive.js b/www/js/lib/zimArchive.js index ae1f2b0e..20050a19 100644 --- a/www/js/lib/zimArchive.js +++ b/www/js/lib/zimArchive.js @@ -200,6 +200,8 @@ define(['zimfile', 'zimDirEntry', 'util', 'utf8'], callback(title.name(), data); }); }; + + var regexpTitleNameWithNamespaceA = /^A\//; /** * Searches a title (article / page) by name. @@ -208,6 +210,10 @@ define(['zimfile', 'zimDirEntry', 'util', 'utf8'], */ ZIMArchive.prototype.getTitleByName = function(titleName) { var that = this; + // If the namespace is not mentioned, we have to add it + if (!regexpTitleNameWithNamespaceA.test(titleName)) { + titleName= "A/" + titleName; + } return util.binarySearch(0, this._file.articleCount, function(i) { return that._file.dirEntryByUrlIndex(i).then(function(dirEntry) { var url = dirEntry.namespace + "/" + dirEntry.url;