Import OnlyOffice code from the 'onlyoffice' branch and sframe it
@ -0,0 +1,117 @@
|
|||||||
|
|
||||||
|
const sockjs = require('sockjs');
|
||||||
|
const co = require('co');
|
||||||
|
try {
|
||||||
|
config = require('./config');
|
||||||
|
} catch (e) {
|
||||||
|
console.log("You can customize the configuration by copying config.example.js to config.js");
|
||||||
|
config = require('./config.example');
|
||||||
|
}
|
||||||
|
var origin = config.httpUnsafeOrigin || 'http://localhost:3000/';
|
||||||
|
|
||||||
|
exports.install = function(server, callbackFunction) {
|
||||||
|
var sockjs_opts = {sockjs_url: ""},
|
||||||
|
sockjs_echo = sockjs.createServer(sockjs_opts),
|
||||||
|
urlParse = new RegExp("^/onlyoffice/doc/([0-9-.a-zA-Z_=]*)/c.+", 'i');
|
||||||
|
|
||||||
|
console.log("Start ooserver");
|
||||||
|
console.log("Port " + sockjs_echo.port);
|
||||||
|
|
||||||
|
function getBaseUrl(protocol, hostHeader, forwardedProtoHeader, forwardedHostHeader) {
|
||||||
|
var url = '';
|
||||||
|
if (forwardedProtoHeader) {
|
||||||
|
url += forwardedProtoHeader;
|
||||||
|
} else if (protocol) {
|
||||||
|
url += protocol;
|
||||||
|
} else {
|
||||||
|
url += 'http';
|
||||||
|
}
|
||||||
|
url += '://';
|
||||||
|
if (forwardedHostHeader) {
|
||||||
|
url += forwardedHostHeader;
|
||||||
|
} else if (hostHeader) {
|
||||||
|
url += hostHeader;
|
||||||
|
} else {
|
||||||
|
url += origin.slice(0, -1);
|
||||||
|
}
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
function getBaseUrlByConnection(conn) {
|
||||||
|
return getBaseUrl('', conn.headers['host'], conn.headers['x-forwarded-proto'], conn.headers['x-forwarded-host']);
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendData(conn, data) {
|
||||||
|
conn.write(JSON.stringify(data));
|
||||||
|
}
|
||||||
|
function sendDataWarning(conn, msg) {
|
||||||
|
sendData(conn, {type: "warning", message: msg});
|
||||||
|
}
|
||||||
|
function sendDataMessage(conn, msg) {
|
||||||
|
sendData(conn, {type: "message", messages: msg});
|
||||||
|
}
|
||||||
|
|
||||||
|
sockjs_echo.on('connection', function(conn) {
|
||||||
|
console.log("ooserver in connection");
|
||||||
|
if (null == conn) {
|
||||||
|
console.log("null == conn");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
conn.baseUrl = getBaseUrlByConnection(conn);
|
||||||
|
console.log("BaseUrl: " + conn.baseUrl);
|
||||||
|
conn.sessionIsSendWarning = false;
|
||||||
|
conn.sessionTimeConnect = conn.sessionTimeLastAction = new Date().getTime();
|
||||||
|
console.log("ooserver setting handlers");
|
||||||
|
conn.on('data', function(message) {
|
||||||
|
console.log("In data");
|
||||||
|
return co(function* () {
|
||||||
|
try {
|
||||||
|
console.log("Received: " + message);
|
||||||
|
var data = JSON.parse(message);
|
||||||
|
switch (data.type) {
|
||||||
|
case 'auth':
|
||||||
|
console.log("Response auth");
|
||||||
|
var fileUrl = origin + "onlyoffice/document/test.bin";
|
||||||
|
if (data.openCmd.format=="xlsx")
|
||||||
|
fileUrl = origin + "onlyoffice/spreadsheet/test.bin"
|
||||||
|
else if (data.openCmd.format=="pptx")
|
||||||
|
fileUrl = origin + "onlyoffice/presentation/test.bin"
|
||||||
|
sendData(conn, {"type":"auth","result":1,"sessionId":"08e77705-dc5c-477d-b73a-b1a7cbca1e9b","sessionTimeConnect":1494226099270,"participants":[]});
|
||||||
|
sendData(conn, {"type":"documentOpen","data":{"type":"open","status":"ok","data":{"Editor.bin":fileUrl}}});
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.log("error receiving response: docId = %s type = %s\r\n%s", docId, (data && data.type) ? data.type : 'null', e.stack);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
conn.on('error', function() {
|
||||||
|
console.log("On error");
|
||||||
|
});
|
||||||
|
conn.on('close', function() {
|
||||||
|
return co(function* () {
|
||||||
|
console.log("On close");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
console.log("ooserver sending welcome message");
|
||||||
|
sendData(conn, {
|
||||||
|
type: 'license',
|
||||||
|
license: {
|
||||||
|
type: 3,
|
||||||
|
light: false,
|
||||||
|
trial: false,
|
||||||
|
rights: 1,
|
||||||
|
buildVersion: "4.3.3",
|
||||||
|
buildNumber: 4,
|
||||||
|
branding: false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
sockjs_echo.installHandlers(server, {prefix: '/onlyoffice/doc/[0-9-.a-zA-Z_=]*/c', log: function(severity, message) {
|
||||||
|
console.log(message);
|
||||||
|
}});
|
||||||
|
|
||||||
|
callbackFunction();
|
||||||
|
};
|
@ -0,0 +1,10 @@
|
|||||||
|
git clone https://github.com/ldubost/web-apps.git
|
||||||
|
git clone https://github.com/ldubost/sdkjs.git
|
||||||
|
cd sdkjs
|
||||||
|
make
|
||||||
|
cd ..
|
||||||
|
rm -rf ../web-apps
|
||||||
|
cp -r web-apps/deploy/web-apps ..
|
||||||
|
rm -rf ../sdkjs
|
||||||
|
cp -r web-apps/deploy/sdkjs ..
|
||||||
|
|
@ -0,0 +1,5 @@
|
|||||||
|
cd web-apps
|
||||||
|
git pull
|
||||||
|
cd ../sdkjs
|
||||||
|
git pull
|
||||||
|
make clean
|
@ -0,0 +1,38 @@
|
|||||||
|
@import (once) "../../customize/src/less2/include/browser.less";
|
||||||
|
@import (once) "../../customize/src/less2/include/toolbar.less";
|
||||||
|
@import (once) "../../customize/src/less2/include/markdown.less";
|
||||||
|
@import (once) '../../customize/src/less2/include/fileupload.less';
|
||||||
|
@import (once) '../../customize/src/less2/include/alertify.less';
|
||||||
|
@import (once) '../../customize/src/less2/include/avatar.less';
|
||||||
|
|
||||||
|
.toolbar_main();
|
||||||
|
.fileupload_main();
|
||||||
|
.alertify_main();
|
||||||
|
|
||||||
|
// body
|
||||||
|
&.cp-app-oo {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column;
|
||||||
|
|
||||||
|
#cp-toolbar {
|
||||||
|
display: flex; // We need this to remove a 3px border at the bottom of the toolbar
|
||||||
|
}
|
||||||
|
|
||||||
|
.cp-cryptpad-toolbar {
|
||||||
|
padding: 0px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
#cp-app-oo-container {
|
||||||
|
flex: 1;
|
||||||
|
height: 100%;
|
||||||
|
background-color: lightgrey;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
#ooframe {
|
||||||
|
flex: 1;
|
||||||
|
border:none;
|
||||||
|
margin:0;
|
||||||
|
padding:0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,23 @@
|
|||||||
|
config = {
|
||||||
|
"document": {
|
||||||
|
"fileType": "docx",
|
||||||
|
"key": "Khirz6zTPdfd7",
|
||||||
|
"title": "test.docx",
|
||||||
|
"url": "/onlyoffice/test.docx"
|
||||||
|
},
|
||||||
|
"documentType": "text",
|
||||||
|
"editorConfig": {
|
||||||
|
"user": {
|
||||||
|
"id": "c0c3bf82-20d7-4663-bf6d-7fa39c598b1d",
|
||||||
|
"name": "John Smith"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"events": {
|
||||||
|
"onDocumentStateChange": function(evt) { console.log("in change"); window.top.APP.onLocal(); },
|
||||||
|
"onReady": function(evt) { console.log("in onReady"); window.top.onOOReady(); }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
var docEditor = new DocsAPI.DocEditor("placeholder", config);
|
||||||
|
|
@ -0,0 +1,14 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="placeholder"></div>
|
||||||
|
<script type="text/javascript" src="/onlyoffice/web-apps/apps/api/documents/api.js"></script>
|
||||||
|
<script type="text/javascript" src="/onlyoffice/document/doc.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,38 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>CryptPad</title>
|
||||||
|
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta name="referrer" content="no-referrer" />
|
||||||
|
<script async data-bootload="main.js" data-main="/common/boot.js?ver=1.0" src="/bower_components/requirejs/require.js?ver=2.3.5"></script>
|
||||||
|
<style>
|
||||||
|
html, body {
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
#sbox-iframe {
|
||||||
|
position:fixed;
|
||||||
|
top:0px;
|
||||||
|
left:0px;
|
||||||
|
bottom:0px;
|
||||||
|
right:0px;
|
||||||
|
width:100%;
|
||||||
|
height:100%;
|
||||||
|
border:none;
|
||||||
|
margin:0;
|
||||||
|
padding:0;
|
||||||
|
overflow:hidden;
|
||||||
|
}
|
||||||
|
#sbox-filePicker-iframe {
|
||||||
|
position: fixed;
|
||||||
|
top:0; left:0;
|
||||||
|
bottom:0; right:0;
|
||||||
|
width:100%;
|
||||||
|
height: 100%;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<iframe id="sbox-iframe">
|
@ -0,0 +1,17 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html class="cp-app-noscroll">
|
||||||
|
<head>
|
||||||
|
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
|
||||||
|
<script async data-bootload="/onlyoffice/document/inner.js" data-main="/common/sframe-boot.js?ver=1.4" src="/bower_components/requirejs/require.js?ver=2.3.5"></script>
|
||||||
|
<style>
|
||||||
|
.loading-hidden { display: none; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body class="cp-app-oo">
|
||||||
|
<div id="cp-toolbar" class="cp-toolbar-container"></div>
|
||||||
|
<div id="cp-app-oo-container">
|
||||||
|
<iframe id="ooframe" src="document.html" width="100%" height="100%">
|
||||||
|
</iframe>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
@ -0,0 +1,308 @@
|
|||||||
|
define([
|
||||||
|
'jquery',
|
||||||
|
'/common/toolbar3.js',
|
||||||
|
'json.sortify',
|
||||||
|
'/bower_components/nthen/index.js',
|
||||||
|
'/common/sframe-common.js',
|
||||||
|
'/common/common-interface.js',
|
||||||
|
'/api/config',
|
||||||
|
'/customize/messages.js',
|
||||||
|
'/customize/application_config.js',
|
||||||
|
'/bower_components/chainpad/chainpad.dist.js',
|
||||||
|
|
||||||
|
'/bower_components/file-saver/FileSaver.min.js',
|
||||||
|
|
||||||
|
'css!/bower_components/bootstrap/dist/css/bootstrap.min.css',
|
||||||
|
'less!/bower_components/components-font-awesome/css/font-awesome.min.css',
|
||||||
|
'less!/customize/src/less2/main.less',
|
||||||
|
], function (
|
||||||
|
$,
|
||||||
|
Toolbar,
|
||||||
|
JSONSortify,
|
||||||
|
nThen,
|
||||||
|
SFCommon,
|
||||||
|
UI,
|
||||||
|
ApiConfig,
|
||||||
|
Messages,
|
||||||
|
AppConfig,
|
||||||
|
ChainPad)
|
||||||
|
{
|
||||||
|
var saveAs = window.saveAs;
|
||||||
|
|
||||||
|
var ooReady = window.frames[0] && window.frames[0].frames[0] && window.frames[0].frames[0].editor;
|
||||||
|
window.onOOReady = function () {
|
||||||
|
ooReady = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
var APP = window.APP = {
|
||||||
|
$: $
|
||||||
|
};
|
||||||
|
|
||||||
|
var stringify = function (obj) {
|
||||||
|
return JSONSortify(obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
var toolbar;
|
||||||
|
|
||||||
|
var andThen = function (common) {
|
||||||
|
var config = {};
|
||||||
|
|
||||||
|
var emitResize = APP.emitResize = function () {
|
||||||
|
var cw = $('#ooframe')[0].contentWindow;
|
||||||
|
|
||||||
|
var evt = cw.document.createEvent('UIEvents');
|
||||||
|
evt.initUIEvent('resize', true, false, cw, 0);
|
||||||
|
cw.dispatchEvent(evt);
|
||||||
|
};
|
||||||
|
|
||||||
|
var saveToServer = APP.saveToServer = function () {
|
||||||
|
config.onLocal();
|
||||||
|
}
|
||||||
|
|
||||||
|
var callRemote = APP.callRemote = function() {
|
||||||
|
config.onRemote();
|
||||||
|
}
|
||||||
|
|
||||||
|
var saveDocument = APP.saveDocument = function () {
|
||||||
|
var defaultName = "text.oot";
|
||||||
|
UI.prompt(Messages.exportPrompt, defaultName, function (filename) {
|
||||||
|
if (!(typeof(filename) === 'string' && filename)) { return; }
|
||||||
|
console.log("In saveDocument");
|
||||||
|
var content = window.frames[0].frames[0].editor.asc_nativeGetFile();
|
||||||
|
var blob = new Blob([content], {type: "text/plain;charset=utf-8"});
|
||||||
|
saveAs(blob, filename);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var loadDocument = APP.loadDocument = function (content, file) {
|
||||||
|
console.log("Read " + content);
|
||||||
|
return;
|
||||||
|
window.frames[0].frames[0].editor.asc_CloseFile();
|
||||||
|
var openResult = {bSerFormat: true, data: content, url: "http://localhost:3000/onlyoffice/", changes: null};
|
||||||
|
window.frames[0].frames[0].editor.openDocument(openResult);
|
||||||
|
};
|
||||||
|
|
||||||
|
var readOnly = false;
|
||||||
|
var initializing = true;
|
||||||
|
var $bar = $('#cp-toolbar');
|
||||||
|
var Title;
|
||||||
|
var cpNfInner;
|
||||||
|
var metadataMgr = common.getMetadataMgr();
|
||||||
|
|
||||||
|
config = {
|
||||||
|
readOnly: readOnly,
|
||||||
|
patchTransformer: ChainPad.NaiveJSONTransformer,
|
||||||
|
// cryptpad debug logging (default is 1)
|
||||||
|
// logLevel: 0,
|
||||||
|
validateContent: function (content) {
|
||||||
|
try {
|
||||||
|
JSON.parse(content);
|
||||||
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
console.log("Failed to parse, rejecting patch");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var setEditable = function (state) {
|
||||||
|
console.log(state);
|
||||||
|
};
|
||||||
|
|
||||||
|
var stringifyInner = function (textValue) {
|
||||||
|
var obj = {
|
||||||
|
content: textValue,
|
||||||
|
metadata: metadataMgr.getMetadataLazy()
|
||||||
|
};
|
||||||
|
// stringify the json and send it into chainpad
|
||||||
|
return stringify(obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
APP.onLocal = config.onLocal = function () {
|
||||||
|
console.log(initializing, readOnly);
|
||||||
|
if (initializing) { return; }
|
||||||
|
if (readOnly) { return; }
|
||||||
|
|
||||||
|
if (!window.frames[0].frames[0] || !window.frames[0].frames[0].editor) {
|
||||||
|
console.log("Cannot access editor");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log('ok');
|
||||||
|
var data = window.frames[0].frames[0].editor.asc_nativeGetFile();
|
||||||
|
var content = stringifyInner(data);
|
||||||
|
APP.realtime.contentUpdate(content);
|
||||||
|
};
|
||||||
|
|
||||||
|
config.onInit = function (info) {
|
||||||
|
readOnly = metadataMgr.getPrivateData().readOnly;
|
||||||
|
|
||||||
|
Title = common.createTitle({});
|
||||||
|
|
||||||
|
var configTb = {
|
||||||
|
displayed: [
|
||||||
|
'userlist',
|
||||||
|
'title',
|
||||||
|
'useradmin',
|
||||||
|
'spinner',
|
||||||
|
'newpad',
|
||||||
|
'share',
|
||||||
|
'limit',
|
||||||
|
'unpinnedWarning'
|
||||||
|
],
|
||||||
|
title: Title.getTitleConfig(),
|
||||||
|
metadataMgr: metadataMgr,
|
||||||
|
readOnly: readOnly,
|
||||||
|
realtime: info.realtime,
|
||||||
|
sfCommon: common,
|
||||||
|
$container: $bar,
|
||||||
|
$contentContainer: $('#cp-app-oo-container')
|
||||||
|
};
|
||||||
|
toolbar = APP.toolbar = Toolbar.create(configTb);
|
||||||
|
Title.setToolbar(toolbar);
|
||||||
|
|
||||||
|
var $rightside = toolbar.$rightside;
|
||||||
|
|
||||||
|
|
||||||
|
/* add an export button */
|
||||||
|
var $export = common.createButton('export', true, {}, saveDocument);
|
||||||
|
$rightside.append($export);
|
||||||
|
var $import = common.createButton('import', true, {}, loadDocument);
|
||||||
|
$rightside.append($import);
|
||||||
|
var $save = common.createButton('save', true, {}, saveToServer);
|
||||||
|
$save.click(function () {
|
||||||
|
saveToServer();
|
||||||
|
});
|
||||||
|
$rightside.append($save);
|
||||||
|
var $remote = common.createButton('remote', true, {}, callRemote);
|
||||||
|
$remote.click(function () {
|
||||||
|
callRemote();
|
||||||
|
});
|
||||||
|
$rightside.append($remote);
|
||||||
|
|
||||||
|
if (common.isLoggedIn()) {
|
||||||
|
common.createButton('hashtag', true).appendTo($rightside);
|
||||||
|
}
|
||||||
|
|
||||||
|
var $forget = common.createButton('forget', true, {}, function (err) {
|
||||||
|
if (err) { return; }
|
||||||
|
setEditable(false);
|
||||||
|
});
|
||||||
|
$rightside.append($forget);
|
||||||
|
};
|
||||||
|
|
||||||
|
config.onReady = function (info) {
|
||||||
|
if (APP.realtime !== info.realtime) {
|
||||||
|
APP.realtime = info.realtime;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!window.frames[0].frames[0] || !window.frames[0].frames[0].editor) {
|
||||||
|
console.log("Cannot access editor");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var userDoc = APP.realtime.getUserDoc();
|
||||||
|
var isNew = false;
|
||||||
|
var newDoc = '';
|
||||||
|
if (userDoc === "" || userDoc === "{}") { isNew = true; }
|
||||||
|
|
||||||
|
if (userDoc !== "") {
|
||||||
|
var hjson = JSON.parse(userDoc);
|
||||||
|
|
||||||
|
if (hjson && hjson.metadata) {
|
||||||
|
metadataMgr.updateMetadata(hjson.metadata);
|
||||||
|
}
|
||||||
|
if (typeof (hjson) !== 'object' || Array.isArray(hjson) ||
|
||||||
|
(hjson.metadata && typeof(hjson.metadata.type) !== 'undefined' &&
|
||||||
|
hjson.metadata.type !== 'oo')) {
|
||||||
|
var errorText = Messages.typeError;
|
||||||
|
UI.errorLoadingScreen(errorText);
|
||||||
|
throw new Error(errorText);
|
||||||
|
}
|
||||||
|
newDoc = hjson.content;
|
||||||
|
} else {
|
||||||
|
Title.updateTitle(Title.defaultTitle);
|
||||||
|
}
|
||||||
|
|
||||||
|
loadDocument(newDoc);
|
||||||
|
initializing = false;
|
||||||
|
setEditable(!readOnly);
|
||||||
|
UI.removeLoadingScreen();
|
||||||
|
};
|
||||||
|
|
||||||
|
config.onRemote = function () {
|
||||||
|
if (initializing) { return; }
|
||||||
|
if (!window.frames[0].frames[0] || !window.frames[0].frames[0].editor) {
|
||||||
|
console.log("Cannot access editor");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// force readonly to prevent interlacing
|
||||||
|
readOnly = true;
|
||||||
|
|
||||||
|
var previousData = window.frames[0].frames[0].editor.asc_nativeGetFile();
|
||||||
|
var userDoc = APP.realtime.getUserDoc();
|
||||||
|
|
||||||
|
var json = JSON.parse(userDoc);
|
||||||
|
if (json.metadata) {
|
||||||
|
metadataMgr.updateMetadata(json.metadata);
|
||||||
|
}
|
||||||
|
var remoteDoc = json.content;
|
||||||
|
if (remoteDoc!=previousData) {
|
||||||
|
console.log("Remote content is different")
|
||||||
|
console.log("Remote content hjson: " + remoteDoc);
|
||||||
|
loadDocument(remoteDoc);
|
||||||
|
common.notify();
|
||||||
|
} else {
|
||||||
|
console.log("Data is unchanged");
|
||||||
|
}
|
||||||
|
|
||||||
|
readOnly = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
config.onAbort = function () {
|
||||||
|
// inform of network disconnect
|
||||||
|
setEditable(false);
|
||||||
|
toolbar.failed();
|
||||||
|
UI.alert(Messages.common_connectionLost, undefined, true);
|
||||||
|
};
|
||||||
|
|
||||||
|
config.onConnectionChange = function (info) {
|
||||||
|
setEditable(info.state);
|
||||||
|
if (info.state) {
|
||||||
|
initializing = true;
|
||||||
|
UI.findOKButton().click();
|
||||||
|
} else {
|
||||||
|
UI.alert(Messages.common_connectionLost, undefined, true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
cpNfInner = common.startRealtime(config);
|
||||||
|
|
||||||
|
cpNfInner.onInfiniteSpinner(function () {
|
||||||
|
setEditable(false);
|
||||||
|
UI.confirm(Messages.realtime_unrecoverableError, function (yes) {
|
||||||
|
if (!yes) { return; }
|
||||||
|
common.gotoURL();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
common.onLogout(function () { setEditable(false); });
|
||||||
|
};
|
||||||
|
|
||||||
|
var main = function () {
|
||||||
|
var common;
|
||||||
|
|
||||||
|
nThen(function (waitFor) {
|
||||||
|
if (!ooReady) {
|
||||||
|
window.onOOReady = waitFor();
|
||||||
|
}
|
||||||
|
$(waitFor(function () {
|
||||||
|
UI.addLoadingScreen();
|
||||||
|
}));
|
||||||
|
SFCommon.create(waitFor(function (c) { APP.common = common = c; }));
|
||||||
|
}).nThen(function (/*waitFor*/) {
|
||||||
|
andThen(common);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
main();
|
||||||
|
});
|
@ -0,0 +1,43 @@
|
|||||||
|
// Load #1, load as little as possible because we are in a race to get the loading screen up.
|
||||||
|
define([
|
||||||
|
'/bower_components/nthen/index.js',
|
||||||
|
'/api/config',
|
||||||
|
'/common/dom-ready.js',
|
||||||
|
'/common/requireconfig.js',
|
||||||
|
'/common/sframe-common-outer.js'
|
||||||
|
], function (nThen, ApiConfig, DomReady, RequireConfig, SFCommonO) {
|
||||||
|
var requireConfig = RequireConfig();
|
||||||
|
|
||||||
|
// Loaded in load #2
|
||||||
|
nThen(function (waitFor) {
|
||||||
|
DomReady.onReady(waitFor());
|
||||||
|
}).nThen(function (waitFor) {
|
||||||
|
var req = {
|
||||||
|
cfg: requireConfig,
|
||||||
|
req: [ '/common/loading.js' ],
|
||||||
|
pfx: window.location.origin
|
||||||
|
};
|
||||||
|
window.rc = requireConfig;
|
||||||
|
window.apiconf = ApiConfig;
|
||||||
|
document.getElementById('sbox-iframe').setAttribute('src',
|
||||||
|
ApiConfig.httpSafeOrigin + '/onlyoffice/document/inner.html?' + requireConfig.urlArgs +
|
||||||
|
'#' + encodeURIComponent(JSON.stringify(req)));
|
||||||
|
|
||||||
|
// This is a cheap trick to avoid loading sframe-channel in parallel with the
|
||||||
|
// loading screen setup.
|
||||||
|
var done = waitFor();
|
||||||
|
var onMsg = function (msg) {
|
||||||
|
var data = JSON.parse(msg.data);
|
||||||
|
if (data.q !== 'READY') { return; }
|
||||||
|
window.removeEventListener('message', onMsg);
|
||||||
|
var _done = done;
|
||||||
|
done = function () { };
|
||||||
|
_done();
|
||||||
|
};
|
||||||
|
window.addEventListener('message', onMsg);
|
||||||
|
}).nThen(function (/*waitFor*/) {
|
||||||
|
SFCommonO.start({
|
||||||
|
type: 'oo'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
After Width: | Height: | Size: 477 KiB |
@ -0,0 +1,10 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<ul>
|
||||||
|
<li><a href="document/">Text</a></li>
|
||||||
|
<li><a href="spreadsheet/">Calc</a></li>
|
||||||
|
<li><a href="presentation/">Presentation</a></li>
|
||||||
|
</ul>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,60 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html class="cp">
|
||||||
|
<head>
|
||||||
|
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
|
<script data-bootload="main.js" data-main="/common/boot.js" src="/bower_components/requirejs/require.js"></script>
|
||||||
|
<link rel="icon" type="image/png"
|
||||||
|
href="/customize/main-favicon.png"
|
||||||
|
data-main-favicon="/customize/main-favicon.png"
|
||||||
|
data-alt-favicon="/customize/alt-favicon.png"
|
||||||
|
id="favicon" />
|
||||||
|
<link rel="stylesheet" href="/bower_components/components-font-awesome/css/font-awesome.min.css">
|
||||||
|
<link rel="stylesheet" href="/customize/main.css" />
|
||||||
|
<style>
|
||||||
|
html, body{
|
||||||
|
padding: 0px;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
#editor {
|
||||||
|
position: absolute;
|
||||||
|
margin-top: 70px;
|
||||||
|
top: 0px;
|
||||||
|
left: 0px;
|
||||||
|
right: 0px;
|
||||||
|
bottom: 0px;
|
||||||
|
background-color: lightgrey;
|
||||||
|
}
|
||||||
|
#ooframe {
|
||||||
|
position:absolute;
|
||||||
|
width:100%;
|
||||||
|
height:100%;
|
||||||
|
border:none;
|
||||||
|
margin:0;
|
||||||
|
padding:0;
|
||||||
|
overflow:hidden;
|
||||||
|
}
|
||||||
|
.cryptpad-toolbar {
|
||||||
|
height: 100px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="toolbar" class="toolbar-container"></div>
|
||||||
|
|
||||||
|
<div id="editor">
|
||||||
|
<iframe id="ooframe" src="presentation.html" width="100%" height="100%">
|
||||||
|
</iframe>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="loading">
|
||||||
|
<div class="loadingContainer">
|
||||||
|
<img class="cryptofist" src="/customize/cryptofist_small.png" />
|
||||||
|
<div class="spinnerContainer">
|
||||||
|
<span class="fa fa-spinner fa-pulse fa-4x fa-fw"></span>
|
||||||
|
</div>
|
||||||
|
<p data-localization="loading"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,495 @@
|
|||||||
|
require.config({ paths: {
|
||||||
|
'json.sortify': '/bower_components/json.sortify/dist/JSON.sortify'
|
||||||
|
}});
|
||||||
|
|
||||||
|
define([
|
||||||
|
'/api/config?cb=' + Math.random().toString(16).substring(2),
|
||||||
|
'/bower_components/chainpad-netflux/chainpad-netflux.js',
|
||||||
|
'/bower_components/hyperjson/hyperjson.js',
|
||||||
|
'/bower_components/chainpad-crypto/crypto.js',
|
||||||
|
'/common/toolbar.js',
|
||||||
|
'/bower_components/textpatcher/TextPatcher.amd.js',
|
||||||
|
'json.sortify',
|
||||||
|
'/bower_components/chainpad-json-validator/json-ot.js',
|
||||||
|
'/common/cryptpad-common.js',
|
||||||
|
'/bower_components/secure-fabric.js/dist/fabric.min.js',
|
||||||
|
'/bower_components/jquery/dist/jquery.min.js',
|
||||||
|
'/bower_components/file-saver/FileSaver.min.js',
|
||||||
|
'/bower_components/diff-dom/diffDOM.js',
|
||||||
|
], function (Config, Realtime, Hyperjson, Crypto, Toolbar, TextPatcher, JSONSortify, JsonOT, Cryptpad) {
|
||||||
|
var saveAs = window.saveAs;
|
||||||
|
var Messages = Cryptpad.Messages;
|
||||||
|
|
||||||
|
var module = window.APP = { };
|
||||||
|
var $ = module.$ = window.jQuery;
|
||||||
|
var Fabric = module.Fabric = window.fabric;
|
||||||
|
window.Hyperjson = Hyperjson;
|
||||||
|
|
||||||
|
$(function () {
|
||||||
|
var DiffDom = window.diffDOM;
|
||||||
|
Cryptpad.addLoadingScreen();
|
||||||
|
var onConnectError = function (info) {
|
||||||
|
Cryptpad.errorLoadingScreen(Messages.websocketError);
|
||||||
|
};
|
||||||
|
|
||||||
|
var emitResize = module.emitResize = function () {
|
||||||
|
var cw = $('#ooframe')[0].contentWindow;
|
||||||
|
|
||||||
|
var evt = cw.document.createEvent('UIEvents');
|
||||||
|
evt.initUIEvent('resize', true, false, cw, 0);
|
||||||
|
cw.dispatchEvent(evt);
|
||||||
|
};
|
||||||
|
|
||||||
|
var toolbar;
|
||||||
|
|
||||||
|
var secret = Cryptpad.getSecrets();
|
||||||
|
readOnly = secret.keys && !secret.keys.editKeyStr;
|
||||||
|
ooReady = false;
|
||||||
|
firstRemote = false;
|
||||||
|
|
||||||
|
if (!secret.keys) {
|
||||||
|
secret.keys = secret.key;
|
||||||
|
}
|
||||||
|
|
||||||
|
var andThen = function () {
|
||||||
|
|
||||||
|
var saveToServer = module.saveToServer = function () {
|
||||||
|
config.onLocal();
|
||||||
|
}
|
||||||
|
|
||||||
|
var callRemote = module.callRemote = function() {
|
||||||
|
config.onRemote();
|
||||||
|
}
|
||||||
|
|
||||||
|
var saveDocument = module.saveDocument = function () {
|
||||||
|
var defaultName = "text.oot";
|
||||||
|
Cryptpad.prompt(Messages.exportPrompt, defaultName, function (filename) {
|
||||||
|
if (!(typeof(filename) === 'string' && filename)) { return; }
|
||||||
|
console.log("In saveDocument");
|
||||||
|
var content = window.frames[0].frames[0].editor.asc_nativeGetFile();
|
||||||
|
var blob = new Blob([content], {type: "text/plain;charset=utf-8"});
|
||||||
|
saveAs(blob, filename);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var loadDocument = module.loadDocument = function (content, file) {
|
||||||
|
// console.log("Read " + content);
|
||||||
|
console.log("In loadDocument");
|
||||||
|
var openResult = {data: content, url: "http://localhost:3000/onlyoffice/"};
|
||||||
|
window.frames[0].frames[0].AscCommon.History.TurnOff();
|
||||||
|
window.frames[0].frames[0].editor.openDocument(openResult);
|
||||||
|
};
|
||||||
|
|
||||||
|
initializing = true;
|
||||||
|
|
||||||
|
var $bar = $('#toolbar');
|
||||||
|
var parsedHash = Cryptpad.parsePadUrl(window.location.href);
|
||||||
|
var defaultName = Cryptpad.getDefaultName(parsedHash);
|
||||||
|
var isHistoryMode = false;
|
||||||
|
var userData = module.userData = {}; // List of pretty name of all users (mapped with their server ID)
|
||||||
|
var userList; // List of users still connected to the channel (server IDs)
|
||||||
|
var addToUserData = function(data) {
|
||||||
|
var users = module.users;
|
||||||
|
for (var attrname in data) { userData[attrname] = data[attrname]; }
|
||||||
|
|
||||||
|
if (users && users.length) {
|
||||||
|
for (var userKey in userData) {
|
||||||
|
if (users.indexOf(userKey) === -1) {
|
||||||
|
delete userData[userKey];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(userList && typeof userList.onChange === "function") {
|
||||||
|
userList.onChange(userData);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var myData = {};
|
||||||
|
var myUserName = ''; // My "pretty name"
|
||||||
|
var myID; // My server ID
|
||||||
|
|
||||||
|
var setMyID = function(info) {
|
||||||
|
myID = info.myID || null;
|
||||||
|
myUserName = myID;
|
||||||
|
};
|
||||||
|
|
||||||
|
var config = module.config = {
|
||||||
|
initialState: '{}',
|
||||||
|
websocketURL: Cryptpad.getWebsocketURL(),
|
||||||
|
validateKey: secret.keys.validateKey,
|
||||||
|
readOnly: readOnly,
|
||||||
|
channel: secret.channel,
|
||||||
|
crypto: Crypto.createEncryptor(secret.keys),
|
||||||
|
setMyID: setMyID,
|
||||||
|
transformFunction: JsonOT.transform,
|
||||||
|
};
|
||||||
|
|
||||||
|
var suggestName = function (fallback) {
|
||||||
|
if (document.title === defaultName) {
|
||||||
|
return fallback || "";
|
||||||
|
} else {
|
||||||
|
return document.title || defaultName;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var renameCb = function (err, title) {
|
||||||
|
if (err) { return; }
|
||||||
|
document.title = title;
|
||||||
|
config.onLocal();
|
||||||
|
};
|
||||||
|
|
||||||
|
var editHash;
|
||||||
|
var onInit = config.onInit = function (info) {
|
||||||
|
userList = info.userList;
|
||||||
|
var config = {
|
||||||
|
displayed: ['useradmin', 'spinner', 'lag', 'state', 'share', 'userlist', 'newpad'],
|
||||||
|
userData: userData,
|
||||||
|
readOnly: readOnly,
|
||||||
|
share: {
|
||||||
|
secret: secret,
|
||||||
|
channel: info.channel
|
||||||
|
},
|
||||||
|
ifrw: window,
|
||||||
|
title: {
|
||||||
|
onRename: renameCb,
|
||||||
|
defaultName: defaultName,
|
||||||
|
suggestName: suggestName
|
||||||
|
},
|
||||||
|
common: Cryptpad
|
||||||
|
};
|
||||||
|
if (readOnly) {delete config.changeNameID; }
|
||||||
|
toolbar = module.toolbar = Toolbar.create($bar, info.myID, info.realtime, info.getLag, userList, config);
|
||||||
|
|
||||||
|
var $rightside = $bar.find('.' + Toolbar.constants.rightside);
|
||||||
|
|
||||||
|
/* add a history button */
|
||||||
|
var histConfig = {};
|
||||||
|
histConfig.onRender = function (val) {
|
||||||
|
if (typeof val === "undefined") { return; }
|
||||||
|
try {
|
||||||
|
console.log("History render: " + val);
|
||||||
|
} catch (e) {
|
||||||
|
// Probably a parse error
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
histConfig.onClose = function () {
|
||||||
|
// Close button clicked
|
||||||
|
setHistory(false, true);
|
||||||
|
jQuery("#editor")[0].style="margin-top: 70px;";
|
||||||
|
|
||||||
|
};
|
||||||
|
histConfig.onRevert = function () {
|
||||||
|
// Revert button clicked
|
||||||
|
setHistory(false, false);
|
||||||
|
onLocal();
|
||||||
|
onRemote();
|
||||||
|
};
|
||||||
|
histConfig.onReady = function () {
|
||||||
|
// Called when the history is loaded and the UI displayed
|
||||||
|
setHistory(true);
|
||||||
|
jQuery("#editor")[0].style="margin-top: 100px;";
|
||||||
|
};
|
||||||
|
histConfig.$toolbar = $bar;
|
||||||
|
var $hist = Cryptpad.createButton('history', true, {histConfig: histConfig});
|
||||||
|
$rightside.append($hist);
|
||||||
|
|
||||||
|
var $export = Cryptpad.createButton('export', true, {}, saveDocument);
|
||||||
|
$rightside.append($export);
|
||||||
|
var $import = Cryptpad.createButton('import', true, {}, loadDocument);
|
||||||
|
$rightside.append($import);
|
||||||
|
var $save = Cryptpad.createButton('save', true, {}, saveToServer);
|
||||||
|
$save.click(function () {
|
||||||
|
saveToServer();
|
||||||
|
});
|
||||||
|
$rightside.append($save);
|
||||||
|
var $remote = Cryptpad.createButton('remote', true, {}, callRemote);
|
||||||
|
$remote.click(function () {
|
||||||
|
callRemote();
|
||||||
|
});
|
||||||
|
$rightside.append($remote);
|
||||||
|
|
||||||
|
var editHash;
|
||||||
|
var viewHash = Cryptpad.getViewHashFromKeys(info.channel, secret.keys);
|
||||||
|
|
||||||
|
if (!readOnly) {
|
||||||
|
editHash = Cryptpad.getEditHashFromKeys(info.channel, secret.keys);
|
||||||
|
}
|
||||||
|
if (!readOnly) { Cryptpad.replaceHash(editHash); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// used for debugging, feel free to remove
|
||||||
|
var Catch = function (f) {
|
||||||
|
return function () {
|
||||||
|
try {
|
||||||
|
f();
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
var setHistory = function (bool, update) {
|
||||||
|
isHistoryMode = bool;
|
||||||
|
// setEditable(!bool);
|
||||||
|
if (!bool && update) {
|
||||||
|
config.onRemote();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var updateTitle = function (newTitle) {
|
||||||
|
if (newTitle === document.title) { return; }
|
||||||
|
// Change the title now, and set it back to the old value if there is an error
|
||||||
|
var oldTitle = document.title;
|
||||||
|
document.title = newTitle;
|
||||||
|
Cryptpad.renamePad(newTitle, function (err, data) {
|
||||||
|
if (err) {
|
||||||
|
console.log("Couldn't set pad title");
|
||||||
|
console.error(err);
|
||||||
|
document.title = oldTitle;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
document.title = data;
|
||||||
|
$bar.find('.' + Toolbar.constants.title).find('span.title').text(data);
|
||||||
|
$bar.find('.' + Toolbar.constants.title).find('input').val(data);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var updateDefaultTitle = function (defaultTitle) {
|
||||||
|
defaultName = defaultTitle;
|
||||||
|
$bar.find('.' + Toolbar.constants.title).find('input').attr("placeholder", defaultName);
|
||||||
|
};
|
||||||
|
|
||||||
|
var updateMetadata = function(shjson) {
|
||||||
|
// Extract the user list (metadata) from the hyperjson
|
||||||
|
var json = (shjson === "") ? "" : JSON.parse(shjson);
|
||||||
|
var titleUpdated = false;
|
||||||
|
if (json && json.metadata) {
|
||||||
|
if (json.metadata.users) {
|
||||||
|
var userData = json.metadata.users;
|
||||||
|
// Update the local user data
|
||||||
|
addToUserData(userData);
|
||||||
|
}
|
||||||
|
if (json.metadata.defaultTitle) {
|
||||||
|
updateDefaultTitle(json.metadata.defaultTitle);
|
||||||
|
}
|
||||||
|
if (typeof json.metadata.title !== "undefined") {
|
||||||
|
updateTitle(json.metadata.title || defaultName);
|
||||||
|
titleUpdated = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!titleUpdated) {
|
||||||
|
updateTitle(defaultName);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var hjson2domstring = function(hjson) {
|
||||||
|
var userDocStateDom = hjsonToDom(JSON.parse(hjson));
|
||||||
|
var tmp = document.createElement("div");
|
||||||
|
tmp.appendChild(userDocStateDom);
|
||||||
|
return tmp.innerHTML;
|
||||||
|
};
|
||||||
|
|
||||||
|
var onRemoteInit = config.onRemoteInit = Catch(function() {
|
||||||
|
console.log("In onRemoteInit");
|
||||||
|
ooReady = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
var onRemote = config.onRemote = Catch(function () {
|
||||||
|
console.log("In onRemote");
|
||||||
|
if (initializing) { return; }
|
||||||
|
if (isHistoryMode) { return; }
|
||||||
|
|
||||||
|
// force readonly to prevent interlacing
|
||||||
|
readOnly = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (window.frames[0].frames[0]==null || window.frames[0].frames[0].editor==null) {
|
||||||
|
console.log("Cannot access editor");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("In onRemote sync");
|
||||||
|
var previousData = window.frames[0].frames[0].editor.asc_nativeGetFile();
|
||||||
|
var userDoc = module.realtime.getUserDoc();
|
||||||
|
|
||||||
|
// console.log("Current data " + previousData);
|
||||||
|
|
||||||
|
updateMetadata(userDoc);
|
||||||
|
var json = JSON.parse(userDoc);
|
||||||
|
var remoteDoc = json.content;
|
||||||
|
if (remoteDoc!=previousData) {
|
||||||
|
console.log("Remote content is different")
|
||||||
|
// console.log("Remote content hjson: " + remoteDoc);
|
||||||
|
if (ooReady) {
|
||||||
|
if (remoteDoc)
|
||||||
|
loadDocument(remoteDoc);
|
||||||
|
firstRemote = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log("Data is unchanged");
|
||||||
|
firstRemote = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
readOnly = false;
|
||||||
|
} catch (e) {
|
||||||
|
console.log("Exception: " + e);
|
||||||
|
throw e;
|
||||||
|
} finally {
|
||||||
|
readOnly = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
var diffOptions = {
|
||||||
|
preDiffApply: function (info) {
|
||||||
|
},
|
||||||
|
postDiffApply : function(info) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var DD = new DiffDom(diffOptions);
|
||||||
|
|
||||||
|
// apply patches, and try not to lose the cursor in the process!
|
||||||
|
var applyHjson = function (shjson, domElement) {
|
||||||
|
var userDocStateDom = hjsonToDom(JSON.parse(shjson));
|
||||||
|
|
||||||
|
if (!readOnly && !initializing) {
|
||||||
|
userDocStateDom.setAttribute("contenteditable", "true"); // lol wtf
|
||||||
|
}
|
||||||
|
var patch = (DD).diff(domElement, userDocStateDom);
|
||||||
|
(DD).apply(domElement, patch);
|
||||||
|
};
|
||||||
|
|
||||||
|
var stringify = function (obj) {
|
||||||
|
return JSONSortify(obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
var hjsonToDom = function (H) {
|
||||||
|
var dom = Hyperjson.toDOM(H);
|
||||||
|
return dom;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
var stringifyInner = function (textValue) {
|
||||||
|
var obj = {
|
||||||
|
content: textValue,
|
||||||
|
metadata: {
|
||||||
|
users: userData,
|
||||||
|
defaultTitle: defaultName
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (!initializing) {
|
||||||
|
obj.metadata.title = document.title;
|
||||||
|
}
|
||||||
|
// stringify the json and send it into chainpad
|
||||||
|
return JSONSortify(obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
var onLocal = config.onLocal = Catch(function () {
|
||||||
|
console.log("In onLocal");
|
||||||
|
if (initializing) { return; }
|
||||||
|
if (isHistoryMode) { return; }
|
||||||
|
if (readOnly) { return; }
|
||||||
|
if (!ooReady) { return; }
|
||||||
|
|
||||||
|
if (!firstRemote) {
|
||||||
|
console.log("First remote");
|
||||||
|
onRemote();
|
||||||
|
if (firstRemote) {
|
||||||
|
console.log("First remote success");
|
||||||
|
} else {
|
||||||
|
console.log("First remote failure");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window.frames[0].frames[0]==null || window.frames[0].frames[0].editor==null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
console.log("In onLocal sync");
|
||||||
|
var data = window.frames[0].frames[0].editor.asc_nativeGetFile();
|
||||||
|
var content = stringifyInner(data);
|
||||||
|
module.patchText(content);
|
||||||
|
});
|
||||||
|
|
||||||
|
var setName = module.setName = function (newName) {
|
||||||
|
if (typeof(newName) !== 'string') { return; }
|
||||||
|
var myUserNameTemp = newName.trim();
|
||||||
|
if(newName.trim().length > 32) {
|
||||||
|
myUserNameTemp = myUserNameTemp.substr(0, 32);
|
||||||
|
}
|
||||||
|
myUserName = myUserNameTemp;
|
||||||
|
myData[myID] = {
|
||||||
|
name: myUserName,
|
||||||
|
uid: Cryptpad.getUid(),
|
||||||
|
};
|
||||||
|
addToUserData(myData);
|
||||||
|
Cryptpad.setAttribute('username', myUserName, function (err, data) {
|
||||||
|
if (err) {
|
||||||
|
console.log("Couldn't set username");
|
||||||
|
console.error(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
onLocal();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var onReady = config.onReady = function (info) {
|
||||||
|
var realtime = module.realtime = info.realtime;
|
||||||
|
module.patchText = TextPatcher.create({
|
||||||
|
realtime: realtime
|
||||||
|
});
|
||||||
|
|
||||||
|
Cryptpad.removeLoadingScreen();
|
||||||
|
// setEditable(true);
|
||||||
|
initializing = false;
|
||||||
|
onRemote();
|
||||||
|
Cryptpad.getLastName(function (err, lastName) {
|
||||||
|
if (err) {
|
||||||
|
console.log("Could not get previous name");
|
||||||
|
console.error(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Update the toolbar list:
|
||||||
|
// Add the current user in the metadata if he has edit rights
|
||||||
|
if (readOnly) { return; }
|
||||||
|
if (typeof(lastName) === 'string') {
|
||||||
|
setName(lastName);
|
||||||
|
} else {
|
||||||
|
myData[myID] = {
|
||||||
|
name: "",
|
||||||
|
uid: Cryptpad.getUid(),
|
||||||
|
};
|
||||||
|
addToUserData(myData);
|
||||||
|
onLocal();
|
||||||
|
// module.$userNameButton.click();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var onAbort = config.onAbort = function (info) {
|
||||||
|
// setEditable(false);
|
||||||
|
window.alert("Server Connection Lost");
|
||||||
|
|
||||||
|
if (window.confirm("Would you like to save your image?")) {
|
||||||
|
saveImage();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var rt = Realtime.start(config);
|
||||||
|
};
|
||||||
|
|
||||||
|
Cryptpad.ready(function (err, env) {
|
||||||
|
andThen();
|
||||||
|
});
|
||||||
|
Cryptpad.onError(function (info) {
|
||||||
|
if (info) {
|
||||||
|
onConnectError();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,31 @@
|
|||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<div id="placeholder"></div>
|
||||||
|
<script type="text/javascript" src="/onlyoffice/web-apps/apps/api/documents/api.js"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
config = {
|
||||||
|
"document": {
|
||||||
|
"fileType": "pptx",
|
||||||
|
"key": "Khirz6zTPdfd7",
|
||||||
|
"title": "test.pptx",
|
||||||
|
"url": "http://localhost:3000/onlyoffice/test.pptx"
|
||||||
|
},
|
||||||
|
"documentType": "presentation",
|
||||||
|
"editorConfig": {
|
||||||
|
"user": {
|
||||||
|
"id": "c0c3bf82-20d7-4663-bf6d-7fa39c598b1d",
|
||||||
|
"name": "John Smith"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"events": {
|
||||||
|
"onDocumentStateChange": function(evt) { console.log("in change"); window.top.APP.config.onLocal(); },
|
||||||
|
"onReady": function(evt) { console.log("in onReady"); window.top.APP.config.onRemoteInit(); }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
var docEditor = new DocsAPI.DocEditor("placeholder", config);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 902 B |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 7.3 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 6.0 KiB |
After Width: | Height: | Size: 131 KiB |
After Width: | Height: | Size: 163 KiB |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 540 KiB |