移除office-plugin, 使用新版jodconverter
@@ -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 -->
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
99
server/src/main/java/cn/keking/utils/ConfigUtils.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
111
server/src/main/java/cn/keking/utils/LocalOfficeUtils.java
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
|
||||
16481
server/windows-office/CREDITS.fodt
Normal file
6787
server/windows-office/LICENSE.html
Normal file
159
server/windows-office/NOTICE
Normal 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/)
|
||||
|
||||
100
server/windows-office/help/a11y-toggle.js
Normal 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);
|
||||
})();
|
||||
907
server/windows-office/help/default.css
Normal file
608
server/windows-office/help/fuzzysort.js
Normal file
46
server/windows-office/help/help.html
Normal 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>
|
||||
|
||||
188
server/windows-office/help/help.js
Normal 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: */
|
||||
266
server/windows-office/help/help2.js
Normal 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: */
|
||||
8433
server/windows-office/help/hid2file.js
Normal file
51
server/windows-office/help/idxcaption.xsl
Normal 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>
</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="*"/>
|
||||
|
||||
</xsl:stylesheet>
|
||||
|
||||
131
server/windows-office/help/idxcontent.xsl
Normal 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>
</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="table">
|
||||
<xsl:apply-templates/>
|
||||
<xsl:text>
</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="tablecell">
|
||||
<xsl:apply-templates/>
|
||||
<xsl:text>
</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="tablerow">
|
||||
<xsl:apply-templates/>
|
||||
<xsl:text>
</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="list">
|
||||
<xsl:apply-templates/>
|
||||
<xsl:text>
</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="listitem">
|
||||
<xsl:apply-templates/>
|
||||
<xsl:text>
</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="item">
|
||||
<xsl:apply-templates/>
|
||||
<xsl:text>
</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="emph">
|
||||
<xsl:apply-templates/>
|
||||
<xsl:text>
</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="sub">
|
||||
<xsl:apply-templates/>
|
||||
<xsl:text>
</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="sup">
|
||||
<xsl:apply-templates/>
|
||||
<xsl:text>
</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="paragraph">
|
||||
<xsl:value-of select="."/>
|
||||
<xsl:text>
</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="section">
|
||||
<xsl:apply-templates/>
|
||||
<xsl:text>
</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="bookmark">
|
||||
<xsl:apply-templates/>
|
||||
<xsl:text>
</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="bookmark_value">
|
||||
<xsl:apply-templates/>
|
||||
<xsl:text>
</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="link">
|
||||
<xsl:apply-templates/>
|
||||
<xsl:text>
</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="ahelp[@visibility='visible']">
|
||||
<xsl:value-of select="."/>
|
||||
<xsl:text>
</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match="*"/>
|
||||
|
||||
</xsl:stylesheet>
|
||||
|
||||
|
||||
74
server/windows-office/help/index.html
Normal 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>
|
||||
1
server/windows-office/help/languages.js
Normal 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']);
|
||||
933
server/windows-office/help/main_transform.xsl
Normal file
BIN
server/windows-office/help/media/files/scalc/functions_ifs.ods
Normal file
BIN
server/windows-office/help/media/files/scalc/imtrigon.ods
Normal file
BIN
server/windows-office/help/media/files/scalc/pivot.ods
Normal file
BIN
server/windows-office/help/media/files/scalc/trigon.ods
Normal file
BIN
server/windows-office/help/media/helpimg/area1.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
server/windows-office/help/media/helpimg/area2.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
server/windows-office/help/media/helpimg/border_ca_1.png
Normal file
|
After Width: | Height: | Size: 937 B |
BIN
server/windows-office/help/media/helpimg/border_ca_2.png
Normal file
|
After Width: | Height: | Size: 858 B |
BIN
server/windows-office/help/media/helpimg/border_ca_3.png
Normal file
|
After Width: | Height: | Size: 894 B |
BIN
server/windows-office/help/media/helpimg/border_ca_4.png
Normal file
|
After Width: | Height: | Size: 787 B |
BIN
server/windows-office/help/media/helpimg/border_ca_5.png
Normal file
|
After Width: | Height: | Size: 386 B |
BIN
server/windows-office/help/media/helpimg/border_ca_6.png
Normal file
|
After Width: | Height: | Size: 727 B |
BIN
server/windows-office/help/media/helpimg/border_ca_7.png
Normal file
|
After Width: | Height: | Size: 733 B |
BIN
server/windows-office/help/media/helpimg/border_ca_8.png
Normal file
|
After Width: | Height: | Size: 776 B |
BIN
server/windows-office/help/media/helpimg/border_ca_9.png
Normal file
|
After Width: | Height: | Size: 956 B |
BIN
server/windows-office/help/media/helpimg/border_ca_gray.png
Normal file
|
After Width: | Height: | Size: 748 B |
BIN
server/windows-office/help/media/helpimg/border_ca_white.png
Normal file
|
After Width: | Height: | Size: 742 B |
BIN
server/windows-office/help/media/helpimg/border_wr_1.png
Normal file
|
After Width: | Height: | Size: 941 B |
BIN
server/windows-office/help/media/helpimg/border_wr_2.png
Normal file
|
After Width: | Height: | Size: 983 B |
BIN
server/windows-office/help/media/helpimg/border_wr_3.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |
BIN
server/windows-office/help/media/helpimg/border_wr_4.png
Normal file
|
After Width: | Height: | Size: 1.0 KiB |