5.0版本 发布 新增pptm 新增heif 美化heif 模板 美化tif 美化md 优化http方法 优化首页目录读取方法

This commit is contained in:
高雄
2026-01-23 15:50:24 +08:00
parent b08f4657e5
commit 0aa8de27d4
19 changed files with 13656 additions and 77728 deletions

View File

@@ -3,7 +3,7 @@
<head>
<title>CADViewer - 中文界面</title>
<meta charset="utf-8">
<#include "*/commonHeader.ftl">
<!-- 核心样式 - 精简版本 -->
<link href="cadviewer/app/css/cadviewer-core-styles.css" media="screen" rel="stylesheet" type="text/css" />
<link href="cadviewer/app/css/font-awesome.min.css" media="screen" rel="stylesheet" type="text/css" />

File diff suppressed because it is too large Load Diff

View File

@@ -145,7 +145,7 @@
</div>
<div>
<ol>
<li>支持 doc, docx, xls, xlsx, xlsm, ppt, pptx, csv, tsv, dotm, xlt, xltm, dot, dotx, xlam, xla, pages Office 办公文档</li>
<li>支持 doc, docx, xls, xlsx, xlsm, ppt, pptx, csv, tsv, dotm, xlt, xltm, dot, dotx, xlam, xla, pages ,pptm Office 办公文档</li>
<li>支持 wps, dps, et, ett, wpt 等国产 WPS Office 办公文档</li>
<li>支持 odt, ods, ots, odp, otp, six, ott, fodt, fods 等OpenOfficeLibreOffice 办公文档</li>
<li>支持 vsd, vsdx Visio 流程图文件</li>
@@ -160,7 +160,7 @@
<li>支持 dwg, dxf, dwf, iges , igs, dwt, dng, ifc, dwfx, stl, cf2, plt CAD 模型文件</li>
<li>支持 txt, xml(渲染), md(渲染), java, php, py, js, css 等所有纯文本</li>
<li>支持 zip, rar, jar, tar, gzip, 7z 等压缩包</li>
<li>支持 jpg, jpeg, png, gif, bmp, ico, jfif, webp, heic 等图片预览翻转缩放镜像</li>
<li>支持 jpg, jpeg, png, gif, bmp, ico, jfif, webp, heic ,heif 等图片预览翻转缩放镜像</li>
<li>支持 tif, tiff 图信息模型文件翻转缩放</li>
<li>支持 tga 图像格式文件</li>
<li>支持 svg 矢量图像格式文件 翻转缩放</li>

View File

@@ -50,7 +50,7 @@
8. 优化 marked 解析 <br>
<h4>新增</h4>
1. 新增 msg 邮件 解析 <br>
2. 新增 heic 图片 解析 <br>
2. 新增 heic、 heif 图片 解析 <br>
3. 新增 跨域方法 <br>
4. 新增 高亮方法 <br>
5. 新增 页码方法 <br>
@@ -61,6 +61,7 @@
10. 新增 异步等待 <br>
11. 新增 上传限制不支持的文件禁止上传 <br>
12. 新增 cadviewer转换方法<br>
13. 新增 pptm<br>
<h4>修复</h4>
1. 压缩包路径问题 <br>
2. 安全问题 <br>

View File

