移除office-plugin, 使用新版jodconverter

This commit is contained in:
陈精华
2022-12-15 18:19:30 +08:00
parent 281a9cfbab
commit 7d3a4ebc4e
12562 changed files with 202 additions and 3641 deletions

View File

@@ -25,9 +25,9 @@
<dependencies>
<dependency>
<groupId>cn.keking</groupId>
<artifactId>office-plugin</artifactId>
<version>${project.version}</version>
<groupId>org.jodconverter</groupId>
<artifactId>jodconverter-local</artifactId>
<version>${jodconverter.version}</version>
</dependency>
<!-- web start -->

View File

@@ -25,7 +25,7 @@
<outputDirectory>${file.separator}log</outputDirectory>
</fileSet>
<fileSet>
<directory>../office-plugin/windows-office</directory>
<directory>windows-office</directory>
<outputDirectory>${file.separator}windows-office</outputDirectory>
</fileSet>
<fileSet>
@@ -36,4 +36,4 @@
</includes>
</fileSet>
</fileSets>
</assembly>
</assembly>

View File

@@ -1,6 +1,6 @@
package cn.keking.config;
import org.artofsolving.jodconverter.util.ConfigUtils;
import cn.keking.utils.ConfigUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

View File

@@ -1,7 +1,6 @@
package cn.keking.config;
import org.artofsolving.jodconverter.office.OfficeUtils;
import org.artofsolving.jodconverter.util.ConfigUtils;
import cn.keking.utils.ConfigUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@@ -59,7 +58,7 @@ public class ConfigRefreshComponent {
FileReader fileReader = new FileReader(configFilePath);
BufferedReader bufferedReader = new BufferedReader(fileReader);
properties.load(bufferedReader);
OfficeUtils.restorePropertiesFromEnvFormat(properties);
ConfigUtils.restorePropertiesFromEnvFormat(properties);
cacheEnabled = Boolean.parseBoolean(properties.getProperty("cache.enabled", ConfigConstants.DEFAULT_CACHE_ENABLED));
text = properties.getProperty("simText", ConfigConstants.DEFAULT_TXT_TYPE);
media = properties.getProperty("media", ConfigConstants.DEFAULT_MEDIA_TYPE);

View File

@@ -1,7 +1,6 @@
package cn.keking.model;
import cn.keking.config.ConfigConstants;
import org.artofsolving.jodconverter.model.FileProperties;
/**
* Created by kl on 2018/1/17.
@@ -38,12 +37,6 @@ public class FileAttribute {
this.officePreviewType = officePreviewType;
}
public FileProperties toFileProperties() {
FileProperties fileProperties = new FileProperties();
fileProperties.setFilePassword(filePassword);
return fileProperties;
}
public String getFileKey() {
return fileKey;
}

View File

@@ -1,157 +0,0 @@
package cn.keking.service;
import org.artofsolving.jodconverter.document.DocumentFamily;
import org.artofsolving.jodconverter.document.DocumentFormat;
import org.artofsolving.jodconverter.document.SimpleDocumentFormatRegistry;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* 重写了DefaultDocumentFormatRegistry类因为要添加自定义行为比如字符编码。。。
* @author yudian-it
* @date 2017/12/5
*/
public class OfficePluginExtendFormatRegistry extends SimpleDocumentFormatRegistry {
public OfficePluginExtendFormatRegistry() {
DocumentFormat pdf = new DocumentFormat("Portable Document Format", "pdf", "application/pdf");
pdf.setStoreProperties(DocumentFamily.TEXT, Collections.singletonMap("FilterName", "writer_pdf_Export"));
pdf.setStoreProperties(DocumentFamily.SPREADSHEET, Collections.singletonMap("FilterName", "calc_pdf_Export"));
pdf.setStoreProperties(DocumentFamily.PRESENTATION, Collections.singletonMap("FilterName", "impress_pdf_Export"));
pdf.setStoreProperties(DocumentFamily.DRAWING, Collections.singletonMap("FilterName", "draw_pdf_Export"));
addFormat(pdf);
DocumentFormat swf = new DocumentFormat("Macromedia Flash", "swf", "application/x-shockwave-flash");
swf.setStoreProperties(DocumentFamily.PRESENTATION, Collections.singletonMap("FilterName", "impress_flash_Export"));
swf.setStoreProperties(DocumentFamily.DRAWING, Collections.singletonMap("FilterName", "draw_flash_Export"));
addFormat(swf);
// disabled because it's not always available
//DocumentFormat xhtml = new DocumentFormat("XHTML", "xhtml", "application/xhtml+xml");
//xhtml.setStoreProperties(DocumentFamily.TEXT, Collections.singletonMap("FilterName", "XHTML Writer File"));
//xhtml.setStoreProperties(DocumentFamily.SPREADSHEET, Collections.singletonMap("FilterName", "XHTML Calc File"));
//xhtml.setStoreProperties(DocumentFamily.PRESENTATION, Collections.singletonMap("FilterName", "XHTML Impress File"));
//addFormat(xhtml);
DocumentFormat html = new DocumentFormat("HTML", "html", "text/html");
// HTML is treated as Text when supplied as input, but as an output it is also
// available for exporting Spreadsheet and Presentation formats
html.setInputFamily(DocumentFamily.TEXT);
html.setStoreProperties(DocumentFamily.TEXT, Collections.singletonMap("FilterName", "HTML (StarWriter)"));
Map<String,Object> htmlLoadAndStoreProperties = new LinkedHashMap<>();
htmlLoadAndStoreProperties.put("FilterName", "HTML (StarCalc)");
htmlLoadAndStoreProperties.put("FilterOptions", "utf8");
html.setStoreProperties(DocumentFamily.SPREADSHEET, htmlLoadAndStoreProperties);
html.setStoreProperties(DocumentFamily.PRESENTATION, Collections.singletonMap("FilterName", "impress_html_Export"));
addFormat(html);
DocumentFormat odt = new DocumentFormat("OpenDocument Text", "odt", "application/vnd.oasis.opendocument.text");
odt.setInputFamily(DocumentFamily.TEXT);
odt.setStoreProperties(DocumentFamily.TEXT, Collections.singletonMap("FilterName", "writer8"));
addFormat(odt);
DocumentFormat sxw = new DocumentFormat("OpenOffice.org 1.0 Text Document", "sxw", "application/vnd.sun.xml.writer");
sxw.setInputFamily(DocumentFamily.TEXT);
sxw.setStoreProperties(DocumentFamily.TEXT, Collections.singletonMap("FilterName", "StarOffice XML (Writer)"));
addFormat(sxw);
DocumentFormat doc = new DocumentFormat("Microsoft Word", "doc", "application/msword");
doc.setInputFamily(DocumentFamily.TEXT);
doc.setStoreProperties(DocumentFamily.TEXT, Collections.singletonMap("FilterName", "MS Word 97"));
addFormat(doc);
DocumentFormat docx = new DocumentFormat("Microsoft Word 2007 XML", "docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document");
docx.setInputFamily(DocumentFamily.TEXT);
addFormat(docx);
DocumentFormat rtf = new DocumentFormat("Rich Text Format", "rtf", "text/rtf");
rtf.setInputFamily(DocumentFamily.TEXT);
rtf.setStoreProperties(DocumentFamily.TEXT, Collections.singletonMap("FilterName", "Rich Text Format"));
addFormat(rtf);
DocumentFormat wpd = new DocumentFormat("WordPerfect", "wpd", "application/wordperfect");
wpd.setInputFamily(DocumentFamily.TEXT);
addFormat(wpd);
DocumentFormat txt = new DocumentFormat("Plain Text", "txt", "text/plain");
txt.setInputFamily(DocumentFamily.TEXT);
Map<String,Object> txtLoadAndStoreProperties = new LinkedHashMap<>();
txtLoadAndStoreProperties.put("FilterName", "Text (encoded)");
txtLoadAndStoreProperties.put("FilterOptions", "utf8");
txt.setLoadProperties(txtLoadAndStoreProperties);
txt.setStoreProperties(DocumentFamily.TEXT, txtLoadAndStoreProperties);
addFormat(txt);
DocumentFormat wikitext = new DocumentFormat("MediaWiki wikitext", "wiki", "text/x-wiki");
wikitext.setStoreProperties(DocumentFamily.TEXT, Collections.singletonMap("FilterName", "MediaWiki"));
//addFormat(wikitext);
DocumentFormat ods = new DocumentFormat("OpenDocument Spreadsheet", "ods", "application/vnd.oasis.opendocument.spreadsheet");
ods.setInputFamily(DocumentFamily.SPREADSHEET);
ods.setStoreProperties(DocumentFamily.SPREADSHEET, Collections.singletonMap("FilterName", "calc8"));
addFormat(ods);
DocumentFormat sxc = new DocumentFormat("OpenOffice.org 1.0 Spreadsheet", "sxc", "application/vnd.sun.xml.calc");
sxc.setInputFamily(DocumentFamily.SPREADSHEET);
sxc.setStoreProperties(DocumentFamily.SPREADSHEET, Collections.singletonMap("FilterName", "StarOffice XML (Calc)"));
addFormat(sxc);
DocumentFormat xls = new DocumentFormat("Microsoft Excel", "xls", "application/vnd.ms-excel");
xls.setInputFamily(DocumentFamily.SPREADSHEET);
xls.setStoreProperties(DocumentFamily.SPREADSHEET, Collections.singletonMap("FilterName", "MS Excel 97"));
addFormat(xls);
DocumentFormat xlsx = new DocumentFormat("Microsoft Excel 2007 XML", "xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
xlsx.setInputFamily(DocumentFamily.SPREADSHEET);
addFormat(xlsx);
DocumentFormat csv = new DocumentFormat("Comma Separated Values", "csv", "text/csv");
csv.setInputFamily(DocumentFamily.SPREADSHEET);
Map<String,Object> csvLoadAndStoreProperties = new LinkedHashMap<>();
csvLoadAndStoreProperties.put("FilterName", "Text - txt - csv (StarCalc)");
csvLoadAndStoreProperties.put("FilterOptions", "44,34,0"); // Field Separator: ','; Text Delimiter: '"'
csv.setLoadProperties(csvLoadAndStoreProperties);
csv.setStoreProperties(DocumentFamily.SPREADSHEET, csvLoadAndStoreProperties);
addFormat(csv);
DocumentFormat tsv = new DocumentFormat("Tab Separated Values", "tsv", "text/tab-separated-values");
tsv.setInputFamily(DocumentFamily.SPREADSHEET);
Map<String,Object> tsvLoadAndStoreProperties = new LinkedHashMap<>();
tsvLoadAndStoreProperties.put("FilterName", "Text - txt - csv (StarCalc)");
tsvLoadAndStoreProperties.put("FilterOptions", "9,34,0"); // Field Separator: '\t'; Text Delimiter: '"'
tsv.setLoadProperties(tsvLoadAndStoreProperties);
tsv.setStoreProperties(DocumentFamily.SPREADSHEET, tsvLoadAndStoreProperties);
addFormat(tsv);
DocumentFormat odp = new DocumentFormat("OpenDocument Presentation", "odp", "application/vnd.oasis.opendocument.presentation");
odp.setInputFamily(DocumentFamily.PRESENTATION);
odp.setStoreProperties(DocumentFamily.PRESENTATION, Collections.singletonMap("FilterName", "impress8"));
addFormat(odp);
DocumentFormat sxi = new DocumentFormat("OpenOffice.org 1.0 Presentation", "sxi", "application/vnd.sun.xml.impress");
sxi.setInputFamily(DocumentFamily.PRESENTATION);
sxi.setStoreProperties(DocumentFamily.PRESENTATION, Collections.singletonMap("FilterName", "StarOffice XML (Impress)"));
addFormat(sxi);
DocumentFormat ppt = new DocumentFormat("Microsoft PowerPoint", "ppt", "application/vnd.ms-powerpoint");
ppt.setInputFamily(DocumentFamily.PRESENTATION);
ppt.setStoreProperties(DocumentFamily.PRESENTATION, Collections.singletonMap("FilterName", "MS PowerPoint 97"));
addFormat(ppt);
DocumentFormat pptx = new DocumentFormat("Microsoft PowerPoint 2007 XML", "pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation");
pptx.setInputFamily(DocumentFamily.PRESENTATION);
addFormat(pptx);
DocumentFormat odg = new DocumentFormat("OpenDocument Drawing", "odg", "application/vnd.oasis.opendocument.graphics");
odg.setInputFamily(DocumentFamily.DRAWING);
odg.setStoreProperties(DocumentFamily.DRAWING, Collections.singletonMap("FilterName", "draw8"));
addFormat(odg);
DocumentFormat svg = new DocumentFormat("Scalable Vector Graphics", "svg", "image/svg+xml");
svg.setStoreProperties(DocumentFamily.DRAWING, Collections.singletonMap("FilterName", "draw_svg_Export"));
addFormat(svg);
}
}

View File

@@ -1,12 +1,12 @@
package cn.keking.service;
import com.sun.star.document.UpdateDocMode;
import cn.keking.utils.LocalOfficeUtils;
import org.apache.commons.lang3.StringUtils;
import org.artofsolving.jodconverter.OfficeDocumentConverter;
import org.artofsolving.jodconverter.office.DefaultOfficeManagerConfiguration;
import org.artofsolving.jodconverter.office.OfficeManager;
import org.artofsolving.jodconverter.office.OfficeUtils;
import org.artofsolving.jodconverter.util.PlatformUtils;
import org.jodconverter.core.office.InstalledOfficeManagerHolder;
import org.jodconverter.core.office.OfficeException;
import org.jodconverter.core.office.OfficeUtils;
import org.jodconverter.core.util.OSUtils;
import org.jodconverter.local.office.LocalOfficeManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
@@ -21,16 +21,13 @@ import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
/**
* 创建文件转换器
*
* @author yudian-it
* @date 2017/11/13
* @author chenjh
* @since 2022-12-15
*/
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
@@ -38,7 +35,7 @@ public class OfficePluginManager {
private final Logger logger = LoggerFactory.getLogger(OfficePluginManager.class);
private OfficeManager officeManager;
private LocalOfficeManager officeManager;
@Value("${office.plugin.server.ports:2001,2002}")
private String serverPorts;
@@ -50,8 +47,8 @@ public class OfficePluginManager {
* 启动Office组件进程
*/
@PostConstruct
public void startOfficeManager() {
File officeHome = OfficeUtils.getDefaultOfficeHome();
public void startOfficeManager() throws OfficeException {
File officeHome = LocalOfficeUtils.getDefaultOfficeHome();
if (officeHome == null) {
throw new RuntimeException("找不到office组件请确认'office.home'配置是否有误");
}
@@ -60,45 +57,26 @@ public class OfficePluginManager {
logger.warn("检测到有正在运行的office进程已自动结束该进程");
}
try {
DefaultOfficeManagerConfiguration configuration = new DefaultOfficeManagerConfiguration();
configuration.setOfficeHome(officeHome);
String[] portsString = serverPorts.split(",");
int[] ports = Arrays.stream(portsString).mapToInt(Integer::parseInt).toArray();
configuration.setPortNumbers(ports);
long timeout = DurationStyle.detectAndParse(timeOut).toMillis();
// 设置任务执行超时为5分钟
configuration.setTaskExecutionTimeout(timeout);
// 设置任务队列超时为24小时
//configuration.setTaskQueueTimeout(1000 * 60 * 60 * 24L);
officeManager = configuration.buildOfficeManager();
officeManager = LocalOfficeManager.builder()
.officeHome(officeHome)
.portNumbers(ports)
.processTimeout(timeout)
.build();
officeManager.start();
InstalledOfficeManagerHolder.setInstance(officeManager);
} catch (Exception e) {
logger.error("启动office组件失败请检查office组件是否可用");
throw e;
}
}
public OfficeDocumentConverter getDocumentConverter() {
OfficeDocumentConverter converter = new OfficeDocumentConverter(officeManager, new OfficePluginExtendFormatRegistry());
converter.setDefaultLoadProperties(getLoadProperties());
return converter;
}
private Map<String, ?> getLoadProperties() {
Map<String, Object> loadProperties = new HashMap<>(10);
loadProperties.put("Hidden", true);
loadProperties.put("ReadOnly", true);
loadProperties.put("UpdateDocMode", UpdateDocMode.QUIET_UPDATE);
loadProperties.put("CharacterSet", StandardCharsets.UTF_8.name());
return loadProperties;
}
private boolean killProcess() {
boolean flag = false;
try {
if (PlatformUtils.isWindows()) {
if (OSUtils.IS_OS_WINDOWS) {
Process p = Runtime.getRuntime().exec("cmd /c tasklist ");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
InputStream os = p.getInputStream();
@@ -111,21 +89,7 @@ public class OfficePluginManager {
Runtime.getRuntime().exec("taskkill /im " + "soffice.bin" + " /f");
flag = true;
}
} else if (PlatformUtils.isLinux()) {
Process p = Runtime.getRuntime().exec(new String[]{"sh", "-c", "ps -ef | grep " + "soffice.bin" + " |grep -v grep | wc -l"});
ByteArrayOutputStream baos = new ByteArrayOutputStream();
InputStream os = p.getInputStream();
byte[] b = new byte[256];
while (os.read(b) > 0) {
baos.write(b);
}
String s = baos.toString();
if (!s.startsWith("0")) {
String[] cmd = {"sh", "-c", "ps -ef | grep soffice.bin | grep -v grep | awk '{print \"kill -9 \"$2}' | sh"};
Runtime.getRuntime().exec(cmd);
flag = true;
}
} else {
} else if (OSUtils.IS_OS_MAC || OSUtils.IS_OS_MAC_OSX) {
Process p = Runtime.getRuntime().exec(new String[]{"sh", "-c", "ps -ef | grep " + "soffice.bin"});
ByteArrayOutputStream baos = new ByteArrayOutputStream();
InputStream os = p.getInputStream();
@@ -139,6 +103,20 @@ public class OfficePluginManager {
Runtime.getRuntime().exec(cmd);
flag = true;
}
} else {
Process p = Runtime.getRuntime().exec(new String[]{"sh", "-c", "ps -ef | grep " + "soffice.bin" + " |grep -v grep | wc -l"});
ByteArrayOutputStream baos = new ByteArrayOutputStream();
InputStream os = p.getInputStream();
byte[] b = new byte[256];
while (os.read(b) > 0) {
baos.write(b);
}
String s = baos.toString();
if (!s.startsWith("0")) {
String[] cmd = {"sh", "-c", "ps -ef | grep soffice.bin | grep -v grep | awk '{print \"kill -9 \"$2}' | sh"};
Runtime.getRuntime().exec(cmd);
flag = true;
}
}
} catch (IOException e) {
logger.error("检测office进程异常", e);
@@ -150,7 +128,7 @@ public class OfficePluginManager {
public void destroyOfficeManager() {
if (null != officeManager && officeManager.isRunning()) {
logger.info("Shutting down office process");
officeManager.stop();
OfficeUtils.stopQuietly(officeManager);
}
}

View File

@@ -1,7 +1,7 @@
package cn.keking.service;
import cn.keking.model.FileAttribute;
import org.artofsolving.jodconverter.OfficeDocumentConverter;
import org.jodconverter.core.office.OfficeException;
import org.jodconverter.local.JodConverter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@@ -15,30 +15,23 @@ import java.io.File;
public class OfficeToPdfService {
private final static Logger logger = LoggerFactory.getLogger(OfficeToPdfService.class);
private final OfficePluginManager officePluginManager;
public OfficeToPdfService(OfficePluginManager officePluginManager) {
this.officePluginManager = officePluginManager;
}
public void openOfficeToPDF(String inputFilePath, String outputFilePath, FileAttribute fileAttribute) {
office2pdf(inputFilePath, outputFilePath, fileAttribute);
public void openOfficeToPDF(String inputFilePath, String outputFilePath) throws OfficeException {
office2pdf(inputFilePath, outputFilePath);
}
public static void converterFile(File inputFile, String outputFilePath_end, OfficeDocumentConverter converter, FileAttribute fileAttribute) {
public static void converterFile(File inputFile, String outputFilePath_end) throws OfficeException {
File outputFile = new File(outputFilePath_end);
// 假如目标路径不存在,则新建该路径
if (!outputFile.getParentFile().exists() && !outputFile.getParentFile().mkdirs()) {
logger.error("创建目录【{}】失败,请检查目录权限!",outputFilePath_end);
}
converter.convert(inputFile, outputFile, fileAttribute.toFileProperties());
JodConverter.convert(inputFile).to(outputFile).execute();
}
public void office2pdf(String inputFilePath, String outputFilePath, FileAttribute fileAttribute) {
OfficeDocumentConverter converter = officePluginManager.getDocumentConverter();
public void office2pdf(String inputFilePath, String outputFilePath) throws OfficeException {
if (null != inputFilePath) {
File inputFile = new File(inputFilePath);
// 判断目标文件路径是否为空
@@ -47,12 +40,12 @@ public class OfficeToPdfService {
String outputFilePath_end = getOutputFilePath(inputFilePath);
if (inputFile.exists()) {
// 找不到源文件, 则返回
converterFile(inputFile, outputFilePath_end, converter, fileAttribute);
converterFile(inputFile, outputFilePath_end);
}
} else {
if (inputFile.exists()) {
// 找不到源文件, 则返回
converterFile(inputFile, outputFilePath, converter, fileAttribute);
converterFile(inputFile, outputFilePath);
}
}
}

View File

@@ -1,7 +1,7 @@
package cn.keking.service.cache.impl;
import cn.keking.service.cache.CacheService;
import org.artofsolving.jodconverter.util.ConfigUtils;
import cn.keking.utils.ConfigUtils;
import org.rocksdb.RocksDB;
import org.rocksdb.RocksDBException;
import org.slf4j.Logger;

View File

@@ -5,10 +5,10 @@ import cn.keking.model.FileAttribute;
import cn.keking.model.FileType;
import cn.keking.model.ReturnResponse;
import cn.keking.service.FilePreview;
import cn.keking.utils.ConfigUtils;
import cn.keking.utils.DownloadUtils;
import cn.keking.service.FileHandlerService;
import cn.keking.web.filter.BaseUrlFilter;
import org.artofsolving.jodconverter.util.ConfigUtils;
import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FFmpegFrameRecorder;

View File

@@ -9,7 +9,7 @@ import cn.keking.service.OfficeToPdfService;
import cn.keking.utils.DownloadUtils;
import cn.keking.utils.OfficeUtils;
import cn.keking.web.filter.BaseUrlFilter;
import org.artofsolving.jodconverter.office.OfficeException;
import org.jodconverter.core.office.OfficeException;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
@@ -83,7 +83,7 @@ public class OfficeFilePreviewImpl implements FilePreview {
isPwdProtectedOffice = OfficeUtils.isPwdProtected(filePath);
}
if (isCached == false) {
if (!isCached) {
// 没有缓存执行转换逻辑
if (isPwdProtectedOffice && !StringUtils.hasLength(filePassword)) {
// 加密文件需要密码
@@ -92,9 +92,9 @@ public class OfficeFilePreviewImpl implements FilePreview {
} else {
if (StringUtils.hasText(outFilePath)) {
try {
officeToPdfService.openOfficeToPDF(filePath, outFilePath, fileAttribute);
officeToPdfService.openOfficeToPDF(filePath, outFilePath);
} catch (OfficeException e) {
if (isPwdProtectedOffice && OfficeUtils.isCompatible(filePath, filePassword) == false) {
if (isPwdProtectedOffice && !OfficeUtils.isCompatible(filePath, filePassword)) {
// 加密文件密码错误,提示重新输入
model.addAttribute("needFilePassword", true);
model.addAttribute("filePasswordError", true);

View File

@@ -0,0 +1,99 @@
package cn.keking.utils;
import java.io.File;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
/**
* @author : kl
**/
public class ConfigUtils {
private static final String MAIN_DIRECTORY_NAME = "server";
public static String getHomePath() {
String userDir = System.getenv("KKFILEVIEW_BIN_FOLDER");
if (userDir == null) {
userDir = System.getProperty("user.dir");
}
if (userDir.endsWith("bin")) {
userDir = userDir.substring(0, userDir.length() - 4);
} else {
String separator = File.separator;
if (userDir.endsWith(MAIN_DIRECTORY_NAME)) {
userDir = userDir + separator + "src" + separator + "main";
} else {
userDir = userDir + separator + MAIN_DIRECTORY_NAME + separator + "src" + separator + "main";
}
}
return userDir;
}
// 获取环境变量,如果找不到则返回默认值
@SuppressWarnings("SameParameterValue")
private static String getEnvOrDefault(String key, String def) {
String value = System.getenv(key);
return value == null ? def : value;
}
// 返回参数列表中第一个真实存在的路径,或者 null
private static String firstExists(File... paths) {
for (File path : paths) {
if (path.exists()) {
return path.getAbsolutePath();
}
}
return null;
}
public static String getUserDir() {
String userDir = System.getProperty("user.dir");
String binFolder = getEnvOrDefault("KKFILEVIEW_BIN_FOLDER", userDir);
File pluginPath = new File(binFolder);
// 如果指定了 bin 或其父目录,则返回父目录
if (new File(pluginPath, "bin").exists()) {
return pluginPath.getAbsolutePath();
} else if (pluginPath.exists() && pluginPath.getName().equals("bin")) {
return pluginPath.getParentFile().getAbsolutePath();
} else {
return firstExists(new File(pluginPath, MAIN_DIRECTORY_NAME),
new File(pluginPath.getParentFile(), MAIN_DIRECTORY_NAME));
}
}
public static String getCustomizedConfigPath() {
String homePath = getHomePath();
String separator = java.io.File.separator;
return homePath + separator + "config" + separator + "application.properties";
}
public synchronized static void restorePropertiesFromEnvFormat(Properties properties) {
Iterator<Map.Entry<Object, Object>> iterator = properties.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<Object, Object> entry = iterator.next();
String key = entry.getKey().toString();
String value = entry.getValue().toString();
if (value.trim().startsWith("${") && value.trim().endsWith("}")) {
int beginIndex = value.indexOf(":");
if (beginIndex < 0) {
beginIndex = value.length() - 1;
}
int endIndex = value.length() - 1;
String envKey = value.substring(2, beginIndex);
String envValue = System.getenv(envKey);
if (envValue == null || "".equals(envValue.trim())) {
value = value.substring(beginIndex + 1, endIndex);
} else {
value = envValue;
}
properties.setProperty(key, value);
}
}
}
}

View File

@@ -0,0 +1,111 @@
package cn.keking.utils;
import org.jodconverter.core.util.OSUtils;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Properties;
import java.util.stream.Stream;
/**
* @author chenjh
* @since 2022-12-15
*/
public class LocalOfficeUtils {
public static final String OFFICE_HOME_KEY = "office.home";
public static final String DEFAULT_OFFICE_HOME_VALUE = "default";
private static final String EXECUTABLE_DEFAULT = "program/soffice.bin";
private static final String EXECUTABLE_MAC = "program/soffice";
private static final String EXECUTABLE_MAC_41 = "MacOS/soffice";
private static final String EXECUTABLE_WINDOWS = "program/soffice.exe";
public static File getDefaultOfficeHome() {
Properties properties = new Properties();
String customizedConfigPath = ConfigUtils.getCustomizedConfigPath();
try {
BufferedReader bufferedReader = new BufferedReader(new FileReader(customizedConfigPath));
properties.load(bufferedReader);
ConfigUtils.restorePropertiesFromEnvFormat(properties);
} catch (Exception ignored) {}
String officeHome = properties.getProperty(OFFICE_HOME_KEY);
if (officeHome != null && !DEFAULT_OFFICE_HOME_VALUE.equals(officeHome)) {
return new File(officeHome);
}
if (OSUtils.IS_OS_WINDOWS) {
String userDir = ConfigUtils.getUserDir();
// Try to find the most recent version of LibreOffice or OpenOffice,
// starting with the 64-bit version. %ProgramFiles(x86)% on 64-bit
// machines; %ProgramFiles% on 32-bit ones
final String programFiles64 = System.getenv("ProgramFiles");
final String programFiles32 = System.getenv("ProgramFiles(x86)");
return findOfficeHome(EXECUTABLE_WINDOWS,
userDir + File.separator + "windows-office",
programFiles32 + File.separator + "LibreOffice",
programFiles64 + File.separator + "LibreOffice 7",
programFiles32 + File.separator + "LibreOffice 7",
programFiles64 + File.separator + "LibreOffice 6",
programFiles32 + File.separator + "LibreOffice 6",
programFiles64 + File.separator + "LibreOffice 5",
programFiles32 + File.separator + "LibreOffice 5",
programFiles64 + File.separator + "LibreOffice 4",
programFiles32 + File.separator + "LibreOffice 4",
programFiles32 + File.separator + "OpenOffice 4",
programFiles64 + File.separator + "LibreOffice 3",
programFiles32 + File.separator + "LibreOffice 3",
programFiles32 + File.separator + "OpenOffice.org 3");
} else if (OSUtils.IS_OS_MAC) {
File homeDir = findOfficeHome(EXECUTABLE_MAC_41,
"/Applications/LibreOffice.app/Contents",
"/Applications/OpenOffice.app/Contents",
"/Applications/OpenOffice.org.app/Contents");
if (homeDir == null) {
homeDir = findOfficeHome(EXECUTABLE_MAC,
"/Applications/LibreOffice.app/Contents",
"/Applications/OpenOffice.app/Contents",
"/Applications/OpenOffice.org.app/Contents");
}
return homeDir;
} else {
// Linux or other *nix variants
return findOfficeHome(EXECUTABLE_DEFAULT,
"/opt/libreoffice6.0",
"/opt/libreoffice6.1",
"/opt/libreoffice6.2",
"/opt/libreoffice6.3",
"/opt/libreoffice6.4",
"/opt/libreoffice7.0",
"/opt/libreoffice7.1",
"/opt/libreoffice7.2",
"/opt/libreoffice7.3",
"/opt/libreoffice7.4",
"/opt/libreoffice7.5",
"/usr/lib64/libreoffice",
"/usr/lib/libreoffice",
"/usr/local/lib64/libreoffice",
"/usr/local/lib/libreoffice",
"/opt/libreoffice",
"/usr/lib64/openoffice",
"/usr/lib64/openoffice.org3",
"/usr/lib64/openoffice.org",
"/usr/lib/openoffice",
"/usr/lib/openoffice.org3",
"/usr/lib/openoffice.org",
"/opt/openoffice4",
"/opt/openoffice.org3");
}
}
private static File findOfficeHome(final String executablePath, final String... homePaths) {
return Stream.of(homePaths)
.filter(homePath -> Files.isRegularFile(Paths.get(homePath, executablePath)))
.findFirst()
.map(File::new)
.orElse(null);
}
}

View File

@@ -3,7 +3,7 @@ package cn.keking.web.filter;
import cn.keking.config.ConfigConstants;
import cn.keking.utils.WebUtils;
import io.mola.galimatias.GalimatiasParseException;
import org.artofsolving.jodconverter.util.PlatformUtils;
import org.jodconverter.core.util.OSUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;
@@ -63,7 +63,7 @@ public class TrustDirFilter implements Filter {
URL url = WebUtils.normalizedURL(urlPath);
if ("file".equals(url.getProtocol().toLowerCase(Locale.ROOT))) {
String filePath = URLDecoder.decode(url.getPath(), StandardCharsets.UTF_8.name());
if (PlatformUtils.isWindows()) {
if (OSUtils.IS_OS_WINDOWS) {
filePath = filePath.replaceAll("/", "\\\\");
}
return filePath.startsWith(ConfigConstants.getFileDir()) || filePath.startsWith(ConfigConstants.getLocalPreviewDir());

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,159 @@
Portions of LibreOffice may include work under the Apache License v2.0
requiring this NOTICE file to be provided.
For a more complete license statement please see the associated
documentation
____
Apache OpenOffice (http://www.openoffice.org)
Copyright 2011, 2014 The Apache Software Foundation
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).
____
Portions of this software copyright (c) 2000-2011, Oracle and/or its affiliates <http://www.oracle.com/>.
Portions of this software (C) Copyright IBM Corporation 2003, 2012. All Rights Reserved.
____
As part of the base system this product also includes code from the following
Apache projects:
- Apache Lucene
- Apache Portable Runtime
- Apache Portable Runtime Utility Library
- Apache Commons - used by MediaWiki Publisher extension
- Apache Jakarta HttpClient - used by MediaWiki Publisher extension
- Apache Tomcat - used by MediaWiki Publisher extension
The notices from these projects are following:
Apache Lucene
Copyright 2006 The Apache Software Foundation
This product includes software developed by
The Apache Software Foundation (http://www.apache.org/).
The snowball stemmers in
contrib/snowball/src/java/net/sf/snowball
were developed by Martin Porter and Richard Boulton.
The full snowball package is available from
http://snowball.tartarus.org/
Apache Portable Runtime
Copyright (c) 2011 The Apache Software Foundation.
This product includes software developed by
The Apache Software Foundation (http://www.apache.org/).
Portions of this software were developed at the National Center
for Supercomputing Applications (NCSA) at the University of
Illinois at Urbana-Champaign.
This software contains code derived from the RSA Data Security
Inc. MD5 Message-Digest Algorithm.
This software contains code derived from UNIX V7, Copyright(C)
Caldera International Inc.
Apache Portable Runtime Utility Library
Copyright (c) 2011 The Apache Software Foundation.
This product includes software developed by
The Apache Software Foundation (http://www.apache.org/).
Portions of this software were developed at the National Center
for Supercomputing Applications (NCSA) at the University of
Illinois at Urbana-Champaign.
This software contains code derived from the RSA Data Security
Inc. MD5 Message-Digest Algorithm, including various
modifications by Spyglass Inc., Carnegie Mellon University, and
Bell Communications Research, Inc (Bellcore).
Apache Commons Codec
Copyright 2002-2012 The Apache Software Foundation
This product includes software developed by
The Apache Software Foundation (http://www.apache.org/).
src/test/org/apache/commons/codec/language/DoubleMetaphoneTest.java contains
test data from http://aspell.sourceforge.net/test/batch0.tab.
Copyright (C) 2002 Kevin Atkinson (kevina@gnu.org). Verbatim copying
and distribution of this entire article is permitted in any medium,
provided this notice is preserved.
Apache Jakarta HttpClient
Copyright 1999-2007 The Apache Software Foundation
This product includes software developed by
The Apache Software Foundation (http://www.apache.org/).
Apache Commons Lang
Copyright 2001-2012 The Apache Software Foundation
This product includes software developed by
The Apache Software Foundation (http://www.apache.org/).
This product includes software from the Spring Framework,
under the Apache License 2.0 (see: StringUtils.containsWhitespace())
Apache Commons Logging
Copyright 2003-2007 The Apache Software Foundation
This product includes software developed by
The Apache Software Foundation (http://www.apache.org/).
Apache Tomcat
Copyright 1999-2012 The Apache Software Foundation
This product includes software developed by
The Apache Software Foundation (http://www.apache.org/).
Java Management Extensions (JMX) support is provided by
the MX4J package, which is open source software. The
original software and related information is available
at http://mx4j.sourceforge.net/.
Java compilation software for JSP pages is provided by Eclipse,
which is open source software. The original software and
related information is available at
http://www.eclipse.org/.
____
As part of the base system this product may also includes code from the following
projects which are licensed under the Apache license:
- serf
- redland
- Apache BeanShell Scripting for Java
The notices from these projects are following:
serf
This product includes software developed by
The Apache Software Foundation (http://www.apache.org/).
redland
This product includes Redland software (http://librdf.org/)
developed at the Institute for Learning and Research Technology,
University of Bristol, UK (http://www.bristol.ac.uk/).
Apache BeanShell Scripting for Java
Copyright 1997-2012 Patrick Niemeyer
Granted to the Apache Software Foundation 2012
Licensed under the Apache License, Version 2.0.
____
This product includes software developed by the OpenSSL Project
for use in the OpenSSL Toolkit. (http://www.openssl.org/)

View File

@@ -0,0 +1,100 @@
/*
MIT License
Copyright (c) 2016 Edenspiekermann
*/
(function () {
'use strict';
var internalId = 0;
var togglesMap = {};
var targetsMap = {};
function $ (selector, context) {
return Array.prototype.slice.call(
(context || document).querySelectorAll(selector)
);
}
function getClosestToggle (element) {
if (element.closest) {
return element.closest('[data-a11y-toggle]');
}
while (element) {
if (element.nodeType === 1 && element.hasAttribute('data-a11y-toggle')) {
return element;
}
element = element.parentNode;
}
return null;
}
function handleToggle (toggle) {
var target = toggle && targetsMap[toggle.getAttribute('aria-controls')];
if (!target) {
return false;
}
var toggles = togglesMap['#' + target.id];
var isExpanded = target.getAttribute('aria-hidden') === 'false';
target.setAttribute('aria-hidden', isExpanded);
toggles.forEach(function (toggle) {
toggle.setAttribute('aria-expanded', !isExpanded);
});
}
var initA11yToggle = function (context) {
togglesMap = $('[data-a11y-toggle]', context).reduce(function (acc, toggle) {
var selector = '#' + toggle.getAttribute('data-a11y-toggle');
acc[selector] = acc[selector] || [];
acc[selector].push(toggle);
return acc;
}, togglesMap);
var targets = Object.keys(togglesMap);
targets.length && $(targets).forEach(function (target) {
var toggles = togglesMap['#' + target.id];
var isExpanded = target.hasAttribute('data-a11y-toggle-open');
var labelledby = [];
toggles.forEach(function (toggle) {
toggle.id || toggle.setAttribute('id', 'a11y-toggle-' + internalId++);
toggle.setAttribute('aria-controls', target.id);
toggle.setAttribute('aria-expanded', isExpanded);
labelledby.push(toggle.id);
});
target.setAttribute('aria-hidden', !isExpanded);
target.hasAttribute('aria-labelledby') || target.setAttribute('aria-labelledby', labelledby.join(' '));
targetsMap[target.id] = target;
});
};
document.addEventListener('DOMContentLoaded', function () {
initA11yToggle();
});
document.addEventListener('click', function (event) {
var toggle = getClosestToggle(event.target);
handleToggle(toggle);
});
document.addEventListener('keyup', function (event) {
if (event.which === 13 || event.which === 32) {
var toggle = getClosestToggle(event.target);
if (toggle && toggle.getAttribute('role') === 'button') {
handleToggle(toggle);
}
}
});
window && (window.a11yToggle = initA11yToggle);
})();

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,46 @@
<!DOCTYPE html>
<!--
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
-->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline' 'unsafe-eval' piwik.documentfoundation.org"/>
</head>
<body>
<script type="text/javascript">
function getParameterByName(name, url) {
if (!url) {
url = window.location.href;
}
name = name.replace(/[\[\]]/g, "\\$&");
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)");
var results = regex.exec(url);
if (!results) {
return null;
}
if (!results[2]) {
return '';
}
return decodeURIComponent(results[2].replace(/\+/g, " "));
}
var url = window.location.href;
var n = url.indexOf('?');
if (n != -1) {
// the URL came from LibreOffice help (F1)
var version = getParameterByName("Version", url);
var query = url.substr(n + 1, url.length);
var newURL = version + '/index.html?' + query;
window.location.replace(newURL);
} else {
window.location.replace('latest/index.html');
}
</script>
</body>
</html>

View File

@@ -0,0 +1,188 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
// Pagination and fuzzy search
var url = window.location.pathname;
var moduleRegex = new RegExp('text\\/(\\w+)\\/');
var regexArray = moduleRegex.exec(url);
var modules = ['CALC', 'WRITER', 'IMPRESS', 'DRAW', 'BASE', 'MATH', 'CHART', 'BASIC', 'SHARED'];
var indexEl = document.getElementsByClassName("index")[0];
var fullLinks = fullLinkify(indexEl, bookmarks, modules, currentModule());
var search = document.getElementById('search-bar');
search.addEventListener('keyup', debounce(filter, 100, indexEl));
// Preserve search input value during the session
search.value = sessionStorage.getItem('searchsave');
if (search.value !== undefined) {
filter(indexEl);
}
window.addEventListener('unload', function(event) {
sessionStorage.setItem('searchsave', search.value);
});
// render the unfiltered index list on page load
fillIndex(indexEl, fullLinks, modules);
function currentModule() {
var module = '';
// get the module name from the URL and remove the first character,
// but first deal with snowflake Base
if(url.indexOf('explorer/database/') !== -1) {
module = 'BASE';
} else {
if (null === regexArray){// comes from search or elsewhere, no defined module in URL
module = 'HARED'
} else {
module = regexArray[1].toUpperCase().substring(1);
}
}
return module;
};
function fullLinkify(indexEl, bookmarks, modules, currentModule) {
var fullLinkified = '';
// if user is not on a shared category page, limit the index to the current module + shared
if(currentModule !== 'HARED') {
bookmarks = bookmarks.filter(function(obj) {
return obj['app'] === currentModule || obj['app'] === 'SHARED';
});
}
bookmarks.forEach(function(obj) {
fullLinkified += '<a href="' + obj['url'] + '" class="' + obj['app'] + '">' + obj['text'] + '</a>';
});
return fullLinkified;
}
function fillIndex(indexEl, content, modules) {
indexEl.innerHTML = content;
var indexKids = indexEl.children;
for (var i = 0, len = indexKids.length; i < len; i++) {
indexKids[i].removeAttribute("id");
}
modules.forEach(function(module) {
var moduleHeader = indexEl.getElementsByClassName(module)[0];
if (typeof moduleHeader !== 'undefined') {
// let's wrap the header in a span, so the ::before element will not become a link
moduleHeader.outerHTML = '<span id="' + module + '" class="' + module + '">' + moduleHeader.outerHTML + '</span>';
}
});
Paginator(indexEl);
}
// filter the index list based on search field input
function filter(indexList) {
var results = null;
var target = search.value.trim();
var filtered = '';
if (target.length < 1) {
fillIndex(indexEl, fullLinks, modules);
return;
}
results = fuzzysort.go(target, bookmarks, {threshold: -15000, key:'text'});
results.forEach(function(result) {
filtered += '<a href="' + result.obj['url'] + '" class="' + result.obj['app'] + '">' + fuzzysort.highlight(result) + '</a>';
});
fillIndex(indexList, filtered, modules);
};
// delay the rendering of the filtered results while user is typing
function debounce(fn, wait, indexList) {
var timeout;
return function() {
clearTimeout(timeout);
timeout = setTimeout(function() {
fn.call(this, indexList);
}, (wait || 150));
};
}
// copy pycode and bascode to clipboard on mouse click
// Show border when copy is done
divcopyable(document.getElementsByClassName("bascode"));
divcopyable(document.getElementsByClassName("pycode"));
function divcopyable(itemcopyable){
for (var i = 0, len = itemcopyable.length; i < len; i++) {
(function() {
var item = itemcopyable[i];
function changeBorder(item, color) {
var saveBorder = item.style.border;
item.style.borderColor = color;
setTimeout(function() {
item.style.border = saveBorder;
}, 150);
}
item.onclick = function() {
document.execCommand("copy");
changeBorder(item, "#18A303");
};
item.addEventListener("copy", function(event) {
event.preventDefault();
if (event.clipboardData) {
event.clipboardData.setData("text/plain", item.textContent);
}
});
}());
}
}
// copy useful content to clipboard on mouse click
var copyable = document.getElementsByClassName("input");
for (var i = 0, len = copyable.length; i < len; i++) {
(function() {
var item = copyable[i];
function changeColor(item, color, colorToChangeBackTo) {
item.style.backgroundColor = color;
setTimeout(function() {
item.style.backgroundColor = colorToChangeBackTo;
}, 150);
}
item.onclick = function() {
document.execCommand("copy");
changeColor(item, "#18A303", "transparent");
};
item.addEventListener("copy", function(event) {
event.preventDefault();
if (event.clipboardData) {
event.clipboardData.setData("text/plain", item.textContent);
}
});
}());
}
// auto-expand contents per subitem
var pathname = window.location.pathname;
var pathRegex = /text\/.*\.html$/;
var linkIndex = 0;
var contentMatch = pathname.match(pathRegex);
function linksMatch(content) {
var linkMatch = new RegExp(content);
var links = document.getElementById("Contents").getElementsByTagName("a");
for (var i = 0, len = links.length; i < len; i++) {
if (links[i].href.match(linkMatch)) {
return i;
}
}
}
linkIndex = linksMatch(contentMatch);
if (typeof linkIndex !== "undefined") {
var current = document.getElementById("Contents").getElementsByTagName("a")[linkIndex];
var cItem = current.parentElement;
var parents = [];
while (cItem.parentElement && !cItem.parentElement.matches("#Contents") && parents.indexOf(cItem.parentElement) == -1) {
parents.push(cItem = cItem.parentElement);
}
var liParents = [].filter.call(parents, function(item) {
return item.matches("li");
});
for (var i = 0, len = liParents.length; i < len; i++) {
var input = liParents[i].querySelectorAll(':scope > input');
document.getElementById(input[0].id).checked = true;
}
current.classList.add('contents-current');
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */

View File

@@ -0,0 +1,266 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
// Used to set Application in caseinline=APP
function setApplSpan(spanZ) {
var module = getParameterByName("DbPAR");
if (module === null) {
module = "WRITER";
}
var y = spanZ.getElementsByTagName("SPAN");
var n = y.length;
var foundAppl = false;
for (i = 0; i < n; i++) {
if (y[i].getAttribute("id") === null){
continue;
}
else if( y[i].getAttribute("id").startsWith(module)){
y[i].removeAttribute("hidden");
foundAppl=true;
}
}
for (i = 0; i < n; i++) {
if (y[i].getAttribute("id") === null){
continue;
}
else if( y[i].getAttribute("id").startsWith("default")){
if(!foundAppl){
y[i].removeAttribute("hidden");
}
}
}
}
// Used to set system in case, caseinline=SYSTEM
function setSystemSpan(spanZ) {
// if no System in URL, get browser system
var system = getParameterByName("System");
if (system === null) {
system = getSystem();
}
var y = spanZ.getElementsByTagName("SPAN");
var n = y.length;
var foundSystem = false;
for (i = 0; i < n; i++) {
if (y[i].getAttribute("id") === null){
continue;
}
else if( y[i].getAttribute("id").startsWith(system)){
y[i].removeAttribute("hidden");
foundSystem=true;
}
}
for (i = 0; i < n; i++) {
if (y[i].getAttribute("id") === null){
continue;
}
else if( y[i].getAttribute("id").startsWith("default")){
if(!foundSystem){
y[i].removeAttribute("hidden");
}
}
}
}
// paint headers and headings with appl color
function moduleColor (module) {
switch (module){
case "WRITER" : {color="#0369A3"; break;}
case "CALC" : {color="#43C330"; break;}
case "CHART" : {color="darkcyan"; break;}
case "IMPRESS": {color="#A33E03"; break;}
case "DRAW" : {color="#C99C00"; break;}
case "BASE" : {color="#8E03A3"; break;}
case "BASIC" : {color="black"; break;}
case "MATH" : {color="darkslategray"; break;}
case "SHARED" : {color="gray"; break;}
default : {color="#18A303"; break;}
}
document.getElementById("TopLeftHeader").style.background = color;
document.getElementById("SearchFrame").style.background = color;
document.getElementById("DonationFrame").style.background = color;
var cols = document.getElementsByClassName('tableheadcell');
for(i = 0; i < cols.length; i++) {cols[i].style.backgroundColor = color;};
for (j of [1,2,3,4,5,6]) {
var hh = document.getElementsByTagName("H" + j);
for(i = 0; i < hh.length; i++) {
hh[i].style.color = color;
hh[i].style.borderBottomColor = color;
}
}
}
// Find spans that need the switch treatment and give it to them
var spans = document.querySelectorAll("[class^=switch]");
var n = spans.length;
for (z = 0; z < n; z++) {
var id = spans[z].getAttribute("id");
if (id === null) {
continue;
}
else if (id.startsWith("swlnsys")) {
setSystemSpan(spans[z]);
} else {
setApplSpan(spans[z]);
}
}
/* add &DbPAR= and &System= to the links in DisplayArea div */
/* skip for object files */
function fixURL(module, system) {
if ((DisplayArea = document.getElementById("DisplayArea")) === null) return;
var itemlink = DisplayArea.getElementsByTagName("a");
var pSystem = (system === null) ? getSystem() : system;
var pAppl = (module === null) ? "WRITER" : module;
var n = itemlink.length;
for (var i = 0; i < n; i++) {
if (itemlink[i].getAttribute("class") != "objectfiles") {
setURLParam(itemlink[i], pSystem, pAppl);
}
}
}
//Set the params inside URL
function setURLParam(itemlink, pSystem, pAppl) {
var href = itemlink.getAttribute("href");
if (href !== null) {
// skip external links
if (!href.startsWith("http")) {
// handle bookmark.
if (href.lastIndexOf('#') != -1) {
var postf = href.substring(href.lastIndexOf('#'), href.length);
var pref = href.substring(0, href.lastIndexOf('#'));
itemlink.setAttribute("href", pref + "?" + '&DbPAR=' + pAppl + '&System=' + pSystem + postf);
} else {
itemlink.setAttribute("href", href + "?" + '&DbPAR=' + pAppl + '&System=' + pSystem);
}
}
}
}
function getSystem() {
var system = "Unknown OS";
if (navigator.appVersion.indexOf("Win") != -1) system = "WIN";
if (navigator.appVersion.indexOf("Mac") != -1) system = "MAC";
if (navigator.appVersion.indexOf("X11") != -1) system = "UNIX";
if (navigator.appVersion.indexOf("Linux") != -1) system = "UNIX";
return system;
}
function getParameterByName(name, url) {
if (!url) {
url = window.location.href;
}
name = name.replace(/[\[\]]/g, "\\$&");
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)");
var results = regex.exec(url);
if (!results) {
return null;
}
if (!results[2]) {
return '';
}
return decodeURIComponent(results[2].replace(/\+/g, " "));
}
function existingLang(lang) {
if (lang === undefined) {
return 'en-US';
}
if (languagesSet.has(lang)) {
return lang;
}
lang = lang.replace(/[-_].*/, '');
if (languagesSet.has(lang)) {
return lang;
}
return 'en-US';
}
function setupModules(lang) {
var modulesNav = document.getElementById('modules-nav');
if (!modulesNav.classList.contains('loaded')) {
var html =
'<a href="' + lang + '/text/swriter/main0000.html?DbPAR=WRITER"><div class="writer-icon"></div>Writer</a>' +
'<a href="' + lang + '/text/scalc/main0000.html?DbPAR=CALC"><div class="calc-icon"></div>Calc</a>' +
'<a href="' + lang + '/text/simpress/main0000.html?DbPAR=IMPRESS"><div class="impress-icon"></div>Impress</a>' +
'<a href="' + lang + '/text/sdraw/main0000.html?DbPAR=DRAW"><div class="draw-icon"></div>Draw</a>' +
'<a href="' + lang + '/text/sdatabase/main.html?DbPAR=BASE"><div class="base-icon"></div>Base</a>' +
'<a href="' + lang + '/text/smath/main0000.html?DbPAR=MATH"><div class="math-icon"></div>Math</a>' +
'<a href="' + lang + '/text/schart/main0000.html?DbPAR=CHART"><div class="chart-icon"></div>Chart</a>' +
'<a href="' + lang + '/text/sbasic/shared/main0601.html?DbPAR=BASIC"><div class="basic-icon"></div>Basic</a>';
modulesNav.innerHTML = html;
modulesNav.classList.add('loaded');
}
}
function setupLanguages(page) {
var langNav = document.getElementById('langs-nav');
if (!langNav.classList.contains('loaded')) {
var html = '';
languagesSet.forEach(function(lang) {
html += '<a href="' + lang + page + '">' + ((lang in languageNames)? languageNames[lang]: lang) + '</a>';
});
langNav.innerHTML = html;
langNav.classList.add('loaded');
}
}
// Test, if we are online
if (document.body.getElementsByTagName('meta')) {
var _paq = _paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(['disableCookies']);
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="//piwik.documentfoundation.org/";
_paq.push(['setTrackerUrl', u+'piwik.php']);
_paq.push(['setSiteId', '68']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s);
})();
var system = getParameterByName("System");
} else {
var system = getSystem();
}
var module = getParameterByName("DbPAR");
fixURL(module,system);
moduleColor(module);
var helpID = getParameterByName("HID");
// only used in xhp pages with <help-id-missing/> tags
var missingElement = document.getElementById("bm_HID2");
if(missingElement != null){missingElement.innerHTML = helpID;}
function debugInfo(dbg) {
if (dbg == null) return;
document.getElementById("DEBUG").style.display = "block";
document.getElementById("bm_module").innerHTML = "Module is: "+module;
document.getElementById("bm_system").innerHTML = "System is: "+system;
document.getElementById("bm_HID").innerHTML = "HID is: "+helpID;
}
debugInfo(getParameterByName("Debug"));
// Mobile devices need the modules and langs on page load
if (Math.max(document.documentElement.clientWidth, window.innerWidth || 0) < 960) {
var e = new Event('click');
var modulesBtn = document.getElementById('modules');
var langsBtn = document.getElementById('langs');
var modules = document.getElementById('modules-nav');
var langs = document.getElementById('langs-nav');
modules.setAttribute('data-a11y-toggle-open', '');
modulesBtn.dispatchEvent(e);
if (langs) {
langs.setAttribute('data-a11y-toggle-open', '');
langsBtn.dispatchEvent(e);
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,51 @@
<!--
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
-->
<xsl:stylesheet version="1.0" encoding="UTF-8"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:office="http://openoffice.org/2000/office"
xmlns:style="http://openoffice.org/2000/style"
xmlns:table="http://openoffice.org/2000/table"
xmlns:draw="http://openoffice.org/2000/drawing"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:meta="http://openoffice.org/2000/meta"
xmlns:number="http://openoffice.org/2000/datastyle"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:chart="http://openoffice.org/2000/chart"
xmlns:help="http://openoffice.org/2000/help"
xmlns:index="http://sun.com/2000/XMLSearch"
xmlns:text="http://openoffice.org/2000/text">
<xsl:param name="Language" select="'en-US'"/>
<xsl:output method="text" encoding="UTF-8"/>
<xsl:template match="/">
<xsl:apply-templates select="//title" mode="include"/>
<xsl:apply-templates select="//paragraph[@role='heading']" mode="include"/>
</xsl:template>
<xsl:template match="*" mode="include">
<xsl:value-of select="."/>
<xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="*"/>
</xsl:stylesheet>

View File

@@ -0,0 +1,131 @@
<!--
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
-->
<xsl:stylesheet version="1.0" encoding="UTF-8"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:office="http://openoffice.org/2000/office"
xmlns:style="http://openoffice.org/2000/style"
xmlns:table="http://openoffice.org/2000/table"
xmlns:draw="http://openoffice.org/2000/drawing"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:meta="http://openoffice.org/2000/meta"
xmlns:number="http://openoffice.org/2000/datastyle"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:chart="http://openoffice.org/2000/chart"
xmlns:help="http://openoffice.org/2000/help"
xmlns:index="http://sun.com/2000/XMLSearch"
xmlns:text="http://openoffice.org/2000/text">
<xsl:param name="Language" select="'en-US'"/>
<xsl:output method="text" encoding="UTF-8"/>
<xsl:template match="helpdocument|body">
<xsl:choose>
<xsl:when test="meta/topic[@indexer='exclude']"/>
<xsl:otherwise>
<xsl:apply-templates/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="title">
<xsl:value-of select="."/>
<xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="table">
<xsl:apply-templates/>
<xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="tablecell">
<xsl:apply-templates/>
<xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="tablerow">
<xsl:apply-templates/>
<xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="list">
<xsl:apply-templates/>
<xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="listitem">
<xsl:apply-templates/>
<xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="item">
<xsl:apply-templates/>
<xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="emph">
<xsl:apply-templates/>
<xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="sub">
<xsl:apply-templates/>
<xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="sup">
<xsl:apply-templates/>
<xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="paragraph">
<xsl:value-of select="."/>
<xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="section">
<xsl:apply-templates/>
<xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="bookmark">
<xsl:apply-templates/>
<xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="bookmark_value">
<xsl:apply-templates/>
<xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="link">
<xsl:apply-templates/>
<xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="ahelp[@visibility='visible']">
<xsl:value-of select="."/>
<xsl:text>&#xA;</xsl:text>
</xsl:template>
<xsl:template match="*"/>
</xsl:stylesheet>

View File

@@ -0,0 +1,74 @@
<!DOCTYPE html>
<!--
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
-->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline' 'unsafe-eval' piwik.documentfoundation.org"/>
<script type="text/javascript" src="polyfills.js"></script>
<script type="text/javascript" src="hid2file.js"></script>
<script type="text/javascript" src="languages.js"></script>
<script type="text/javascript" src="help2.js" defer></script>
</head>
<body>
<script type="text/javascript">
// We have to wait until both the deferred help2.js and the document have loaded
window.addEventListener('DOMContentLoaded', function() {
var url = window.location.href;
var n = url.indexOf('index.html?');
if (n != -1) {
// the URL came from LibreOffice help (F1)
var target = getParameterByName("Target",url);
var lang = existingLang(getParameterByName("Language", url));
var system = getParameterByName("System", url);
var module;
var defaultFile;
var smodule = target.substr(0, target.indexOf('/'));
switch (smodule) {
case "swriter": {defaultFile='text/swriter/main0000.html';module="WRITER";break;}
case "scalc": {defaultFile='text/scalc/main0000.html';module="CALC";break;}
case "schart": {defaultFile='text/schart/main0000.html';module="CHART";break;}
case "simpress": {defaultFile='text/simpress/main0000.html';module="IMPRESS";break;}
case "sdraw": {defaultFile='text/sdraw/main0000.html';module="DRAW";break;}
case "smath": {defaultFile='text/smath/main0000.html';module="MATH";break;}
case "sdatabase": {defaultFile='text/sdatabase/main.html';module="BASE";break;}
case "sbasic": {defaultFile='text/sbasic/shared/main0601.html';module="BASIC";break;}
default: {defaultFile='text/shared/05/new_help.html';module="WRITER";break;}
}
//Special case of application F1 or menu Help -> LibreOffice Help
if (target.indexOf('.uno:HelpIndex') != -1) {
window.location.replace(lang + '/' + defaultFile + '?System=' + system + '&DbPAR=' + module);
}
var bookmark = target.slice(target.indexOf('/') + 1, target.length);
var file = hid2fileMap[bookmark];
// check first if a root bookmark @@nowidget@@ can be used
if (file === undefined) {
var b2 = bookmark.substring(0, bookmark.lastIndexOf("/")) + '/@@nowidget@@';
file = hid2fileMap[b2];
}
// rebuild URL
if (file === undefined) {
var newURL = lang + '/text/shared/05/err_html.html?System=' + system + '&DbPAR=' + module + '&HID=' + bookmark ;
} else {
var indx = file.indexOf('#');
var bm = file.substr(indx,file.length);
file = file.substr(0,indx);
var newURL = lang + '/' + file + '?System=' + system + '&DbPAR=' + module + '&HID=' + bookmark + bm;
}
window.location.replace(newURL);
} else {
// URL came from elsewhere, direct access to webroot, we redirect to main Help page
var system = 'WIN';
if (navigator.userAgent.indexOf("Mac") != -1) system = 'MAC';
if (navigator.userAgent.indexOf("Linux") != -1) system = 'UNIX';
window.location.replace(existingLang(navigator.language) + '/text/shared/05/new_help.html?&DbPAR=WRITER&System=' + system);
}
});
</script>
</body>
</html>

View File

@@ -0,0 +1 @@
var languagesSet = new Set(['en-US', 'am', 'ar', 'ast', 'bg', 'bn', 'bn-IN', 'bo', 'bs', 'ca', 'ca-valencia', 'cs', 'da', 'de', 'dz', 'el', 'en-GB', 'en-ZA', 'eo', 'es', 'et', 'eu', 'fi', 'fr', 'gl', 'gu', 'he', 'hi', 'hr', 'hu', 'id', 'is', 'it', 'ja', 'ka', 'km', 'ko', 'lo', 'lt', 'lv', 'mk', 'nb', 'ne', 'nl', 'nn', 'om', 'pl', 'pt', 'pt-BR', 'ro', 'ru', 'si', 'sid', 'sk', 'sl', 'sq', 'sv', 'ta', 'tg', 'tr', 'ug', 'uk', 'vi', 'zh-CN', 'zh-TW']);

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 937 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 858 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 894 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 787 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 386 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 727 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 776 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 956 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 748 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 742 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 941 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 983 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Some files were not shown because too many files have changed in this diff Show More