mirror of
https://github.com/kiwix/kiwix-js-pwa.git
synced 2025-09-10 04:40:27 -04:00
Fix subtitles and media download
Former-commit-id: 40b838098ce913dd7d285fdfab5c9b4817e7b7ec [formerly 462f9114eeed8cdadf0b8f795cff62efb6f0fe77 [formerly 5191fb4a99aece1d0cd015204cf496a1418f9f45]] Former-commit-id: 74b41d33d653e7ed16d6ab084b99fd5594c33b63 Former-commit-id: 9f6abd5c077893dad3ffbdd6a82f913017c2bd85
This commit is contained in:
parent
3cb56113fc
commit
2d0dd806f1
105
www/js/app.js
105
www/js/app.js
@ -3228,13 +3228,13 @@ define(['jquery', 'zimArchiveLoader', 'uiUtil', 'util', 'cache', 'images', 'sett
|
|||||||
var regexpPath = /^(.*\/)[^\/]+$/;
|
var regexpPath = /^(.*\/)[^\/]+$/;
|
||||||
// Pattern to find a ZIM URL (with its namespace) - see https://wiki.openzim.org/wiki/ZIM_file_format#Namespaces
|
// Pattern to find a ZIM URL (with its namespace) - see https://wiki.openzim.org/wiki/ZIM_file_format#Namespaces
|
||||||
var regexpZIMUrlWithNamespace = /^[./]*([-ABCIJMUVWX]\/.+)$/;
|
var regexpZIMUrlWithNamespace = /^[./]*([-ABCIJMUVWX]\/.+)$/;
|
||||||
// Regex below finds images, scripts, stylesheets and tracks with ZIM-type metadata and image namespaces [kiwix-js #378].
|
// Regex below finds images, scripts, stylesheets (not tracks) with ZIM-type metadata and image namespaces [kiwix-js #378].
|
||||||
// It first searches for <img, <script, <link, etc., then scans forward to find, on a word boundary, either src=["'] or href=["']
|
// It first searches for <img, <script, <link, etc., then scans forward to find, on a word boundary, either src=["'] or href=["']
|
||||||
// (ignoring any extra whitespace), and it then tests the path of the URL with a non-capturing negative lookahead that excludes
|
// (ignoring any extra whitespace), and it then tests the path of the URL with a non-capturing negative lookahead that excludes
|
||||||
// URLs that begin 'http' (i.e. non-relative URLs). It then captures the whole of the URL up until either the opening delimiter
|
// URLs that begin 'http' (i.e. non-relative URLs). It then captures the whole of the URL up until either the opening delimiter
|
||||||
// (" or ', which is capture group \3) or a querystring or hash character (? or #). When the regex is used below, it will be further
|
// (" or ', which is capture group \3) or a querystring or hash character (? or #). When the regex is used below, it will be further
|
||||||
// processed to calculate the ZIM URL from the relative path. This regex can cope with legitimate single quote marks (') in the URL.
|
// processed to calculate the ZIM URL from the relative path. This regex can cope with legitimate single quote marks (') in the URL.
|
||||||
var regexpTagsWithZimUrl = /(<(?:img|script|link|track)\b[^>]*?\s)(?:src|href)(\s*=\s*(["']))(?!http|app:)(.+?)(?=\3|\?|#)/ig;
|
var regexpTagsWithZimUrl = /(<(?:img|script|link)\b[^>]*?\s)(?:src|href)(\s*=\s*(["']))(?!http|app:)(.+?)(?=\3|\?|#)/ig;
|
||||||
// Regex below tests the html of an article for active content [kiwix-js #466]
|
// Regex below tests the html of an article for active content [kiwix-js #466]
|
||||||
// It inspects every <script> block in the html and matches in the following cases: 1) the script loads a UI application called app.js;
|
// It inspects every <script> block in the html and matches in the following cases: 1) the script loads a UI application called app.js;
|
||||||
// 2) the script block has inline content that does not contain "importScript()", "toggleOpenSection" or an "articleId" assignment
|
// 2) the script block has inline content that does not contain "importScript()", "toggleOpenSection" or an "articleId" assignment
|
||||||
@ -3822,7 +3822,7 @@ define(['jquery', 'zimArchiveLoader', 'uiUtil', 'util', 'cache', 'images', 'sett
|
|||||||
}
|
}
|
||||||
var mediaElement = /audio|video/i.test(mediaSource.tagName) ? mediaSource : mediaSource.parentElement;
|
var mediaElement = /audio|video/i.test(mediaSource.tagName) ? mediaSource : mediaSource.parentElement;
|
||||||
// Create custom subtitle / cc load menu if it doesn't already exist
|
// Create custom subtitle / cc load menu if it doesn't already exist
|
||||||
if (!articleDocument.getElementById('kiwixCCMenu')) buildCustomCCMenu(articleDocument, mediaElement, function (ccBlob) {
|
if (!articleWindow.document.getElementById('kiwixCCMenu')) buildCustomCCMenu(articleWindow.document, mediaElement, function (ccBlob) {
|
||||||
trackBlob = ccBlob;
|
trackBlob = ccBlob;
|
||||||
});
|
});
|
||||||
// Load media file
|
// Load media file
|
||||||
@ -3838,60 +3838,63 @@ define(['jquery', 'zimArchiveLoader', 'uiUtil', 'util', 'cache', 'images', 'sett
|
|||||||
if (/track/i.test(mediaSource.tagName)) return;
|
if (/track/i.test(mediaSource.tagName)) return;
|
||||||
mediaElement.load();
|
mediaElement.load();
|
||||||
// Add a download link in case media source not supported
|
// Add a download link in case media source not supported
|
||||||
document.getElementById('alertBoxFooter').innerHTML =
|
if (articleWindow.kiwixType === 'iframe') {
|
||||||
'<div id="downloadAlert" class="alert alert-info alert-dismissible">\n' +
|
var iframe = document.getElementById('articleContent').contentDocument;
|
||||||
' <a href="#" class="close" data-dismiss="alert" aria-label="close">×</a>\n' +
|
document.getElementById('alertBoxFooter').innerHTML =
|
||||||
' <span id="alertMessage"></span>\n' +
|
'<div id="downloadAlert" class="alert alert-info alert-dismissible">\n' +
|
||||||
'</div>\n';
|
' <a href="#" class="close" data-dismiss="alert" aria-label="close">×</a>\n' +
|
||||||
var alertMessage = document.getElementById('alertMessage');
|
' <span id="alertMessage"></span>\n' +
|
||||||
var filename = articleWindow.title + '_' + dirEntry.url.replace(/^.*\/([^\/]+)$/, '$1');
|
'</div>\n';
|
||||||
// Make filename safe
|
var alertMessage = document.getElementById('alertMessage');
|
||||||
filename = filename.replace(/[\/\\:*?"<>|]/g, '_');
|
var filename = iframe.title + '_' + dirEntry.url.replace(/^.*\/([^\/]+)$/, '$1');
|
||||||
alertMessage.innerHTML = '<a href="#" class="alert-link" id="downloadMedia">Download this file</a> (and any selected subtitles) to play with another app';
|
// Make filename safe
|
||||||
document.getElementById('downloadMedia').addEventListener('click', function () {
|
filename = filename.replace(/[\/\\:*?"<>|]/g, '_');
|
||||||
var downloadFiles = [];
|
alertMessage.innerHTML = '<a href="#" class="alert-link" id="downloadMedia">Download this file</a> (and any selected subtitles) to play with another app';
|
||||||
downloadFiles.push({
|
document.getElementById('downloadMedia').addEventListener('click', function () {
|
||||||
'blob': blob,
|
var downloadFiles = [];
|
||||||
'filename': filename,
|
|
||||||
'src': mediaSource.src
|
|
||||||
});
|
|
||||||
// Add any selected subtitle file to the download package
|
|
||||||
var selTextTrack = iframe.getElementById('kiwixSelCC');
|
|
||||||
if (selTextTrack) {
|
|
||||||
var selTextExt = selTextTrack.dataset.kiwixurl.replace(/^.*\.([^.]+)$/, '$1');
|
|
||||||
// Subtitle files should have same name as video + .es.vtt (for example)
|
|
||||||
downloadFiles.push({
|
downloadFiles.push({
|
||||||
'blob': trackBlob,
|
'blob': blob,
|
||||||
'filename': filename.replace(/^(.*)\.[^.]+$/, '$1.' + selTextTrack.srclang + '.' + selTextExt),
|
'filename': filename,
|
||||||
'src': selTextTrack.src
|
'src': mediaSource.src
|
||||||
});
|
});
|
||||||
}
|
// Add any selected subtitle file to the download package
|
||||||
for (var j = downloadFiles.length; j--;) {
|
var selTextTrack = iframe.getElementById('kiwixSelCC');
|
||||||
if (typeof Windows !== 'undefined' && typeof Windows.Storage !== 'undefined') {
|
if (selTextTrack) {
|
||||||
uiUtil.downloadBlobUWP(downloadFiles[j].blob, downloadFiles[j].filename, alertMessage);
|
var selTextExt = selTextTrack.dataset.kiwixurl.replace(/^.*\.([^.]+)$/, '$1');
|
||||||
} else {
|
// Subtitle files should have same name as video + .es.vtt (for example)
|
||||||
var mimeType = downloadFiles[j].blob.type ? downloadFiles[j].blob.type : 'application/octet-stream';
|
downloadFiles.push({
|
||||||
var a = document.createElement('a');
|
'blob': trackBlob,
|
||||||
a.href = downloadFiles[j].src;
|
'filename': filename.replace(/^(.*)\.[^.]+$/, '$1.' + selTextTrack.srclang + '.' + selTextExt),
|
||||||
a.target = '_blank';
|
'src': selTextTrack.src
|
||||||
a.type = mimeType;
|
});
|
||||||
a.download = downloadFiles[j].filename;
|
}
|
||||||
alertMessage.appendChild(a); // NB we have to add the anchor to the document for Firefox to be able to click it
|
for (var j = downloadFiles.length; j--;) {
|
||||||
try {
|
if (typeof Windows !== 'undefined' && typeof Windows.Storage !== 'undefined') {
|
||||||
a.click();
|
uiUtil.downloadBlobUWP(downloadFiles[j].blob, downloadFiles[j].filename, alertMessage);
|
||||||
} catch (err) {
|
} else {
|
||||||
// If the click fails, use an alternative download method
|
var mimeType = downloadFiles[j].blob.type ? downloadFiles[j].blob.type : 'application/octet-stream';
|
||||||
if (window.navigator && window.navigator.msSaveBlob) {
|
var a = document.createElement('a');
|
||||||
// This works for IE11
|
a.href = downloadFiles[j].src;
|
||||||
window.navigator.msSaveBlob(downloadFiles[j].blob, downloadFiles[j].filename);
|
a.target = '_blank';
|
||||||
|
a.type = mimeType;
|
||||||
|
a.download = downloadFiles[j].filename;
|
||||||
|
alertMessage.appendChild(a); // NB we have to add the anchor to the document for Firefox to be able to click it
|
||||||
|
try {
|
||||||
|
a.click();
|
||||||
|
} catch (err) {
|
||||||
|
// If the click fails, use an alternative download method
|
||||||
|
if (window.navigator && window.navigator.msSaveBlob) {
|
||||||
|
// This works for IE11
|
||||||
|
window.navigator.msSaveBlob(downloadFiles[j].blob, downloadFiles[j].filename);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
articleContainer.addEventListener('unload', function (e) {
|
||||||
articleContainer.addEventListener('unload', function (e) {
|
alertMessage.remove();
|
||||||
alertMessage.remove();
|
});
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user