@@ -12,42 +12,40 @@
<script src="js/marked.min.js" type="text/javascript"></script>
<script src="js/base64.min.js" type="text/javascript"></script>
<script src="js/codemirror.js" type="text/javascript"></script>
<link rel="stylesheet" href="js/codemirror.css"/>
<style>
</style>
</head>
<body>
<input hidden id="textData" value="${textData}"/>
<!-- 目录区域 - 左侧 -->
<div id="directory">
<div>文档目录</div>
<div id="content">
<ul></ul>
<div class="empty-toc" style="display:none;">暂无目录</div>
<div class="main-container">
<!-- 目录区域 - 左侧 -->
<div id="directory">
<div>文档目录</div>
<div id="content">
<ul></ul>
<div class="empty-toc" style="display:none;">暂无目录</div>
</div>
</div>
</div>
<!-- 主内容区域 -->
<div class="container">
<div class="panel panel-default">
<div class="panel-heading">
<h6 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapseOne">
${file.name}
</a>
</h6>
</div>
<!-- 视图切换按钮 -->
<div class="view-toggle">
<button id="preview_btn" class="view-btn active">预览模式</button>
<button id="source_btn" class="view-btn">源代码</button>
</div>
<div class="panel-body">
<div id="markdown"></div>
<!-- 主内容区域 -->
<div class="content-container">
<div class="panel panel-default">
<div class="panel-heading">
<h6 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion" href="#collapseOne">
${file.name}
</a>
</h6>
</div>
<!-- 视图切换按钮 -->
<div class="view-toggle">
<button id="preview_btn" class="view-btn active">预览模式</button>
<button id="source_btn" class="view-btn">源代码</button>
</div>
<div class="panel-body">
<div id="markdown"></div>
</div>
</div>
</div>
</div>
@@ -64,6 +62,8 @@
theme: "default",
viewportMargin: Infinity
});
var kkkeyword = '${highlightall}';
// 初始化目录
function initTOC() {
@@ -75,8 +75,11 @@
let id = "heading-" + index++;
$(this).attr('id', id);
let level = this.tagName.toLowerCase().replace('h', '');
let text = $(this).text().substring(0, 50);
html += '<li class="li-h' + level + '"><a href="#' + id + '">' + text + '</a></li>';
let text = $(this).text();
if (text.length > 50) {
text = text.substring(0, 50) + "...";
}
html += '<li class="li-h' + level + '"><a href="#' + id + '" title="' + $(this).text() + '">' + text + '</a></li>';
});
$("#directory ul").html(html);
@@ -90,27 +93,22 @@
$("#directory ul").show();
}
// 更新目录高度
updateTOCHeight();
}
// 更新目录高度
function updateTOCHeight() {
const windowHeight = window.innerHeight;
const tocTop = document.getElementById('directory').getBoundingClientRect().top;
const availableHeight = windowHeight - tocTop - 20;
document.getElementById('directory').style.maxHeight = availableHeight + 'px';
// 确保目录滚动条可见
setTimeout(function() {
const contentDiv = document.getElementById('content');
if (contentDiv.scrollHeight > contentDiv.clientHeight) {
contentDiv.style.paddingRight = '8px';
}
}, 100);
}
// 安全HTML转义函数
function htmlEscape(str) {
if (!str) return "";
return str
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#39;")
.replace(/javascript/gi, "javascript ");
}
@@ -120,20 +118,44 @@
var textData = Base64.decode($("#textData").val());
textData = htmlEscape(textData);
window.textPreData = "<pre style='background-color: #f8f9fa;border:1px solid #e9ecef;border-radius:8px;padding:18px;overflow-x:auto;'>" + textData + "</pre>";
window.textMarkdownData = marked.parse(textData);
// 应用关键字高亮
const highlightedText = highlightKeyword(textData, kkkeyword);
window.textPreData = "<div style='width:100%;'><pre>" + highlightedText + "</pre></div>";
window.textMarkdownData = marked.parse(highlightedText);
$("#markdown").html(window.textMarkdownData);
editor.setValue(textData);
// 更新编辑器容器宽度
setTimeout(function() {
editor.refresh();
// 设置编辑器高度
const panelBody = $('.panel-body');
const editorHeight = panelBody.height() - 40; // 减去一些padding
editor.setSize('100%', editorHeight);
}, 100);
// 初始化目录
initTOC();
} catch (e) {
console.error("加载内容失败:", e);
$("#markdown").html("<div class='alert alert-danger' style='padding:15px;border-radius:8px;'>加载内容失败: " + e.message + "</div>");
$("#markdown").html("<div class='alert alert-danger' style='padding:15px;border-radius:8px;width:100%;'>加载内容失败: " + e.message + "</div>");
}
}
function highlightKeyword(text, keyword) {
if (!keyword || keyword.trim() === '') return text;
const escapedKeyword = keyword.replace(/[.*+?^${'$'}{}()|[\]\\]/g, '\\$&');
const regex = new RegExp('(' + escapedKeyword + ')', 'gi');
return text.replace(regex, '<span class="highlight-keyword">$1</span>');
}
// 切换视图
function switchView(mode) {
@@ -148,8 +170,21 @@
$("#markdown").html(window.textPreData);
$("#directory .empty-toc").show();
$("#directory ul").hide();
// 源代码模式下确保pre元素样式正确
$("#markdown pre").css({
'max-width': '100%',
'overflow-x': 'auto',
'background-color': '#f8f9fa',
'border': '1px solid #e9ecef',
'border-radius': '8px',
'padding': '18px',
'word-wrap': 'break-word',
'white-space': 'pre-wrap'
});
}
}
// 页面加载完成
$(document).ready(function() {
@@ -162,18 +197,20 @@
loadMarkdown();
// 监听编辑器变化
editor.on('change', function(cm) {
// 更新预览
var content = cm.getValue();
window.textPreData = "<pre style='background-color: #f8f9fa;border:1px solid #e9ecef;border-radius:8px;padding:18px;overflow-x:auto;'>" + content + "</pre>";
window.textMarkdownData = marked.parse(content);
// 如果当前是预览模式,更新预览内容
if ($("#preview_btn").hasClass('active')) {
$("#markdown").html(window.textMarkdownData);
initTOC();
}
});
editor.on('change', function(cm) {
// 更新预览
var content = cm.getValue();
// 应用关键字高亮
const highlightedContent = highlightKeyword(content, kkkeyword);
window.textPreData = "<div style='width:100%;'><pre>" + highlightedContent + "</pre></div>";
window.textMarkdownData = marked.parse(highlightedContent);
// 如果当前是预览模式,更新预览内容
if ($("#preview_btn").hasClass('active')) {
$("#markdown").html(window.textMarkdownData);
initTOC();
}
});
// 绑定视图切换事件
$("#preview_btn").click(function() {
@@ -189,20 +226,28 @@
e.preventDefault();
var target = $(this.getAttribute('href'));
if (target.length) {
$('html, body').animate({
scrollTop: target.offset().top - 100
// 滚动主内容区域
$('.panel-body').animate({
scrollTop: target.offset().top + $('.panel-body').scrollTop() - 20
}, 500);
// 高亮当前目录项
$('#directory li a').removeClass('active');
$(this).addClass('active');
}
});
// 窗口调整大小时更新目录高度
// 窗口调整大小时重新计算高度
$(window).resize(function() {
updateTOCHeight();
// 更新编辑器大小
if (editor) {
const panelBody = $('.panel-body');
const editorHeight = panelBody.height() - 40;
editor.setSize('100%', editorHeight);
editor.refresh();
}
});
// 初始化目录高度
setTimeout(updateTOCHeight, 100);
// 添加键盘快捷键
$(document).keydown(function(e) {
// Ctrl+1 切换到预览模式
@@ -219,9 +264,36 @@
// 添加目录项悬停效果
$(document).on('mouseenter', '#directory li a', function() {
$(this).parent().addClass('hover');
$(this).css('background-color', '#e9ecef');
}).on('mouseleave', '#directory li a', function() {
$(this).parent().removeClass('hover');
if (!$(this).hasClass('active')) {
$(this).css('background-color', 'transparent');
}
});
// 监听主内容区域滚动,更新目录高亮
$('.panel-body').scroll(function() {
if ($("#preview_btn").hasClass('active')) {
var scrollTop = $('.panel-body').scrollTop();
var found = false;
$('#markdown h1, #markdown h2, #markdown h3, #markdown h4, #markdown h5').each(function() {
var elementTop = $(this).offset().top;
var elementBottom = elementTop + $(this).outerHeight();
if (elementTop <= scrollTop + 50 && elementBottom > scrollTop + 50) {
var id = $(this).attr('id');
$('#directory li a').removeClass('active');
$('#directory li a[href="#' + id + '"]').addClass('active');
found = true;
return false;
}
});
if (!found) {
$('#directory li a').removeClass('active');
}
}
});
});
</script>

View File

@@ -51,19 +51,21 @@
try{
imageData = ctx.createImageData(canvas.width, canvas.height);
} catch(e){
if (e.message.indexOf("CanvasRenderingContext2D"))
// 修改异常处理部分,让旋转按钮与正常解析部分保持一致
if (e.message.indexOf("CanvasRenderingContext2D"))
{
var html = "";
html += "<div class=\"img-area\">";
html += "<div class=\"image-container\">";
html += '<img class="my-photo" id="page1" src="'+url+'">';
html += "<div class=\"button-container\">";
html += "<button onclick=\"rotateImg('page1', false)\">旋转</button>";
html += "</div>";
html += "</div>";
html += "</div>";
myp.innerHTML = html;
return;
var html = "";
html += "<div class=\"img-area\">";
html += "<div class=\"image-container\" style=\"position:relative;\">";
html += '<img class="my-photo" id="page1" src="'+url+'">';
html += "<div class=\"button-container\" style=\"position:absolute; bottom:5px; right:5px; opacity:0.1; transition:opacity 0.2s;\" onmouseover=\"this.style.opacity='0.9'\" onmouseout=\"this.style.opacity='0.1'\">";
html += "<button class=\"nszImg\" style=\"margin-right:3px; font-size:11px; padding:2px 6px; background:rgba(255,255,255,0.9); border:1px solid #999; border-radius:2px; min-width:50px;\">1/1页</button>";
html += "<button class=\"sszImg\" onclick=\"rotateImg('page1', true)\" style=\"font-size:11px; padding:2px 6px; background:rgba(255,255,255,0.9); border:1px solid #999; border-radius:2px;\">↻</button>";
html += "</div>";
html += "</div>";
html += "</div>";
myp.innerHTML = html;
return;
}
console.log("错误:" + e);
var html = "";