mirror of
https://github.com/kuaifan/dootask.git
synced 2026-03-07 09:57:37 +00:00
升级 onlyoffice、php、fileview、drawio。(drawio 的 app.min.js、index.html 未完成)
This commit is contained in:
parent
d5d9eb93a3
commit
472ece692d
@ -79,28 +79,28 @@ class IndexController extends InvokeController
|
||||
}
|
||||
$array = [
|
||||
"office/web-apps/apps/api/documents/api.js?hash=" . Base::getVersion(),
|
||||
"office/7.2.2-56/web-apps/vendor/requirejs/require.js",
|
||||
"office/7.2.2-56/web-apps/apps/api/documents/api.js",
|
||||
"office/7.2.2-56/sdkjs/common/AllFonts.js",
|
||||
"office/7.2.2-56/web-apps/vendor/xregexp/xregexp-all-min.js",
|
||||
"office/7.2.2-56/web-apps/vendor/sockjs/sockjs.min.js",
|
||||
"office/7.2.2-56/web-apps/vendor/jszip/jszip.min.js",
|
||||
"office/7.2.2-56/web-apps/vendor/jszip-utils/jszip-utils.min.js",
|
||||
"office/7.2.2-56/sdkjs/common/libfont/wasm/fonts.js",
|
||||
"office/7.2.2-56/sdkjs/common/Charts/ChartStyles.js",
|
||||
"office/7.2.2-56/sdkjs/slide/themes//themes.js",
|
||||
"office/7.3.0-184/web-apps/vendor/requirejs/require.js",
|
||||
"office/7.3.0-184/web-apps/apps/api/documents/api.js",
|
||||
"office/7.3.0-184/sdkjs/common/AllFonts.js",
|
||||
"office/7.3.0-184/web-apps/vendor/xregexp/xregexp-all-min.js",
|
||||
"office/7.3.0-184/web-apps/vendor/sockjs/sockjs.min.js",
|
||||
"office/7.3.0-184/web-apps/vendor/jszip/jszip.min.js",
|
||||
"office/7.3.0-184/web-apps/vendor/jszip-utils/jszip-utils.min.js",
|
||||
"office/7.3.0-184/sdkjs/common/libfont/wasm/fonts.js",
|
||||
"office/7.3.0-184/sdkjs/common/Charts/ChartStyles.js",
|
||||
"office/7.3.0-184/sdkjs/slide/themes//themes.js",
|
||||
|
||||
"office/7.2.2-56/web-apps/apps/presentationeditor/main/app.js",
|
||||
"office/7.2.2-56/sdkjs/slide/sdk-all-min.js",
|
||||
"office/7.2.2-56/sdkjs/slide/sdk-all.js",
|
||||
"office/7.3.0-184/web-apps/apps/presentationeditor/main/app.js",
|
||||
"office/7.3.0-184/sdkjs/slide/sdk-all-min.js",
|
||||
"office/7.3.0-184/sdkjs/slide/sdk-all.js",
|
||||
|
||||
"office/7.2.2-56/web-apps/apps/documenteditor/main/app.js",
|
||||
"office/7.2.2-56/sdkjs/word/sdk-all-min.js",
|
||||
"office/7.2.2-56/sdkjs/word/sdk-all.js",
|
||||
"office/7.3.0-184/web-apps/apps/documenteditor/main/app.js",
|
||||
"office/7.3.0-184/sdkjs/word/sdk-all-min.js",
|
||||
"office/7.3.0-184/sdkjs/word/sdk-all.js",
|
||||
|
||||
"office/7.2.2-56/web-apps/apps/spreadsheeteditor/main/app.js",
|
||||
"office/7.2.2-56/sdkjs/cell/sdk-all-min.js",
|
||||
"office/7.2.2-56/sdkjs/cell/sdk-all.js",
|
||||
"office/7.3.0-184/web-apps/apps/spreadsheeteditor/main/app.js",
|
||||
"office/7.3.0-184/sdkjs/cell/sdk-all-min.js",
|
||||
"office/7.3.0-184/sdkjs/cell/sdk-all.js",
|
||||
];
|
||||
foreach ($array as &$item) {
|
||||
$item = url($item);
|
||||
|
||||
25
cmd
25
cmd
@ -84,6 +84,15 @@ docker_name() {
|
||||
echo `$COMPOSE ps | awk '{print $1}' | grep "\-$1\-"`
|
||||
}
|
||||
|
||||
mix_manifest() {
|
||||
local file=$1
|
||||
if [[ `uname` == 'Linux' ]]; then
|
||||
sed -i '/\"\/uploads/d' ${cur_path}/$file/mix-manifest.json
|
||||
else
|
||||
docker run -it --rm -v ${cur_path}/$file:/public alpine sh -c "sed -i '/\"\/uploads/d' /public/mix-manifest.json"
|
||||
fi
|
||||
}
|
||||
|
||||
run_compile() {
|
||||
local type=$1
|
||||
check_node
|
||||
@ -96,6 +105,7 @@ run_compile() {
|
||||
if [ "$type" = "prod" ]; then
|
||||
rm -rf "./public/js/build"
|
||||
npx mix --production
|
||||
mix_manifest "public"
|
||||
echo "$(rand_string 16)" > ./public/js/hash
|
||||
else
|
||||
npx mix watch --hot
|
||||
@ -125,6 +135,7 @@ run_electron() {
|
||||
#
|
||||
if [ "$argv" != "dev" ] && [ "$argv" != "--nobuild" ]; then
|
||||
npx mix --production -- --env --electron
|
||||
mix_manifest "electron/public"
|
||||
fi
|
||||
if [ "$argv" == "dev" ]; then
|
||||
run_exec php "php bin/run --mode=$argv"
|
||||
@ -243,15 +254,6 @@ arg_get() {
|
||||
echo $value
|
||||
}
|
||||
|
||||
is_arm() {
|
||||
local get_arch=`arch`
|
||||
if [[ $get_arch =~ "aarch" ]] || [[ $get_arch =~ "arm" ]]; then
|
||||
echo "yes"
|
||||
else
|
||||
echo "no"
|
||||
fi
|
||||
}
|
||||
|
||||
####################################################################################
|
||||
####################################################################################
|
||||
####################################################################################
|
||||
@ -264,11 +266,6 @@ fi
|
||||
if [ $# -gt 0 ]; then
|
||||
if [[ "$1" == "init" ]] || [[ "$1" == "install" ]]; then
|
||||
shift 1
|
||||
# 判断架构
|
||||
if [[ "$(is_arm)" == "yes" ]] && [[ -z "$(arg_get force)" ]]; then
|
||||
echo -e "${Error} ${RedBG}暂不支持arm架构,强制安装请使用:./cmd install --force${Font}"
|
||||
exit 1
|
||||
fi
|
||||
# 初始化文件
|
||||
if [[ -n "$(arg_get relock)" ]]; then
|
||||
rm -rf node_modules
|
||||
|
||||
@ -3,7 +3,7 @@ version: '3'
|
||||
services:
|
||||
php:
|
||||
container_name: "dootask-php-${APP_ID}"
|
||||
image: "kuaifan/php:swoole-8.0"
|
||||
image: "kuaifan/php:swoole-8.0.rc1"
|
||||
shm_size: "1024m"
|
||||
volumes:
|
||||
- ./docker/crontab/crontab.conf:/etc/supervisor/conf.d/crontab.conf
|
||||
@ -82,7 +82,7 @@ services:
|
||||
|
||||
office:
|
||||
container_name: "dootask-office-${APP_ID}"
|
||||
image: "onlyoffice/documentserver:7.2.2.56"
|
||||
image: "onlyoffice/documentserver:7.3.0.184"
|
||||
volumes:
|
||||
- ./docker/office/logs:/var/log/onlyoffice
|
||||
- ./docker/office/data:/var/www/onlyoffice/Data
|
||||
@ -103,7 +103,8 @@ services:
|
||||
|
||||
fileview:
|
||||
container_name: "dootask-fileview-${APP_ID}"
|
||||
image: "kuaifan/fileview:4.1.0-SNAPSHOT-RC18"
|
||||
image: "kuaifan/fileview:4.1.0-SNAPSHOT-RC19"
|
||||
platform: linux/amd64
|
||||
environment:
|
||||
TZ: "Asia/Shanghai"
|
||||
KK_CONTEXT_PATH: "/fileview"
|
||||
@ -117,7 +118,7 @@ services:
|
||||
|
||||
drawio-webapp:
|
||||
container_name: "dootask-drawio-webapp-${APP_ID}"
|
||||
image: "jgraph/drawio:16.6.1"
|
||||
image: "jgraph/drawio:20.8.20"
|
||||
volumes:
|
||||
- ./docker/drawio/webapp/index.html:/usr/local/tomcat/webapps/draw/index.html
|
||||
- ./docker/drawio/webapp/stencils:/usr/local/tomcat/webapps/draw/stencils
|
||||
@ -136,6 +137,7 @@ services:
|
||||
drawio-export:
|
||||
container_name: "dootask-drawio-export-${APP_ID}"
|
||||
image: "jgraph/export-server"
|
||||
platform: linux/amd64
|
||||
networks:
|
||||
extnetwork:
|
||||
ipv4_address: "${APP_IPPR}.9"
|
||||
|
||||
@ -5,11 +5,11 @@
|
||||
<title>Flowchart Maker & Online Diagram Software</title>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta name="Description" content="diagrams.net is free online diagram software for making flowcharts, process diagrams, org charts, UML, ER and network diagrams">
|
||||
<meta name="Keywords" content="diagram, online, flow chart, flowchart maker, uml, erd">
|
||||
<meta itemprop="name" content="diagrams.net - free flowchart maker and diagrams online">
|
||||
<meta itemprop="description" content="diagrams.net is a free online diagramming application and flowchart maker . You can use it to create UML, entity relationship,
|
||||
org charts, BPMN and BPM, database schema and networks. Also possible are telecommunication network, workflow, flowcharts, maps overlays and GIS, electronic
|
||||
<meta name="Description" content="draw.io is free online diagram software for making flowcharts, process diagrams, org charts, UML, ER and network diagrams">
|
||||
<meta name="Keywords" content="drawio, diagram, online, flow chart, flowchart maker, uml, erd">
|
||||
<meta itemprop="name" content="draw.io - free flowchart maker and diagrams online">
|
||||
<meta itemprop="description" content="draw.io is a free online diagramming application and flowchart maker . You can use it to create UML, entity relationship,
|
||||
org charts, BPMN and BPM, database schema and networks. Also possible are telecommunication network, workflow, flowcharts, maps overlays and GIS, electronic
|
||||
circuit and social network diagrams.">
|
||||
<meta itemprop="image" content="https://lh4.googleusercontent.com/-cLKEldMbT_E/Tx8qXDuw6eI/AAAAAAAAAAs/Ke0pnlk8Gpg/w500-h344-k/BPMN%2Bdiagram%2Brc2f.png">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
@ -17,12 +17,7 @@
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<meta name="theme-color" content="#d89000">
|
||||
<script type="text/javascript">
|
||||
window.SERVER_HOME_URL = window.location.origin + "/"
|
||||
window.EXPORT_URL = window.SERVER_HOME_URL + "drawio/export/";
|
||||
window.DRAWIO_LIGHTBOX_URL = window.SERVER_HOME_URL + "drawio/webapp";
|
||||
setInterval(function() {window.ICONSEARCH_PATH = window.SERVER_HOME_URL + "drawio/iconsearch";}, 1000)
|
||||
|
||||
/**
|
||||
/**
|
||||
* URL Parameters and protocol description are here:
|
||||
*
|
||||
* https://desk.draw.io/support/solutions/articles/16000042546-what-url-parameters-are-supported
|
||||
@ -45,27 +40,27 @@
|
||||
{
|
||||
var result = new Object();
|
||||
var params = window.location.search.slice(1).split('&');
|
||||
|
||||
|
||||
for (var i = 0; i < params.length; i++)
|
||||
{
|
||||
idx = params[i].indexOf('=');
|
||||
|
||||
var idx = params[i].indexOf('=');
|
||||
|
||||
if (idx > 0)
|
||||
{
|
||||
result[params[i].substring(0, idx)] = params[i].substring(idx + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
})();
|
||||
|
||||
|
||||
// Forces CDN caches by passing URL parameters via URL hash
|
||||
if (window.location.hash != null && window.location.hash.substring(0, 2) == '#P')
|
||||
{
|
||||
try
|
||||
{
|
||||
urlParams = JSON.parse(decodeURIComponent(window.location.hash.substring(2)));
|
||||
|
||||
|
||||
if (urlParams.hash != null)
|
||||
{
|
||||
window.location.hash = urlParams.hash;
|
||||
@ -76,7 +71,7 @@
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Global variable for desktop
|
||||
var mxIsElectron = window && window.process && window.process.type;
|
||||
|
||||
@ -86,21 +81,21 @@
|
||||
(function()
|
||||
{
|
||||
var proto = window.location.protocol;
|
||||
|
||||
|
||||
if (!mxIsElectron)
|
||||
{
|
||||
var host = window.location.host;
|
||||
|
||||
|
||||
// Redirects apex, drive and rt to www
|
||||
if (host === 'draw.io' || host === 'rt.draw.io' || host === 'drive.draw.io')
|
||||
{
|
||||
host = 'www.draw.io';
|
||||
}
|
||||
|
||||
|
||||
var href = proto + '//' + host + window.location.href.substring(
|
||||
window.location.protocol.length +
|
||||
window.location.host.length + 2);
|
||||
|
||||
|
||||
// Redirects if href changes
|
||||
if (href != window.location.href)
|
||||
{
|
||||
@ -109,7 +104,7 @@
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds meta tag to the page.
|
||||
*/
|
||||
@ -118,15 +113,15 @@
|
||||
try
|
||||
{
|
||||
var s = document.createElement('meta');
|
||||
|
||||
if (name != null)
|
||||
|
||||
if (name != null)
|
||||
{
|
||||
s.setAttribute('name', name);
|
||||
}
|
||||
|
||||
s.setAttribute('content', content);
|
||||
|
||||
if (httpEquiv != null)
|
||||
|
||||
if (httpEquiv != null)
|
||||
{
|
||||
s.setAttribute('http-equiv', httpEquiv);
|
||||
}
|
||||
@ -139,14 +134,14 @@
|
||||
// ignore
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Synchronously adds scripts to the page.
|
||||
*/
|
||||
function mxscript(src, onLoad, id, dataAppKey, noWrite)
|
||||
function mxscript(src, onLoad, id, dataAppKey, noWrite, onError)
|
||||
{
|
||||
var defer = onLoad == null && !noWrite;
|
||||
|
||||
|
||||
if ((urlParams['dev'] != '1' && typeof document.createElement('canvas').getContext === "function") ||
|
||||
onLoad != null || noWrite)
|
||||
{
|
||||
@ -159,16 +154,16 @@
|
||||
{
|
||||
s.setAttribute('id', id);
|
||||
}
|
||||
|
||||
|
||||
if (dataAppKey != null)
|
||||
{
|
||||
s.setAttribute('data-app-key', dataAppKey);
|
||||
}
|
||||
|
||||
|
||||
if (onLoad != null)
|
||||
{
|
||||
var r = false;
|
||||
|
||||
|
||||
s.onload = s.onreadystatechange = function()
|
||||
{
|
||||
if (!r && (!this.readyState || this.readyState == 'complete'))
|
||||
@ -179,8 +174,16 @@
|
||||
};
|
||||
}
|
||||
|
||||
if (onError != null)
|
||||
{
|
||||
s.onerror = function(e)
|
||||
{
|
||||
onError('Failed to load ' + src, e);
|
||||
};
|
||||
}
|
||||
|
||||
var t = document.getElementsByTagName('script')[0];
|
||||
|
||||
|
||||
if (t != null)
|
||||
{
|
||||
t.parentNode.insertBefore(s, t);
|
||||
@ -202,11 +205,11 @@
|
||||
g.type = 'text/javascript';
|
||||
g.async = true;
|
||||
g.src = src;
|
||||
|
||||
|
||||
var s = document.getElementsByTagName('script')[0];
|
||||
s.parentNode.insertBefore(g, s);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Adds meta tags with application name (depends on offline URL parameter)
|
||||
*/
|
||||
@ -218,13 +221,13 @@
|
||||
|
||||
if (mxIsElectron)
|
||||
{
|
||||
// mxmeta(null, 'default-src \'self\' \'unsafe-inline\'; connect-src \'self\' https://*.draw.io https://fonts.googleapis.com https://fonts.gstatic.com; img-src * data:; media-src *; font-src *; style-src-elem \'self\' \'unsafe-inline\' https://fonts.googleapis.com', 'Content-Security-Policy');
|
||||
mxmeta(null, 'default-src \'self\' \'unsafe-inline\'; connect-src \'self\' https://*.draw.io https://fonts.googleapis.com https://fonts.gstatic.com; img-src * data:; media-src *; font-src *; style-src-elem \'self\' \'unsafe-inline\' https://fonts.googleapis.com', 'Content-Security-Policy');
|
||||
}
|
||||
})();
|
||||
|
||||
|
||||
// Checks for local storage
|
||||
var isLocalStorage = false;
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
isLocalStorage = urlParams['local'] != '1' && typeof(localStorage) != 'undefined';
|
||||
@ -235,15 +238,15 @@
|
||||
}
|
||||
|
||||
var mxScriptsLoaded = false, mxWinLoaded = false;
|
||||
|
||||
|
||||
function checkAllLoaded()
|
||||
{
|
||||
if (mxScriptsLoaded && mxWinLoaded)
|
||||
{
|
||||
App.main();
|
||||
App.main();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var t0 = new Date();
|
||||
|
||||
// Changes paths for local development environment
|
||||
@ -251,39 +254,41 @@
|
||||
{
|
||||
// Used to request grapheditor/mxgraph sources in dev mode
|
||||
var mxDevUrl = document.location.protocol + '//devhost.jgraph.com/drawio/src/main';
|
||||
|
||||
|
||||
// Used to request draw.io sources in dev mode
|
||||
var drawDevUrl = document.location.protocol + '//devhost.jgraph.com/drawio/src/main/webapp/';
|
||||
var geBasePath = drawDevUrl + '/js/grapheditor';
|
||||
var mxBasePath = mxDevUrl + '/mxgraph';
|
||||
|
||||
|
||||
if (document.location.protocol == 'file:')
|
||||
{
|
||||
geBasePath = './js/grapheditor';
|
||||
mxBasePath = './mxgraph';
|
||||
drawDevUrl = './';
|
||||
|
||||
|
||||
// Forces includes for dev environment in node.js
|
||||
mxForceIncludes = true;
|
||||
}
|
||||
|
||||
mxForceIncludes = false;
|
||||
|
||||
mxscript(drawDevUrl + 'js/PreConfig.js');
|
||||
mxscript(drawDevUrl + 'js/diagramly/Init.js');
|
||||
mxscript(geBasePath + '/Init.js');
|
||||
mxscript(mxBasePath + '/mxClient.js');
|
||||
|
||||
|
||||
// Adds all JS code that depends on mxClient. This indirection via Devel.js is
|
||||
// required in some browsers to make sure mxClient.js (and the files that it
|
||||
// loads asynchronously) are available when the code loaded in Devel.js runs.
|
||||
mxscript(drawDevUrl + 'js/diagramly/Devel.js');
|
||||
|
||||
|
||||
// Electron
|
||||
if (mxIsElectron)
|
||||
{
|
||||
mxscript('js/diagramly/DesktopLibrary.js');
|
||||
mxscript('js/diagramly/ElectronApp.js');
|
||||
}
|
||||
|
||||
|
||||
mxscript(drawDevUrl + 'js/PostConfig.js');
|
||||
}
|
||||
else
|
||||
@ -291,18 +296,18 @@
|
||||
(function()
|
||||
{
|
||||
var hostName = window.location.hostname;
|
||||
|
||||
|
||||
// Supported domains are *.draw.io and the packaged version in Quip
|
||||
var supportedDomain = (hostName.substring(hostName.length - 8, hostName.length) === '.draw.io') ||
|
||||
(hostName.substring(hostName.length - 13, hostName.length) === '.diagrams.net');
|
||||
|
||||
|
||||
function loadAppJS()
|
||||
{
|
||||
mxscript('js/app.min.js', function()
|
||||
{
|
||||
mxScriptsLoaded = true;
|
||||
checkAllLoaded();
|
||||
|
||||
|
||||
// Electron
|
||||
if (mxIsElectron)
|
||||
{
|
||||
@ -329,7 +334,7 @@
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
if (!supportedDomain || mxIsElectron)
|
||||
{
|
||||
mxscript('js/PreConfig.js', loadAppJS);
|
||||
@ -345,7 +350,7 @@
|
||||
window.onerror = function()
|
||||
{
|
||||
var status = document.getElementById('geStatus');
|
||||
|
||||
|
||||
if (status != null)
|
||||
{
|
||||
status.innerHTML = 'Page could not be loaded. Please try refreshing.';
|
||||
@ -353,11 +358,14 @@
|
||||
};
|
||||
</script>
|
||||
<link rel="chrome-webstore-item" href="https://chrome.google.com/webstore/detail/plgmlhohecdddhbmmkncjdmlhcmaachm">
|
||||
<link rel="stylesheet" type="text/css" href="js/croppie/croppie.min.css">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="images/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="images/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="images/favicon-16x16.png">
|
||||
<link rel="mask-icon" href="images/safari-pinned-tab.svg" color="#d89000">
|
||||
<link rel="stylesheet" type="text/css" href="styles/grapheditor.css">
|
||||
<link rel="preconnect" href="https://storage.googleapis.com">
|
||||
<link rel="canonical" href="https://app.diagrams.net">
|
||||
<link rel="manifest" href="images/manifest.json">
|
||||
<link rel="shortcut icon" href="favicon.ico">
|
||||
<style type="text/css">
|
||||
body { overflow:hidden; }
|
||||
div.picker { z-index: 10007; }
|
||||
@ -366,7 +374,6 @@
|
||||
color:#606060;
|
||||
}
|
||||
.geBlock {
|
||||
display: none;
|
||||
z-index:-3;
|
||||
margin:100px;
|
||||
margin-top:40px;
|
||||
@ -380,8 +387,8 @@
|
||||
padding-top:0px;
|
||||
}
|
||||
.geEditor *:not(.geScrollable)::-webkit-scrollbar {
|
||||
width:14px;
|
||||
height:14px;
|
||||
width:10px;
|
||||
height:10px;
|
||||
}
|
||||
.geEditor ::-webkit-scrollbar-track {
|
||||
background-clip:padding-box;
|
||||
@ -411,9 +418,6 @@
|
||||
cursor:pointer;
|
||||
margin:5px;
|
||||
}
|
||||
.geDialog h2 {
|
||||
line-height: 1.2;
|
||||
}
|
||||
</style>
|
||||
<!-- Workaround for binary XHR in IE 9/10, see App.loadUrl -->
|
||||
<!--[if (IE 9)|(IE 10)]><!-->
|
||||
@ -434,7 +438,7 @@
|
||||
<div class="geBlock">
|
||||
<h1>Flowchart Maker and Online Diagram Software</h1>
|
||||
<p>
|
||||
diagrams.net (formerly draw.io) is free online diagram software. You can use it as a flowchart maker, network diagram software, to create UML online, as an ER diagram tool,
|
||||
draw.io is free online diagram software. You can use it as a flowchart maker, network diagram software, to create UML online, as an ER diagram tool,
|
||||
to design database schema, to build BPMN online, as a circuit diagram maker, and more. draw.io can import .vsdx, Gliffy™ and Lucidchart™ files .
|
||||
</p>
|
||||
<h2 id="geStatus">Loading...</h2>
|
||||
@ -447,32 +451,17 @@
|
||||
/**
|
||||
* Main
|
||||
*/
|
||||
if (navigator.userAgent != null && navigator.userAgent.toLowerCase().
|
||||
indexOf(' electron/') >= 0 && typeof process !== 'undefined' && process.versions.electron < 5)
|
||||
if (urlParams['dev'] != '1' && typeof document.createElement('canvas').getContext === "function")
|
||||
{
|
||||
// Redirects old Electron app to latest version
|
||||
var div = document.getElementById('geInfo');
|
||||
|
||||
if (div != null)
|
||||
window.addEventListener('load', function()
|
||||
{
|
||||
div.innerHTML = '<center><h2>You are using an out of date version of this app.<br>Please download the latest version ' +
|
||||
'<a href="https://github.com/jgraph/drawio-desktop/releases/latest" target="_blank">here</a>.</h2></center>';
|
||||
}
|
||||
mxWinLoaded = true;
|
||||
checkAllLoaded();
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
if (urlParams['dev'] != '1' && typeof document.createElement('canvas').getContext === "function")
|
||||
{
|
||||
window.addEventListener('load', function()
|
||||
{
|
||||
mxWinLoaded = true;
|
||||
checkAllLoaded();
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
App.main();
|
||||
}
|
||||
App.main();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
16671
docker/drawio/webapp/js/app.min.js
vendored
16671
docker/drawio/webapp/js/app.min.js
vendored
File diff suppressed because one or more lines are too long
753
docker/drawio/webapp/js/diagramly/ElectronApp.js
vendored
753
docker/drawio/webapp/js/diagramly/ElectronApp.js
vendored
@ -1,9 +1,9 @@
|
||||
window.PLUGINS_BASE_PATH = '.';
|
||||
window.TEMPLATE_PATH = 'templates';
|
||||
window.DRAW_MATH_URL = 'math';
|
||||
window.DRAW_MATH_URL = 'math/es5';
|
||||
window.DRAWIO_BASE_URL = '.'; //Prevent access to online website since it is not allowed
|
||||
FeedbackDialog.feedbackUrl = 'https://log.draw.io/email';
|
||||
|
||||
EditorUi.draftSaveDelay = 5000;
|
||||
//Disables eval for JS (uses shapes-14-6-5.min.js)
|
||||
mxStencilRegistry.allowEval = false;
|
||||
|
||||
@ -60,10 +60,18 @@ mxStencilRegistry.allowEval = false;
|
||||
if (file)
|
||||
{
|
||||
file.updateFileData();
|
||||
xml = file.getData();
|
||||
xml = editorUi.getFileData(true, null, null, null, null, false,
|
||||
null, null, null, false, true);
|
||||
title = file.title;
|
||||
}
|
||||
|
||||
var extras = {globalVars: editorUi.editor.graph.getExportVariables()};
|
||||
|
||||
if (Graph.translateDiagram)
|
||||
{
|
||||
extras.diagramLanguage = Graph.diagramLanguage;
|
||||
}
|
||||
|
||||
new mxElectronRequest('export', {
|
||||
print: true,
|
||||
format: 'pdf',
|
||||
@ -78,6 +86,7 @@ mxStencilRegistry.allowEval = false;
|
||||
sheetsAcross: sheetsAcross,
|
||||
sheetsDown: sheetsDown,
|
||||
scale: zoom,
|
||||
extras: JSON.stringify(extras),
|
||||
fileTitle: title
|
||||
}).send(function(){}, function(){});
|
||||
};
|
||||
@ -85,13 +94,15 @@ mxStencilRegistry.allowEval = false;
|
||||
var oldWindowOpen = window.open;
|
||||
window.open = async function(url)
|
||||
{
|
||||
if (url != null && url.startsWith('http'))
|
||||
// Only open a native electron window when url is empty. We use this in our code in several places.
|
||||
if (url == null)
|
||||
{
|
||||
await requestSync({action: 'openExternal', url: url});
|
||||
return oldWindowOpen(url);
|
||||
}
|
||||
else
|
||||
{
|
||||
return oldWindowOpen(url);
|
||||
// Open external will filter urls based on their protocol
|
||||
await requestSync({action: 'openExternal', url: url});
|
||||
}
|
||||
}
|
||||
|
||||
@ -99,53 +110,93 @@ mxStencilRegistry.allowEval = false;
|
||||
|
||||
App.main = async function()
|
||||
{
|
||||
// Set AutoSave delay
|
||||
var draftSaveDelay = mxSettings.getDraftSaveDelay();
|
||||
|
||||
if (draftSaveDelay != null)
|
||||
{
|
||||
EditorUi.draftSaveDelay = draftSaveDelay * 1000;
|
||||
EditorUi.enableDrafts = draftSaveDelay > 0;
|
||||
}
|
||||
|
||||
//Load desktop plugins
|
||||
var plugins = (mxSettings.settings != null) ? mxSettings.getPlugins() : null;
|
||||
App.initPluginCallback();
|
||||
|
||||
if (plugins != null && plugins.length > 0)
|
||||
{
|
||||
for (var i = 0; i < plugins.length; i++)
|
||||
// Workaround for body not defined if plugins are used in dev mode
|
||||
if (urlParams['dev'] == '1')
|
||||
{
|
||||
try
|
||||
EditorUi.debug('App.main', 'Skipped plugins', plugins);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (var i = 0; i < plugins.length; i++)
|
||||
{
|
||||
if (plugins[i].startsWith('/plugins/'))
|
||||
try
|
||||
{
|
||||
plugins[i] = '.' + plugins[i];
|
||||
if (plugins[i].indexOf('..') >= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (plugins[i].startsWith('/plugins/'))
|
||||
{
|
||||
plugins[i] = '.' + plugins[i];
|
||||
}
|
||||
else if (plugins[i].startsWith('plugins/'))
|
||||
{
|
||||
plugins[i] = './' + plugins[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
let pluginFile = await requestSync({
|
||||
action: 'getPluginFile',
|
||||
plugin: plugins[i]
|
||||
});
|
||||
|
||||
if (pluginFile != null)
|
||||
{
|
||||
plugins[i] = 'file://' + pluginFile;
|
||||
}
|
||||
else
|
||||
{
|
||||
continue; //skip not found files
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
mxscript(plugins[i]);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
else if (plugins[i].startsWith('plugins/'))
|
||||
catch (e)
|
||||
{
|
||||
plugins[i] = './' + plugins[i];
|
||||
// ignore
|
||||
}
|
||||
//Support old plugins added using file:// workaround
|
||||
else if (!plugins[i].startsWith('file://'))
|
||||
{
|
||||
let appFolder = await requestSync('getAppDataFolder');
|
||||
|
||||
let pluginsFile = await requestSync({
|
||||
action: 'checkFileExists',
|
||||
pathParts: [appFolder, '/plugins', plugins[i]]
|
||||
});
|
||||
|
||||
if (pluginsFile.exists)
|
||||
{
|
||||
plugins[i] = 'file://' + pluginsFile.path;
|
||||
}
|
||||
else
|
||||
{
|
||||
continue; //skip not found files
|
||||
}
|
||||
}
|
||||
|
||||
mxscript(plugins[i]);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Remove old relaxed CSP and add strict one
|
||||
var allMeta = document.getElementsByTagName('meta');
|
||||
|
||||
for (var i = 0; i < allMeta.length; i++)
|
||||
{
|
||||
if (allMeta[i].getAttribute('http-equiv') == 'Content-Security-Policy')
|
||||
{
|
||||
allMeta[i].parentNode.removeChild(allMeta[i]);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
mxmeta(null, 'default-src \'self\'; connect-src \'self\' https://fonts.googleapis.com https://fonts.gstatic.com; img-src * data:; media-src *; font-src *; style-src \'self\' \'unsafe-inline\' https://fonts.googleapis.com', 'Content-Security-Policy');
|
||||
|
||||
//Disable web plugins loading
|
||||
urlParams['plugins'] = '0';
|
||||
origAppMain.apply(this, arguments);
|
||||
@ -208,8 +259,8 @@ mxStencilRegistry.allowEval = false;
|
||||
// Replaces file menu to replace openFrom menu with open and rename downloadAs to export
|
||||
this.put('file', new Menu(mxUtils.bind(this, function(menu, parent)
|
||||
{
|
||||
this.addMenuItems(menu, ['import'], parent);
|
||||
this.addSubmenu('exportAs', menu, parent);
|
||||
this.addMenuItems(menu, ['import'], parent);
|
||||
this.addSubmenu('exportAs', menu, parent);
|
||||
menu.addSeparator(parent);
|
||||
this.addSubmenu('embed', menu, parent);
|
||||
menu.addSeparator(parent);
|
||||
@ -229,7 +280,7 @@ mxStencilRegistry.allowEval = false;
|
||||
}
|
||||
}
|
||||
|
||||
this.addMenuItems(menu, ['-', 'pageSetup', 'print'], parent);
|
||||
this.addMenuItems(menu, ['-', 'pageSetup', 'print'], parent);
|
||||
// LATER: Find API for application.quit
|
||||
})));
|
||||
};
|
||||
@ -267,25 +318,25 @@ mxStencilRegistry.allowEval = false;
|
||||
var editorUi = this;
|
||||
var graph = this.editor.graph;
|
||||
|
||||
window.__emt_isModified = function()
|
||||
electron.registerMsgListener('isModified', () =>
|
||||
{
|
||||
if (editorUi.getCurrentFile())
|
||||
const currentFile = editorUi.getCurrentFile();
|
||||
let reply = {isModified: false, draftPath: null};
|
||||
|
||||
if (currentFile != null)
|
||||
{
|
||||
return editorUi.getCurrentFile().isModified()
|
||||
reply.isModified = currentFile.isModified();
|
||||
reply.draftPath = EditorUi.enableDrafts && currentFile.fileObject? currentFile.fileObject.draftFileName : null;
|
||||
}
|
||||
|
||||
return false
|
||||
};
|
||||
electron.sendMessage('isModified-result', reply);
|
||||
});
|
||||
|
||||
window.__emt_removeDraft = function()
|
||||
electron.registerMsgListener('removeDraft', () =>
|
||||
{
|
||||
var currentFile = editorUi.getCurrentFile();
|
||||
|
||||
if (currentFile != null && EditorUi.enableDrafts)
|
||||
{
|
||||
currentFile.removeDraft();
|
||||
}
|
||||
};
|
||||
editorUi.getCurrentFile().removeDraft();
|
||||
electron.sendMessage('draftRemoved', {});
|
||||
});
|
||||
|
||||
// Adds support for libraries
|
||||
this.actions.addAction('newLibrary...', mxUtils.bind(this, function()
|
||||
@ -588,7 +639,19 @@ mxStencilRegistry.allowEval = false;
|
||||
|
||||
editorUi.actions.addAction('plugins...', function()
|
||||
{
|
||||
editorUi.showDialog(new PluginsDialog(editorUi, function(callback)
|
||||
var pluginsMap = {};
|
||||
//Initialize it with plugins in settings
|
||||
var plugins = (mxSettings.settings != null) ? mxSettings.getPlugins() : null;
|
||||
|
||||
if (plugins != null)
|
||||
{
|
||||
for (var i = 0; i < plugins.length; i++)
|
||||
{
|
||||
pluginsMap[plugins[i]] = true;
|
||||
}
|
||||
}
|
||||
|
||||
editorUi.showDialog(new PluginsDialog(editorUi, async function(callback)
|
||||
{
|
||||
var div = document.createElement('div');
|
||||
|
||||
@ -602,9 +665,13 @@ mxStencilRegistry.allowEval = false;
|
||||
|
||||
for (var i = 0; i < App.publicPlugin.length; i++)
|
||||
{
|
||||
var p = App.publicPlugin[i];
|
||||
|
||||
if (pluginsMap[App.pluginRegistry[p]]) continue;
|
||||
|
||||
var option = document.createElement('option');
|
||||
mxUtils.write(option, App.publicPlugin[i]);
|
||||
option.value = App.publicPlugin[i];
|
||||
mxUtils.write(option, p);
|
||||
option.value = p;
|
||||
pluginsSelect.appendChild(option);
|
||||
}
|
||||
|
||||
@ -616,63 +683,89 @@ mxStencilRegistry.allowEval = false;
|
||||
mxUtils.write(title, mxResources.get('extPlugins') + ': ');
|
||||
div.appendChild(title);
|
||||
|
||||
var extPluginsBtn = mxUtils.button(mxResources.get('selectFile') + '...', async function()
|
||||
if (await requestSync('isPluginsEnabled'))
|
||||
{
|
||||
var lastDir = localStorage.getItem('.lastPluginDir');
|
||||
var extPluginsBtn = mxUtils.button(mxResources.get('selectFile') + '...', async function()
|
||||
{
|
||||
var warningMsgs = mxResources.get('pluginWarning').split('\\n');
|
||||
var warningMsg = warningMsgs.pop(); //Last line in the message
|
||||
|
||||
var paths = await requestSync({
|
||||
action: 'showOpenDialog',
|
||||
defaultPath: lastDir || (await requestSync('getDocumentsFolder')),
|
||||
filters: [
|
||||
{ name: 'draw.io Plugins', extensions: ['js'] },
|
||||
{ name: 'All Files', extensions: ['*'] }
|
||||
],
|
||||
properties: ['openFile']
|
||||
if (!warningMsg)
|
||||
{
|
||||
warningMsg = warningMsgs.pop();
|
||||
}
|
||||
|
||||
if (!confirm(warningMsg))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var lastDir = localStorage.getItem('.lastPluginDir');
|
||||
|
||||
var paths = await requestSync({
|
||||
action: 'showOpenDialog',
|
||||
defaultPath: lastDir || (await requestSync('getDocumentsFolder')),
|
||||
filters: [
|
||||
{ name: 'draw.io Plugins', extensions: ['js'] },
|
||||
{ name: 'All Files', extensions: ['*'] }
|
||||
],
|
||||
properties: ['openFile']
|
||||
});
|
||||
|
||||
if (paths !== undefined && paths[0] != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
let ret = await requestSync({
|
||||
action: 'installPlugin',
|
||||
filePath: paths[0]
|
||||
});
|
||||
|
||||
localStorage.setItem('.lastPluginDir', ret.selDir);
|
||||
callback(ret.pluginName);
|
||||
editorUi.hideDialog();
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
if (e.message == 'fileExists')
|
||||
{
|
||||
alert(mxResources.get('fileExists'));
|
||||
}
|
||||
else
|
||||
{
|
||||
alert('Adding plugin failed.');
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (paths !== undefined && paths[0] != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
let ret = await requestSync({
|
||||
action: 'installPlugin',
|
||||
filePath: paths[0]
|
||||
});
|
||||
|
||||
localStorage.setItem('.lastPluginDir', ret.selDir);
|
||||
callback(ret.pluginName);
|
||||
editorUi.hideDialog();
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
if (e.message == 'fileExists')
|
||||
{
|
||||
alert(mxResources.get('fileExists'));
|
||||
}
|
||||
else
|
||||
{
|
||||
alert('Adding plugin failed.');
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
extPluginsBtn.className = 'geBtn';
|
||||
div.appendChild(extPluginsBtn);
|
||||
extPluginsBtn.className = 'geBtn';
|
||||
div.appendChild(extPluginsBtn);
|
||||
}
|
||||
else
|
||||
{
|
||||
title = document.createElement('span');
|
||||
mxUtils.write(title, mxResources.get('pluginsDisabled'));
|
||||
div.appendChild(title);
|
||||
}
|
||||
|
||||
var dlg = new CustomDialog(editorUi, div, mxUtils.bind(this, function()
|
||||
{
|
||||
callback(App.pluginRegistry[pluginsSelect.value]);
|
||||
var newP = App.pluginRegistry[pluginsSelect.value];
|
||||
pluginsMap[newP] = true;
|
||||
callback(newP);
|
||||
}));
|
||||
editorUi.showDialog(dlg.container, 300, 125, true, true);
|
||||
},
|
||||
async function(plugin)
|
||||
{
|
||||
delete pluginsMap[plugin];
|
||||
|
||||
await requestSync({
|
||||
action: 'uninstallPlugin',
|
||||
plugin: plugin
|
||||
});
|
||||
}).container, 360, 225, true, false);
|
||||
}, true).container, 360, 225, true, false);
|
||||
});
|
||||
}
|
||||
|
||||
@ -829,25 +922,24 @@ mxStencilRegistry.allowEval = false;
|
||||
|
||||
if (file.fileObject != null)
|
||||
{
|
||||
var title = file.fileObject.path;
|
||||
|
||||
if (title.length > 100)
|
||||
{
|
||||
title = '...' + title.substr(title.length - 97);
|
||||
}
|
||||
|
||||
this.addRecent({id: file.fileObject.path, title: title});
|
||||
file.addToRecent();
|
||||
|
||||
await requestSync({
|
||||
action: 'watchFile',
|
||||
path: file.fileObject.path,
|
||||
listener: mxUtils.bind(this, function(curr, prev)
|
||||
{
|
||||
EditorUi.debug('EditorUi.watchFile', [this],
|
||||
'file', [file], 'stat', [file.stat],
|
||||
'curr', [curr], 'prev', [prev],
|
||||
'inConflictState', file.inConflictState,
|
||||
'unwatchedSaves', file.unwatchedSaves);
|
||||
|
||||
//File is changed (not just accessed) && File is not already in a conflict state
|
||||
if (curr.mtimeMs != prev.mtimeMs && !file.inConflictState)
|
||||
{
|
||||
//Ignore our own changes
|
||||
if (file.unwatchedSaves || (file.state != null && file.stat.mtimeMs == curr.mtimeMs))
|
||||
if (file.unwatchedSaves || (file.stat != null && file.stat.mtimeMs == curr.mtimeMs))
|
||||
{
|
||||
file.unwatchedSaves = false;
|
||||
return;
|
||||
@ -855,26 +947,18 @@ mxStencilRegistry.allowEval = false;
|
||||
|
||||
file.inConflictState = true;
|
||||
|
||||
this.showError(mxResources.get('externalChanges'),
|
||||
mxResources.get('fileChangedSyncDialog'),
|
||||
mxResources.get('synchronize'), mxUtils.bind(this, function()
|
||||
file.addConflictStatus(null, mxUtils.bind(this, function()
|
||||
{
|
||||
file.ui.editor.setStatus(mxUtils.htmlEntities(
|
||||
mxResources.get('updatingDocument')));
|
||||
file.synchronizeFile(mxUtils.bind(this, function()
|
||||
{
|
||||
if (this.spinner.spin(document.body, mxResources.get('updatingDocument')))
|
||||
{
|
||||
file.synchronizeFile(mxUtils.bind(this, function()
|
||||
{
|
||||
this.spinner.stop();
|
||||
}), mxUtils.bind(this, function(err)
|
||||
{
|
||||
file.handleFileError(err, true);
|
||||
}));
|
||||
}
|
||||
}), null, null, null,
|
||||
mxResources.get('cancel'), mxUtils.bind(this, function()
|
||||
file.handleFileSuccess(false);
|
||||
}), mxUtils.bind(this, function(err)
|
||||
{
|
||||
this.hideDialog();
|
||||
file.handleFileError(null, false);
|
||||
}), 340, 150);
|
||||
file.handleFileError(err, true);
|
||||
}));
|
||||
}));
|
||||
}
|
||||
})
|
||||
});
|
||||
@ -964,6 +1048,21 @@ mxStencilRegistry.allowEval = false;
|
||||
}
|
||||
};
|
||||
|
||||
EditorUi.prototype.normalizeFilename = function(title, defaultExtension)
|
||||
{
|
||||
var tokens = title.split('.');
|
||||
var ext = (tokens.length > 1) ? tokens[tokens.length - 1] : '';
|
||||
defaultExtension = (defaultExtension != null) ? defaultExtension : 'drawio';
|
||||
|
||||
if (tokens.length == 1 || mxUtils.indexOf(['xml',
|
||||
'html', 'drawio', 'png', 'svg'], ext) < 0)
|
||||
{
|
||||
tokens.push(defaultExtension);
|
||||
}
|
||||
|
||||
return tokens.join('.');
|
||||
};
|
||||
|
||||
//In order not to repeat the logic for opening a file, we collect files information here and use them in openLocalFile
|
||||
var origOpenFiles = EditorUi.prototype.openFiles;
|
||||
var openFilesMap = {};
|
||||
@ -1160,7 +1259,7 @@ mxStencilRegistry.allowEval = false;
|
||||
{
|
||||
this.ui.readGraphFile(mxUtils.bind(this, function(fileEntry, data, stat, name, isModified)
|
||||
{
|
||||
var file = new LocalFile(this, data, '');
|
||||
var file = new LocalFile(this.ui, data, '');
|
||||
file.stat = stat;
|
||||
file.setModified(isModified? true : false);
|
||||
success(file);
|
||||
@ -1276,6 +1375,12 @@ mxStencilRegistry.allowEval = false;
|
||||
|
||||
LocalFile.prototype.save = function(revision, success, error, unloading, overwrite)
|
||||
{
|
||||
if (!this.isEditable())
|
||||
{
|
||||
this.saveAs(this.title, success, error);
|
||||
return;
|
||||
}
|
||||
|
||||
DrawioFile.prototype.save.apply(this, [revision, mxUtils.bind(this, function()
|
||||
{
|
||||
this.saveFile(revision, mxUtils.bind(this, function()
|
||||
@ -1307,23 +1412,6 @@ mxStencilRegistry.allowEval = false;
|
||||
this.editable = editable;
|
||||
};
|
||||
|
||||
LocalFile.prototype.getFilename = function()
|
||||
{
|
||||
var filename = this.title;
|
||||
|
||||
// Adds default extension
|
||||
if (filename.length > 0 && (!/(\.xml)$/i.test(filename) && !/(\.html)$/i.test(filename) &&
|
||||
!/(\.svg)$/i.test(filename) && !/(\.png)$/i.test(filename) && !/(\.drawio)$/i.test(filename)))
|
||||
{
|
||||
filename += '.drawio';
|
||||
}
|
||||
|
||||
return filename;
|
||||
};
|
||||
|
||||
// Prototype inheritance needs new functions to be added to subclasses
|
||||
LocalLibrary.prototype.getFilename = LocalFile.prototype.getFilename;
|
||||
|
||||
LocalFile.prototype.saveFile = async function(revision, success, error, unloading, overwrite)
|
||||
{
|
||||
//Safeguard in case saveFile is called from online code in the future
|
||||
@ -1420,83 +1508,114 @@ mxStencilRegistry.allowEval = false;
|
||||
}
|
||||
});
|
||||
|
||||
if (this.fileObject == null)
|
||||
try
|
||||
{
|
||||
var lastDir = localStorage.getItem('.lastSaveDir');
|
||||
var name = this.getFilename();
|
||||
var ext = null;
|
||||
|
||||
if (name != null)
|
||||
if (this.fileObject == null)
|
||||
{
|
||||
var idx = name.lastIndexOf('.');
|
||||
var lastDir = localStorage.getItem('.lastSaveDir');
|
||||
var name = this.ui.normalizeFilename(this.getTitle(),
|
||||
this.constructor == LocalLibrary ? 'xml' : null);
|
||||
var ext = null;
|
||||
|
||||
if (idx > 0)
|
||||
if (name != null)
|
||||
{
|
||||
ext = name.substring(idx + 1);
|
||||
name = name.substring(0, idx);
|
||||
var idx = name.lastIndexOf('.');
|
||||
|
||||
if (idx > 0)
|
||||
{
|
||||
ext = name.substring(idx + 1);
|
||||
}
|
||||
}
|
||||
|
||||
var path = await requestSync({
|
||||
action: 'showSaveDialog',
|
||||
defaultPath: (lastDir || (await requestSync('getDocumentsFolder'))) + '/' + name,
|
||||
filters: this.ui.createFileSystemFilters(ext)
|
||||
});
|
||||
|
||||
if (path != null)
|
||||
{
|
||||
localStorage.setItem('.lastSaveDir', await requestSync({action: 'dirname', path: path}));
|
||||
this.fileObject = new Object();
|
||||
this.fileObject.path = path;
|
||||
this.fileObject.name = path.replace(/^.*[\\\/]/, '');
|
||||
this.fileObject.type = 'utf-8';
|
||||
this.title = this.fileObject.name;
|
||||
this.addToRecent();
|
||||
fn();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.ui.spinner.stop();
|
||||
}
|
||||
}
|
||||
|
||||
var path = await requestSync({
|
||||
action: 'showSaveDialog',
|
||||
defaultPath: (lastDir || (await requestSync('getDocumentsFolder'))) + '/' + name,
|
||||
filters: this.ui.createFileSystemFilters(ext)
|
||||
});
|
||||
|
||||
if (path != null)
|
||||
{
|
||||
localStorage.setItem('.lastSaveDir', await requestSync({action: 'dirname', path: path}));
|
||||
this.fileObject = new Object();
|
||||
this.fileObject.path = path;
|
||||
this.fileObject.name = path.replace(/^.*[\\\/]/, '');
|
||||
this.fileObject.type = 'utf-8';
|
||||
else
|
||||
{
|
||||
fn();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.ui.spinner.stop();
|
||||
}
|
||||
}
|
||||
else
|
||||
catch (e)
|
||||
{
|
||||
fn();
|
||||
error(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
LocalFile.prototype.saveAs = async function(title, success, error)
|
||||
LocalFile.prototype.addToRecent = function()
|
||||
{
|
||||
var lastDir = localStorage.getItem('.lastSaveDir');
|
||||
var name = this.getFilename();
|
||||
var ext = null;
|
||||
if (this.fileObject == null) return;
|
||||
|
||||
if (name == '' && this.fileObject != null && this.fileObject.name != null)
|
||||
var title = this.fileObject.path;
|
||||
|
||||
if (title.length > 100)
|
||||
{
|
||||
name = this.fileObject.name;
|
||||
var idx = name.lastIndexOf('.');
|
||||
|
||||
if (idx > 0)
|
||||
{
|
||||
ext = name.substring(idx + 1);
|
||||
name = name.substring(0, idx);
|
||||
}
|
||||
title = '...' + title.substr(title.length - 97);
|
||||
}
|
||||
|
||||
var path = await requestSync({
|
||||
action: 'showSaveDialog',
|
||||
defaultPath: (lastDir || (await requestSync('getDocumentsFolder'))) + '/' + name,
|
||||
filters: this.ui.createFileSystemFilters(ext)
|
||||
});
|
||||
this.ui.addRecent({id: this.fileObject.path, title: title});
|
||||
};
|
||||
|
||||
if (path != null)
|
||||
{
|
||||
localStorage.setItem('.lastSaveDir', await requestSync({action: 'dirname', path: path}));
|
||||
this.fileObject = new Object();
|
||||
this.fileObject.path = path;
|
||||
this.fileObject.name = path.replace(/^.*[\\\/]/, '');
|
||||
this.fileObject.type = 'utf-8';
|
||||
this.setEditable(true); //In case original file is read only
|
||||
this.save(false, success, error, null, true);
|
||||
LocalFile.prototype.saveAs = async function(title, success, error)
|
||||
{
|
||||
try
|
||||
{
|
||||
var lastDir = localStorage.getItem('.lastSaveDir');
|
||||
var name = this.ui.normalizeFilename(this.getTitle(),
|
||||
this.constructor == LocalLibrary ? 'xml' : null);
|
||||
var ext = null;
|
||||
|
||||
if (name != null)
|
||||
{
|
||||
var idx = name.lastIndexOf('.');
|
||||
|
||||
if (idx > 0)
|
||||
{
|
||||
ext = name.substring(idx + 1);
|
||||
}
|
||||
}
|
||||
|
||||
var path = await requestSync({
|
||||
action: 'showSaveDialog',
|
||||
defaultPath: (lastDir || (await requestSync('getDocumentsFolder'))) + '/' + name,
|
||||
filters: this.ui.createFileSystemFilters(ext)
|
||||
});
|
||||
|
||||
if (path != null)
|
||||
{
|
||||
localStorage.setItem('.lastSaveDir', await requestSync({action: 'dirname', path: path}));
|
||||
this.fileObject = new Object();
|
||||
this.fileObject.path = path;
|
||||
this.fileObject.name = path.replace(/^.*[\\\/]/, '');
|
||||
this.fileObject.type = 'utf-8';
|
||||
this.title = this.fileObject.name;
|
||||
this.addToRecent();
|
||||
this.setEditable(true); //In case original file is read only
|
||||
this.save(false, success, error, null, true);
|
||||
}
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
error(e);
|
||||
}
|
||||
};
|
||||
|
||||
@ -1543,6 +1662,11 @@ mxStencilRegistry.allowEval = false;
|
||||
}
|
||||
};
|
||||
|
||||
LocalLibrary.prototype.addToRecent = function()
|
||||
{
|
||||
// do nothing
|
||||
};
|
||||
|
||||
/**
|
||||
* Loads the given file handle as a local file.
|
||||
*/
|
||||
@ -1710,155 +1834,16 @@ mxStencilRegistry.allowEval = false;
|
||||
electron.sendMessage('toggleSpellCheck');
|
||||
}
|
||||
|
||||
var origUpdateHeader = App.prototype.updateHeader;
|
||||
|
||||
App.prototype.updateHeader = function()
|
||||
App.prototype.toggleStoreBkp = function()
|
||||
{
|
||||
origUpdateHeader.apply(this, arguments);
|
||||
|
||||
if (urlParams['winCtrls'] != '1')
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
document.querySelectorAll('.geStatus').forEach(i => i.style.webkitAppRegion = 'no-drag');
|
||||
var menubarContainer = document.querySelector('.geMenubarContainer');
|
||||
|
||||
if (urlParams['sketch'] == '1')
|
||||
{
|
||||
menubarContainer = this.titlebar;
|
||||
}
|
||||
|
||||
menubarContainer.style.webkitAppRegion = 'drag';
|
||||
|
||||
//Add window control buttons
|
||||
this.windowControls = document.createElement('div');
|
||||
this.windowControls.id = 'geWindow-controls';
|
||||
this.windowControls.innerHTML =
|
||||
'<div class="button" id="min-button">' +
|
||||
' <svg width="10" height="1" viewBox="0 0 11 1">' +
|
||||
' <path d="m11 0v1h-11v-1z" stroke-width=".26208"/>' +
|
||||
' </svg>' +
|
||||
'</div>' +
|
||||
'<div class="button" id="max-button">' +
|
||||
' <svg width="10" height="10" viewBox="0 0 10 10">' +
|
||||
' <path d="m10-1.6667e-6v10h-10v-10zm-1.001 1.001h-7.998v7.998h7.998z" stroke-width=".25" />' +
|
||||
' </svg>' +
|
||||
'</div>' +
|
||||
'<div class="button" id="restore-button">' +
|
||||
' <svg width="10" height="10" viewBox="0 0 11 11">' +
|
||||
' <path' +
|
||||
' d="m11 8.7978h-2.2021v2.2022h-8.7979v-8.7978h2.2021v-2.2022h8.7979zm-3.2979-5.5h-6.6012v6.6011h6.6012zm2.1968-2.1968h-6.6012v1.1011h5.5v5.5h1.1011z"' +
|
||||
' stroke-width=".275" />' +
|
||||
' </svg>' +
|
||||
'</div>' +
|
||||
'<div class="button" id="close-button">' +
|
||||
' <svg width="10" height="10" viewBox="0 0 12 12">' +
|
||||
' <path' +
|
||||
' d="m6.8496 6 5.1504 5.1504-0.84961 0.84961-5.1504-5.1504-5.1504 5.1504-0.84961-0.84961 5.1504-5.1504-5.1504-5.1504 0.84961-0.84961 5.1504 5.1504 5.1504-5.1504 0.84961 0.84961z"' +
|
||||
' stroke-width=".3" />' +
|
||||
' </svg>' +
|
||||
'</div>';
|
||||
|
||||
if (uiTheme == 'atlas')
|
||||
{
|
||||
this.windowControls.style.top = '9px';
|
||||
}
|
||||
else if (urlParams['sketch'] == '1')
|
||||
{
|
||||
this.windowControls.style.top = '-1px';
|
||||
}
|
||||
|
||||
menubarContainer.appendChild(this.windowControls);
|
||||
|
||||
var handleDarkModeChange = mxUtils.bind(this, function ()
|
||||
{
|
||||
if (uiTheme == 'atlas' || Editor.isDarkMode())
|
||||
{
|
||||
this.windowControls.style.fill = 'white';
|
||||
document.querySelectorAll('#geWindow-controls .button').forEach(b => b.className = 'button dark');
|
||||
}
|
||||
else
|
||||
{
|
||||
this.windowControls.style.fill = '#999';
|
||||
document.querySelectorAll('#geWindow-controls .button').forEach(b => b.className = 'button white');
|
||||
}
|
||||
});
|
||||
|
||||
handleDarkModeChange();
|
||||
this.addListener('darkModeChanged', handleDarkModeChange);
|
||||
|
||||
if (this.appIcon != null)
|
||||
{
|
||||
this.appIcon.style.webkitAppRegion = 'no-drag';
|
||||
}
|
||||
|
||||
if (this.menubar != null)
|
||||
{
|
||||
this.menubar.container.style.webkitAppRegion = 'no-drag';
|
||||
|
||||
if (uiTheme == 'atlas')
|
||||
{
|
||||
this.menubar.container.style.width = 'fit-content';
|
||||
}
|
||||
|
||||
if (this.menubar.langIcon != null)
|
||||
{
|
||||
this.menubar.langIcon.parentNode.removeChild(this.menubar.langIcon);
|
||||
menubarContainer.appendChild(this.menubar.langIcon);
|
||||
}
|
||||
}
|
||||
|
||||
window.onbeforeunload = async (event) => {
|
||||
/* If window is reloaded, remove win event listeners
|
||||
(DOM element listeners get auto garbage collected but not
|
||||
Electron win listeners as the win is not dereferenced unless closed) */
|
||||
await requestSync({action: 'windowAction', method: 'removeAllListeners'});
|
||||
}
|
||||
|
||||
// Make minimise/maximise/restore/close buttons work when they are clicked
|
||||
document.getElementById('min-button').addEventListener("click", async event => {
|
||||
await requestSync({action: 'windowAction', method: 'minimize'});
|
||||
});
|
||||
|
||||
document.getElementById('max-button').addEventListener("click", async event => {
|
||||
await requestSync({action: 'windowAction', method: 'maximize'});
|
||||
});
|
||||
|
||||
document.getElementById('restore-button').addEventListener("click", async event => {
|
||||
await requestSync({action: 'windowAction', method: 'unmaximize'});
|
||||
});
|
||||
|
||||
document.getElementById('close-button').addEventListener("click", async event => {
|
||||
await requestSync({action: 'windowAction', method: 'close'});
|
||||
});
|
||||
|
||||
// Toggle maximise/restore buttons when maximisation/unmaximisation occurs
|
||||
toggleMaxRestoreButtons();
|
||||
electron.registerMsgListener('maximize', toggleMaxRestoreButtons)
|
||||
electron.registerMsgListener('unmaximize', toggleMaxRestoreButtons)
|
||||
electron.registerMsgListener('resize', toggleMaxRestoreButtons)
|
||||
|
||||
async function toggleMaxRestoreButtons() {
|
||||
if (await requestSync({action: 'windowAction', method: 'isMaximized'})) {
|
||||
document.body.classList.add('geMaximized');
|
||||
} else {
|
||||
document.body.classList.remove('geMaximized');
|
||||
}
|
||||
}
|
||||
electron.sendMessage('toggleStoreBkp');
|
||||
}
|
||||
|
||||
var origUpdateDocumentTitle = App.prototype.updateDocumentTitle;
|
||||
|
||||
App.prototype.updateDocumentTitle = function()
|
||||
App.prototype.openDevTools = function()
|
||||
{
|
||||
origUpdateDocumentTitle.apply(this, arguments);
|
||||
electron.sendMessage('openDevTools');
|
||||
}
|
||||
|
||||
if (this.titlebar != null && this.titlebar.firstChild != null)
|
||||
{
|
||||
this.titlebar.firstChild.innerHTML = mxUtils.htmlEntities(document.title);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Copies the given cells and XML to the clipboard as an embedded image.
|
||||
*/
|
||||
@ -1961,80 +1946,13 @@ mxStencilRegistry.allowEval = false;
|
||||
}
|
||||
|
||||
//Direct export to pdf
|
||||
EditorUi.prototype.createDownloadRequest = function(filename, format, ignoreSelection, base64, transparent,
|
||||
currentPage, scale, border, grid, includeXml)
|
||||
EditorUi.prototype.createDownloadRequest = function(filename, format, ignoreSelection,
|
||||
base64, transparent, currentPage, scale, border, grid, includeXml, pageRange, w, h)
|
||||
{
|
||||
var graph = this.editor.graph;
|
||||
var bounds = graph.getGraphBounds();
|
||||
var params = this.downloadRequestBuilder(filename, format, ignoreSelection,
|
||||
base64, transparent, currentPage, scale, border, grid, includeXml, pageRange, w, h);
|
||||
|
||||
// Exports only current page for images that does not contain file data, but for
|
||||
// the other formats with XML included or pdf with all pages, we need to send the complete data and use
|
||||
// the from/to URL parameters to specify the page to be exported.
|
||||
var data = this.getFileData(true, null, null, null, ignoreSelection, currentPage == false? false : format != 'xmlpng');
|
||||
var range = null;
|
||||
var allPages = null;
|
||||
|
||||
var embed = (includeXml) ? '1' : '0';
|
||||
|
||||
if (format == 'pdf' && currentPage == false)
|
||||
{
|
||||
allPages = '1';
|
||||
}
|
||||
|
||||
if (format == 'xmlpng')
|
||||
{
|
||||
embed = '1';
|
||||
format = 'png';
|
||||
|
||||
// Finds the current page number
|
||||
if (this.pages != null && this.currentPage != null)
|
||||
{
|
||||
for (var i = 0; i < this.pages.length; i++)
|
||||
{
|
||||
if (this.pages[i] == this.currentPage)
|
||||
{
|
||||
range = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var bg = graph.background;
|
||||
|
||||
if (format == 'png' && transparent)
|
||||
{
|
||||
bg = mxConstants.NONE;
|
||||
}
|
||||
else if (!transparent && (bg == null || bg == mxConstants.NONE))
|
||||
{
|
||||
bg = '#ffffff';
|
||||
}
|
||||
|
||||
var extras = {globalVars: graph.getExportVariables()};
|
||||
|
||||
if (grid)
|
||||
{
|
||||
extras.grid = {
|
||||
size: graph.gridSize,
|
||||
steps: graph.view.gridSteps,
|
||||
color: graph.view.gridColor
|
||||
};
|
||||
}
|
||||
|
||||
return new mxElectronRequest('export', {
|
||||
format: format,
|
||||
xml: data,
|
||||
from: range,
|
||||
bg: (bg != null) ? bg : mxConstants.NONE,
|
||||
filename: (filename != null) ? filename : null,
|
||||
allPages: allPages,
|
||||
base64: base64,
|
||||
embedXml: embed,
|
||||
extras: encodeURIComponent(JSON.stringify(extras)),
|
||||
scale: scale,
|
||||
border: border
|
||||
});
|
||||
return new mxElectronRequest('export', params);
|
||||
};
|
||||
|
||||
var origSetAutosave = Editor.prototype.setAutosave;
|
||||
@ -2082,6 +2000,11 @@ mxStencilRegistry.allowEval = false;
|
||||
{
|
||||
var extras = {globalVars: graph.getExportVariables()};
|
||||
|
||||
if (Graph.translateDiagram)
|
||||
{
|
||||
extras.diagramLanguage = Graph.diagramLanguage;
|
||||
}
|
||||
|
||||
editorUi.saveRequest(name, format,
|
||||
function(newTitle, base64)
|
||||
{
|
||||
|
||||
31
docker/office/resources/api/documents/api.js
vendored
31
docker/office/resources/api/documents/api.js
vendored
@ -1,9 +1,9 @@
|
||||
/*!
|
||||
* Copyright (c) Ascensio System SIA 2022. All rights reserved
|
||||
* Copyright (c) Ascensio System SIA 2023. All rights reserved
|
||||
*
|
||||
* http://www.onlyoffice.com
|
||||
*
|
||||
* Version: 7.2.2 (build:56)
|
||||
* Version: 7.3.0 (build:184)
|
||||
*/
|
||||
|
||||
;(function(window) {
|
||||
@ -66,6 +66,7 @@
|
||||
options: <advanced options>,
|
||||
key: 'key',
|
||||
vkey: 'vkey',
|
||||
referenceData: 'data for external paste',
|
||||
info: {
|
||||
owner: 'owner name',
|
||||
folder: 'path to document',
|
||||
@ -217,9 +218,12 @@
|
||||
},
|
||||
leftMenu: {
|
||||
navigation: false/true,
|
||||
spellcheck: false/true // spellcheck button in sse
|
||||
spellcheck: false/true // spellcheck button in sse,
|
||||
mode: false/true // init value for left panel, true - is visible, false - is hidden, used for option "Left panel" on the View Tab
|
||||
} / false / true, // use instead of customization.leftMenu
|
||||
rightMenu: false/true, // use instead of customization.rightMenu
|
||||
rightMenu: {
|
||||
mode: false/true // init value for right panel, true - is visible, false - is hidden, used for option "Right panel" on the View Tab
|
||||
} / false/true, // use instead of customization.rightMenu
|
||||
statusBar: {
|
||||
textLang: false/true // text language button in de/pe
|
||||
docLang: false/true // document language button in de/pe
|
||||
@ -232,6 +236,9 @@
|
||||
change: false/true // hide/show feature in de/pe/sse
|
||||
} / false / true // if false/true - use as init value in de/pe. use instead of customization.spellcheck parameter
|
||||
},
|
||||
font: {
|
||||
name: "Arial",
|
||||
},
|
||||
chat: true,
|
||||
comments: true,
|
||||
zoom: 100,
|
||||
@ -307,6 +314,7 @@
|
||||
'onRequestCompareFile': <request file to compare>,// must call setRevisedFile method
|
||||
'onRequestSharingSettings': <request sharing settings>,// must call setSharingSettings method
|
||||
'onRequestCreateNew': <try to create document>,
|
||||
'onRequestReferenceData': <try to refresh external data>,
|
||||
}
|
||||
}
|
||||
|
||||
@ -370,6 +378,7 @@
|
||||
_config.editorConfig.canRequestCompareFile = _config.events && !!_config.events.onRequestCompareFile;
|
||||
_config.editorConfig.canRequestSharingSettings = _config.events && !!_config.events.onRequestSharingSettings;
|
||||
_config.editorConfig.canRequestCreateNew = _config.events && !!_config.events.onRequestCreateNew;
|
||||
_config.editorConfig.canRequestReferenceData = _config.events && !!_config.events.onRequestReferenceData;
|
||||
_config.frameEditorId = placeholderId;
|
||||
_config.parentOrigin = window.location.origin;
|
||||
|
||||
@ -783,6 +792,13 @@ b.prototype.lockWithTimeout=function(a){this.lockCounter++;var c=this;setTimeout
|
||||
});
|
||||
};
|
||||
|
||||
var _setReferenceData = function(data) {
|
||||
_sendCommand({
|
||||
command: 'setReferenceData',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
var _serviceCommand = function(command, data) {
|
||||
_sendCommand({
|
||||
command: 'internalCommand',
|
||||
@ -820,7 +836,8 @@ b.prototype.lockWithTimeout=function(a){this.lockCounter++;var c=this;setTimeout
|
||||
setFavorite : _setFavorite,
|
||||
requestClose : _requestClose,
|
||||
grabFocus : _grabFocus,
|
||||
blurFocus : _blurFocus
|
||||
blurFocus : _blurFocus,
|
||||
setReferenceData : _setReferenceData
|
||||
}
|
||||
};
|
||||
|
||||
@ -840,7 +857,7 @@ b.prototype.lockWithTimeout=function(a){this.lockCounter++;var c=this;setTimeout
|
||||
};
|
||||
|
||||
DocsAPI.DocEditor.version = function() {
|
||||
return '7.2.2';
|
||||
return '7.3.0';
|
||||
};
|
||||
|
||||
MessageDispatcher = function(fn, scope) {
|
||||
@ -978,7 +995,7 @@ b.prototype.lockWithTimeout=function(a){this.lockCounter++;var c=this;setTimeout
|
||||
}
|
||||
|
||||
function getAppParameters(config) {
|
||||
var params = "?_dc=7.2.2-56";
|
||||
var params = "?_dc=7.3.0-184";
|
||||
|
||||
if (config.editorConfig && config.editorConfig.lang)
|
||||
params += "&lang=" + config.editorConfig.lang;
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
||||
Subproject commit d1e210ce4ba5cced90a56866036e888795792d59
|
||||
Subproject commit 1a858166fb4f1330cf23e58941e3fbec1dcd16f8
|
||||
Loading…
x
Reference in New Issue
Block a user