forked from nm3clol/nm3clol-express-app
feat: Embedded Microsoft Office Viewer and Google Docs Viewer web services and no longer download as default action when viewer is supported when loading directory with file attachment that doesn't automatically render.
This commit is contained in:
parent
e0b93cf355
commit
1f1071f5a9
|
@ -186,6 +186,14 @@ const renderArchive = (html: string, paths: string[]) => {
|
|||
return html;
|
||||
}
|
||||
|
||||
const isMsOfficeViewerSupported = (file: string) => {
|
||||
return path.extname(file).search(/^((?:.pptx)|(?:.docx)|(?:.xlsx)|(?:.ppt)|(?:.doc)|(?:.xls))$/ig) != -1;
|
||||
}
|
||||
|
||||
const isGoogleDocsViewerSupported = (file: string) => {
|
||||
return isMsOfficeViewerSupported(file) || path.extname(file).search(/^((?:.pdf))$/ig) != -1;
|
||||
}
|
||||
|
||||
export default {
|
||||
leftTrimFirstDirectory,
|
||||
trimSlashes,
|
||||
|
@ -205,4 +213,6 @@ export default {
|
|||
inspect,
|
||||
md,
|
||||
moment,
|
||||
isMsOfficeViewerSupported,
|
||||
isGoogleDocsViewerSupported,
|
||||
};
|
|
@ -78,7 +78,7 @@ export default function () {
|
|||
}
|
||||
});
|
||||
const renderData = { breadcrumbs, content, filePath, fullFilePath, paths, req, route, ...fmData };
|
||||
res.render("page", { h: helpers, ...renderData });
|
||||
res.render("page", { h: helpers, path, config, ...renderData });
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -122,7 +122,7 @@ export default function () {
|
|||
console.log(`Setting route for ${route}`);
|
||||
pageRouter.get(route, async (req, res) => {
|
||||
const html = fs.readFileSync(fullFilePath).toString();
|
||||
const renderData = { route, filePath, fullFilePath, req, paths, html };
|
||||
const renderData = { route, filePath, fullFilePath, req, paths, html, path, config };
|
||||
res.render("archive", { h: helpers, ...renderData });
|
||||
});
|
||||
});
|
||||
|
@ -183,7 +183,7 @@ export default function () {
|
|||
}
|
||||
});
|
||||
const renderData = { breadcrumbs, route, filePath, fullFilePath, req, paths, directory: path.join('public', directory), videoURL, subtitleURL, subtitleVTT, info };
|
||||
res.render("video-player", { h: helpers, ...renderData });
|
||||
res.render("video-player", { h: helpers, path, config, ...renderData });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -81,15 +81,15 @@ export interface ServeHandlerOptions {
|
|||
* current working directory.
|
||||
*
|
||||
* For example, if serving a Jekyll app, it would look like this:
|
||||
* {
|
||||
* "public": "_site"
|
||||
* }
|
||||
* {
|
||||
* "public": "_site"
|
||||
* }
|
||||
*
|
||||
* Using absolute path:
|
||||
*
|
||||
* {
|
||||
* "public": "/path/to/your/_site"
|
||||
* }
|
||||
* {
|
||||
* "public": "/path/to/your/_site"
|
||||
* }
|
||||
*
|
||||
* NOTE: The path cannot contain globs or regular expressions.
|
||||
*/
|
||||
|
@ -101,17 +101,17 @@ export interface ServeHandlerOptions {
|
|||
* with status code 301 to the same path, but with the extension dropped.
|
||||
*
|
||||
* You can disable the feature like follows:
|
||||
* {
|
||||
* "cleanUrls": false
|
||||
* }
|
||||
* {
|
||||
* "cleanUrls": false
|
||||
* }
|
||||
*
|
||||
* However, you can also restrict it to certain paths:
|
||||
* {
|
||||
* "cleanUrls": [
|
||||
* "/app/**",
|
||||
* "/!components/**"
|
||||
* ]
|
||||
* }
|
||||
* {
|
||||
* "cleanUrls": [
|
||||
* "/app/**",
|
||||
* "/!components/**"
|
||||
* ]
|
||||
* }
|
||||
*
|
||||
* NOTE: The paths can only contain globs that are matched using minimatch.
|
||||
*/
|
||||
|
@ -121,19 +121,19 @@ export interface ServeHandlerOptions {
|
|||
* different one behind the curtains, this option is what you need.
|
||||
*
|
||||
* It's perfect for single page applications (SPAs), for example:
|
||||
* {
|
||||
* "rewrites": [
|
||||
* { "source": "app/**", "destination": "/index.html" },
|
||||
* { "source": "projects/edit", "destination": "/edit-project.html" }
|
||||
* ]
|
||||
* }
|
||||
* {
|
||||
* "rewrites": [
|
||||
* { "source": "app/**", "destination": "/index.html" },
|
||||
* { "source": "projects/edit", "destination": "/edit-project.html" }
|
||||
* ]
|
||||
* }
|
||||
*
|
||||
* You can also use so-called "routing segments" as follows:
|
||||
* {
|
||||
* "rewrites": [
|
||||
* { "source": "/projects/:id/edit", "destination": "/edit-project-:id.html" },
|
||||
* ]
|
||||
* }
|
||||
* {
|
||||
* "rewrites": [
|
||||
* { "source": "/projects/:id/edit", "destination": "/edit-project-:id.html" },
|
||||
* ]
|
||||
* }
|
||||
*
|
||||
* Now, if a visitor accesses /projects/123/edit, it will respond with the file /edit-project-123.html.
|
||||
*
|
||||
|
@ -184,8 +184,9 @@ export const directoryTemplate = (vals: ServeDirectoryTemplateParameters) => {
|
|||
});
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
ejs.renderFile(path.join(config.viewsPath, 'directory.ejs'), { breadcrumbs, h: helpers, ...vals }, (err, str) => {
|
||||
ejs.renderFile(path.join(config.viewsPath, 'directory.ejs'), { h: helpers, path, config, breadcrumbs, ...vals }, (err, str) => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(str);
|
||||
|
@ -196,8 +197,9 @@ export const directoryTemplate = (vals: ServeDirectoryTemplateParameters) => {
|
|||
|
||||
export const errorTemplate = (vals: ServeErrorTemplateParameters) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
ejs.renderFile(path.join(config.viewsPath, 'error.ejs'), { h: helpers, ...vals }, (err, str) => {
|
||||
ejs.renderFile(path.join(config.viewsPath, 'error.ejs'), { h: helpers, path, config, ...vals }, (err, str) => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(str);
|
||||
|
@ -1012,4 +1014,4 @@ export default async (request: Request, response: ServerResponse, serveConfig: S
|
|||
|
||||
response.writeHead(response.statusCode || 200, headers);
|
||||
stream.pipe(response);
|
||||
};
|
||||
};
|
|
@ -4,18 +4,13 @@
|
|||
<title><%=h.getDirectoryTitle(directory)%></title>
|
||||
<%- include('./includes/common-head.ejs') %>
|
||||
</head>
|
||||
|
||||
<body onload="initPage()">
|
||||
|
||||
<%- include('./includes/top-navbar.ejs') %>
|
||||
|
||||
<%- include('./includes/no-trash-svg.ejs') %>
|
||||
|
||||
<main class="container">
|
||||
<header>
|
||||
<%- include('./includes/breadcrumbs.ejs') %>
|
||||
</header>
|
||||
|
||||
<% if (h.directoryContainsReadme(directory)) {%>
|
||||
<div class="row p-4 pb-0 pe-lg-0 pt-lg-5 align-items-center rounded-3 border shadow-lg">
|
||||
<div class="col-lg-12 p-3 p-lg-5 pt-lg-3">
|
||||
|
@ -27,13 +22,69 @@
|
|||
<b>Document Date:</b> <%= h.moment(h.readmeFm(directory).docDate).format('MMMM D, YYYY') %>
|
||||
<% } %>
|
||||
<%if (typeof h.readmeFm(directory).file !== 'undefined') { %>
|
||||
<b>Attached Document:</b> <a href="<%- encodeURI(h.readmeFm(directory).file) %>"><%- h.readmeFm(directory).file %></a>
|
||||
<b>Document:</b> <a href="<%- encodeURI(path.basename(h.readmeFm(directory).file)) %>"><%- h.readmeFm(directory).file %></a>
|
||||
<% } %>
|
||||
</small>
|
||||
</p>
|
||||
<% } %>
|
||||
<% if (typeof h.readmeFm(directory).file !== 'undefined') { %>
|
||||
<iframe src="<%- encodeURI(h.readmeFm(directory).file) %>" style="width: 100%; height: 90vh;"></iframe>
|
||||
<ul class="nav nav-tabs" id="readerTab" role="tablist">
|
||||
<% if (h.isMsOfficeViewerSupported(h.readmeFm(directory).file)) { %>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link active" id="ms-office-viewer-tab" data-bs-toggle="tab" data-bs-target="#ms-office-viewer" type="button" role="tab" aria-controls="ms-office-viewer" aria-selected="true">Microsoft Office Web Viewer</button>
|
||||
</li>
|
||||
<% } %>
|
||||
<% if (h.isGoogleDocsViewerSupported(h.readmeFm(directory).file)) { %>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link<%=h.isMsOfficeViewerSupported(h.readmeFm(directory).file) ? '' : ' active'%>" id="google-docs-viewer-tab" data-bs-toggle="tab" data-bs-target="#google-docs-viewer" type="button" role="tab" aria-controls="google-docs-viewer" aria-selected="false">Google Docs Viewer</button>
|
||||
</li>
|
||||
<% } %>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link" id="view-download-tab" data-bs-toggle="tab" data-bs-target="#view-download" type="button" role="tab" aria-controls="view-download" aria-selected="false">View/Download</button>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<% if (h.isMsOfficeViewerSupported(h.readmeFm(directory).file)) { %>
|
||||
<div class="tab-pane active" id="ms-office-viewer" role="tabpanel" aria-labelledby="ms-office-viewer-tab" tabindex="0">
|
||||
<iframe src="https://view.officeapps.live.com/op/embed.aspx?src=<%- encodeURIComponent(h.trimSlashes(config.siteUrl) + path.posix.join(breadcrumbs[breadcrumbs.length-1].url, (h.readmeFm(directory).file.replaceAll('\\', '/')))) %>" style="width: 100%; height: 85vh; border: solid 1px #dfd7ca; border-top: 0px; border-bottom-left-radius: 0.25rem; border-bottom-right-radius: 0.25rem;" frameborder="0"></iframe>
|
||||
</div>
|
||||
<% } %>
|
||||
<% if (h.isGoogleDocsViewerSupported(h.readmeFm(directory).file)) { %>
|
||||
<div class="tab-pane<%=h.isMsOfficeViewerSupported(h.readmeFm(directory).file) ? '' : ' active'%>" id="google-docs-viewer" role="tabpanel" aria-labelledby="google-docs-viewer-tab" tabindex="0">
|
||||
<iframe src="https://docs.google.com/gview?embedded=true&url=<%- encodeURIComponent(h.trimSlashes(config.siteUrl) + path.posix.join(breadcrumbs[breadcrumbs.length-1].url, (h.readmeFm(directory).file.replaceAll('\\', '/')))) %>" style="width: 100%; height: 85vh; border: solid 1px #dfd7ca; border-top: 0px; border-bottom-left-radius: 0.25rem; border-bottom-right-radius: 0.25rem;" frameborder="0"></iframe>
|
||||
</div>
|
||||
<% } %>
|
||||
<div class="tab-pane<%=(h.isMsOfficeViewerSupported(h.readmeFm(directory).file) || h.isGoogleDocsViewerSupported(h.readmeFm(directory).file)) ? '' : ' active'%>" id="view-download" role="tabpanel" aria-labelledby="view-download-tab" tabindex="0">
|
||||
<iframe src="about:blank" style="width: 100%; height: 85vh; border: solid 1px #dfd7ca; border-top: 0px; border-bottom-left-radius: 0.25rem; border-bottom-right-radius: 0.25rem;" frameborder="0"></iframe>
|
||||
</div>
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
var viewDownloadTabButton = $('button#view-download-tab');
|
||||
var viewDownloadTab = new bootstrap.Tab(viewDownloadTabButton);
|
||||
var viewDownloadTabPaneIFrame = $('#view-download iframe');
|
||||
viewDownloadTabButton.on('click', function (event) {
|
||||
event.preventDefault();
|
||||
viewDownloadTab.show();
|
||||
if (viewDownloadTabPaneIFrame.attr('src') == 'about:blank') {
|
||||
console.log('View/Download tab clicked. Loading iframe.');
|
||||
viewDownloadTabPaneIFrame.attr('src', '<%- encodeURI(h.readmeFm(directory).file) %>');
|
||||
} else {
|
||||
console.log('View/Download tab clicked. iframe previously loaded.');
|
||||
}
|
||||
})
|
||||
})
|
||||
</script>
|
||||
<% if (!h.isMsOfficeViewerSupported(h.readmeFm(directory).file) && !h.isGoogleDocsViewerSupported(h.readmeFm(directory).file)) { %>
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
setTimeout(function () {
|
||||
var viewDownloadTabButton = $('button#view-download-tab');
|
||||
viewDownloadTabButton.click();
|
||||
}, 100);
|
||||
});
|
||||
</script>
|
||||
<% } %>
|
||||
</div>
|
||||
<% } else { %>
|
||||
<%- h.printReadme(directory) %>
|
||||
<% } %>
|
||||
|
@ -54,7 +105,6 @@
|
|||
</div>
|
||||
<% } %>
|
||||
<% } %>
|
||||
|
||||
<ul id="files" class="list-group shadow-lg">
|
||||
<% files.forEach(function(value, index) { %>
|
||||
<li class="list-group-item list-group-item-action flex-column align-items-start">
|
||||
|
@ -65,7 +115,6 @@
|
|||
<% }); %>
|
||||
</ul>
|
||||
</main>
|
||||
|
||||
<%- include('./includes/bottom-navbar.ejs') %>
|
||||
<%- include('./includes/bottom-scripts.ejs') %>
|
||||
</body>
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
<!-- Bootstrap JS (optional, if you need Bootstrap JS features) -->
|
||||
<script src="https://daball.me/vendor/jquery/jquery.min.js"></script>
|
||||
<script src="https://daball.me/vendor/popper.js/dist/popper.min.js"></script>
|
||||
<script src="https://daball.me/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
|
||||
<script src="https://daball.me/vendor/jquery-easing/jquery.easing.min.js"></script>
|
||||
<script src="https://daball.me/layouts/blog/js/blog.min.js"></script>
|
||||
<script src="https://daball.me/layouts/blog/js/blog.min.js"></script>
|
|
@ -10,7 +10,6 @@
|
|||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-8937572456576531" crossorigin="anonymous"></script>
|
||||
|
||||
<!-- Bootstrap CSS -->
|
||||
<link href="https://daball.me/vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
|
||||
<link href="https://fonts.googleapis.com/css?family=Saira+Extra+Condensed:100,200,300,400,500,600,700,800,900" rel="stylesheet" />
|
||||
|
@ -26,3 +25,4 @@
|
|||
<link href="https://daball.me/vendor/simple-line-icons/css/simple-line-icons.css" rel="stylesheet" />
|
||||
<link href="https://daball.me/layouts/blog/css/blog.min.css" rel="stylesheet" />
|
||||
<link href="/css/nm3clol.css" rel="stylesheet" />
|
||||
<script src="https://daball.me/vendor/jquery/jquery.min.js"></script>
|
||||
|
|
Loading…
Reference in New Issue
Block a user