mirror of
https://github.com/ONLYOFFICE/document-server-integration.git
synced 2026-04-07 14:06:11 +08:00
Merge branch 'develop' into feature/formats
This commit is contained in:
@ -16,5 +16,6 @@ module.exports = {
|
||||
'no-continue': 'off',
|
||||
'no-extend-native': ['error', { exceptions: ['String'] }],
|
||||
'no-plusplus': ['error', { allowForLoopAfterthoughts: true }],
|
||||
'no-prototype-builtins': 'off',
|
||||
},
|
||||
};
|
||||
|
||||
@ -106,7 +106,6 @@ app.get('/', (req, res) => { // define a handler for default page
|
||||
storedFiles: req.DocManager.getStoredFiles(),
|
||||
params: req.DocManager.getCustomParams(),
|
||||
users,
|
||||
serverUrl: req.DocManager.getServerUrl(),
|
||||
languages: configServer.get('languages'),
|
||||
});
|
||||
} catch (ex) {
|
||||
@ -334,11 +333,11 @@ app.post('/convert', (req, res) => { // define a handler for converting files
|
||||
const result = {};
|
||||
|
||||
// write file name, step and error values to the result object if they are defined
|
||||
if (filename) result.filename = filename;
|
||||
if (result.filename !== null) result.filename = filename;
|
||||
|
||||
if (step) result.step = step;
|
||||
if (result.filenameep !== null) result.step = step;
|
||||
|
||||
if (error) result.error = error;
|
||||
if (result.error !== null) result.error = error;
|
||||
|
||||
response.setHeader('Content-Type', 'application/json');
|
||||
response.write(JSON.stringify(result));
|
||||
@ -539,6 +538,40 @@ app.post('/reference', (req, res) => { // define a handler for renaming file
|
||||
result(data);
|
||||
});
|
||||
|
||||
app.put('/restore', (req, res) => { // define a handler for restore file version
|
||||
const { fileName } = req.body;
|
||||
const result = {};
|
||||
if (fileName) {
|
||||
req.DocManager = new DocManager(req, res);
|
||||
const userAddress = req.DocManager.curUserHostAddress();
|
||||
const key = req.DocManager.getKey(fileName);
|
||||
const { version } = req.body;
|
||||
const filePath = req.DocManager.storagePath(fileName, userAddress);
|
||||
const historyPath = req.DocManager.historyPath(fileName, userAddress);
|
||||
const newVersion = req.DocManager.countVersion(historyPath) + 1;
|
||||
const versionPath = `${historyPath}\\${version}\\prev${fileUtility.getFileExtension(fileName)}`;
|
||||
const newVersionPath = `${historyPath}\\${newVersion}`;
|
||||
|
||||
if (fileSystem.existsSync(versionPath)) {
|
||||
req.DocManager.createDirectory(newVersionPath);
|
||||
req.DocManager.copyFile(filePath, `${newVersionPath}\\prev${fileUtility.getFileExtension(fileName)}`);
|
||||
fileSystem.writeFileSync(`${newVersionPath}\\key.txt`, key);
|
||||
req.DocManager.copyFile(versionPath, filePath);
|
||||
result.success = true;
|
||||
} else {
|
||||
result.success = false;
|
||||
result.error = 'Version path does not exists';
|
||||
}
|
||||
} else {
|
||||
result.success = false;
|
||||
result.error = 'Filename is empty';
|
||||
}
|
||||
|
||||
res.writeHead(200, { 'Content-Type': 'application/json' });
|
||||
res.write(JSON.stringify(result));
|
||||
res.end();
|
||||
});
|
||||
|
||||
app.post('/track', async (req, res) => { // define a handler for tracking file changes
|
||||
req.DocManager = new DocManager(req, res);
|
||||
|
||||
@ -798,7 +831,7 @@ app.post('/track', async (req, res) => { // define a handler for tracking file c
|
||||
// check jwt token
|
||||
if (cfgSignatureEnable && cfgSignatureUseForRequest) {
|
||||
let body = null;
|
||||
if (Object.hasOwn(req.body, 'token')) { // if request body has its own token
|
||||
if (req.body.hasOwnProperty('token')) { // if request body has its own token
|
||||
body = documentService.readToken(req.body.token); // read and verify it
|
||||
} else {
|
||||
const checkJwtHeaderRes = documentService.checkJwtHeader(req); // otherwise, check jwt token headers
|
||||
@ -826,7 +859,7 @@ app.post('/track', async (req, res) => { // define a handler for tracking file c
|
||||
return;
|
||||
}
|
||||
|
||||
if (Object.hasOwn(req.body, 'status')) { // if the request body has status parameter
|
||||
if (req.body.hasOwnProperty('status')) { // if the request body has status parameter
|
||||
await processTrack(res, req.body, fName, uAddress); // track file changes
|
||||
} else {
|
||||
await readbody(req, res, fName, uAddress); // otherwise, read request body first
|
||||
@ -839,8 +872,6 @@ app.get('/editor', (req, res) => { // define a handler for editing document
|
||||
|
||||
const fileName = fileUtility.getFileName(req.query.fileName);
|
||||
let { fileExt } = req.query;
|
||||
const history = [];
|
||||
const historyData = [];
|
||||
const lang = req.DocManager.getLang();
|
||||
const user = users.getUser(req.query.userid);
|
||||
const userDirectUrl = req.query.directUrl === 'true';
|
||||
@ -918,76 +949,6 @@ app.get('/editor', (req, res) => { // define a handler for editing document
|
||||
}
|
||||
const submitForm = mode === 'fillForms' && userid === 'uid-1' && !1;
|
||||
|
||||
let countVersion = 1;
|
||||
|
||||
const historyPath = req.DocManager.historyPath(fileName, userAddress);
|
||||
let changes = null;
|
||||
let keyVersion = key;
|
||||
|
||||
if (historyPath !== '') {
|
||||
countVersion = req.DocManager.countVersion(historyPath) + 1; // get the number of file versions
|
||||
for (let i = 1; i <= countVersion; i++) { // get keys to all the file versions
|
||||
if (i < countVersion) {
|
||||
const keyPath = req.DocManager.keyPath(fileName, userAddress, i);
|
||||
if (!fileSystem.existsSync(keyPath)) continue;
|
||||
keyVersion = `${fileSystem.readFileSync(keyPath)}`;
|
||||
} else {
|
||||
keyVersion = key;
|
||||
}
|
||||
// write all the file history information
|
||||
history.push(req.DocManager.getHistory(fileName, changes, keyVersion, i));
|
||||
|
||||
const userUrl = i === countVersion ? directUrl : (`${req.DocManager.getServerUrl(false)}/history?fileName=`
|
||||
+ `${encodeURIComponent(fileName)}&file=prev${fileExt}&ver=${i}`);
|
||||
const historyD = {
|
||||
fileType: fileExt.slice(1),
|
||||
version: i,
|
||||
key: keyVersion,
|
||||
url: i === countVersion ? url : (`${req.DocManager.getServerUrl(true)}/history?fileName=`
|
||||
+ `${encodeURIComponent(fileName)}&file=prev${fileExt}&ver=${i}&useraddress=${userAddress}`),
|
||||
directUrl: !userDirectUrl ? null : userUrl,
|
||||
};
|
||||
|
||||
// check if the path to the file with document versions differences exists
|
||||
if (i > 1 && req.DocManager.existsSync(req.DocManager.diffPath(fileName, userAddress, i - 1))) {
|
||||
historyD.previous = { // write information about previous file version
|
||||
fileType: historyData[i - 2].fileType,
|
||||
key: historyData[i - 2].key,
|
||||
url: historyData[i - 2].url,
|
||||
directUrl: !userDirectUrl ? null : historyData[i - 2].directUrl,
|
||||
};
|
||||
const changesUrl = `${req.DocManager.getServerUrl(true)}/history?fileName=`
|
||||
+ `${encodeURIComponent(fileName)}&file=diff.zip&ver=${i - 1}&useraddress=${userAddress}`;
|
||||
historyD.changesUrl = changesUrl; // get the path to the diff.zip file and write it to the history object
|
||||
}
|
||||
|
||||
historyData.push(historyD);
|
||||
|
||||
if (i < countVersion) {
|
||||
// get the path to the file with document changes
|
||||
const changesFile = req.DocManager.changesPath(fileName, userAddress, i);
|
||||
changes = req.DocManager.getChanges(changesFile); // get changes made in the file
|
||||
}
|
||||
}
|
||||
} else { // if history path is empty
|
||||
// write the history information about the last file version
|
||||
history.push(req.DocManager.getHistory(fileName, changes, keyVersion, countVersion));
|
||||
historyData.push({
|
||||
fileType: fileExt.slice(1),
|
||||
version: countVersion,
|
||||
key,
|
||||
url,
|
||||
directUrl: !userDirectUrl ? null : directUrl,
|
||||
});
|
||||
}
|
||||
|
||||
if (cfgSignatureEnable) {
|
||||
for (let i = 0; i < historyData.length; i++) {
|
||||
// sign token with given data using signature secret
|
||||
historyData[i].token = jwt.sign(historyData[i], cfgSignatureSecret, { expiresIn: cfgSignatureSecretExpiresIn });
|
||||
}
|
||||
}
|
||||
|
||||
// file config data
|
||||
const argss = {
|
||||
apiUrl: siteUrl + configServer.get('apiUrl'),
|
||||
@ -997,9 +958,8 @@ app.get('/editor', (req, res) => { // define a handler for editing document
|
||||
uri: url,
|
||||
directUrl: !userDirectUrl ? null : directUrl,
|
||||
uriUser: directUrl,
|
||||
version: countVersion,
|
||||
created: new Date().toDateString(),
|
||||
favorite: user.favorite ? user.favorite : 'null',
|
||||
favorite: user.favorite != null ? user.favorite : 'null',
|
||||
},
|
||||
editor: {
|
||||
type,
|
||||
@ -1040,8 +1000,6 @@ app.get('/editor', (req, res) => { // define a handler for editing document
|
||||
instanceId: userid !== 'uid-0' ? req.DocManager.getInstanceId() : null,
|
||||
protect: !user.deniedPermissions.includes('protect'),
|
||||
},
|
||||
history,
|
||||
historyData,
|
||||
dataInsertImage: {
|
||||
fileType: 'png',
|
||||
url: `${req.DocManager.getServerUrl(true)}/images/logo.png`,
|
||||
@ -1060,6 +1018,7 @@ app.get('/editor', (req, res) => { // define a handler for editing document
|
||||
directUrl: !userDirectUrl ? null : `${req.DocManager.getServerUrl()}/csv`,
|
||||
},
|
||||
usersForMentions: user.id !== 'uid-0' ? users.getUsersForMentions(user.id) : null,
|
||||
usersForProtect: user.id !== 'uid-0' ? users.getUsersForProtect(user.id) : null,
|
||||
};
|
||||
|
||||
if (cfgSignatureEnable) {
|
||||
@ -1121,6 +1080,27 @@ app.post('/rename', (req, res) => { // define a handler for renaming file
|
||||
documentService.commandRequest('meta', dockey, result, meta);
|
||||
});
|
||||
|
||||
app.post('/historyObj', (req, res) => {
|
||||
req.DocManager = new DocManager(req, res);
|
||||
const { fileName } = req.body;
|
||||
const { directUrl } = req.body || null;
|
||||
const historyObj = req.DocManager.getHistoryObject(fileName, null, directUrl);
|
||||
|
||||
if (cfgSignatureEnable) {
|
||||
for (let i = 0; i < historyObj.historyData.length; i++) {
|
||||
// sign token with given data using signature secret
|
||||
historyObj.historyData[i].token = jwt.sign(
|
||||
historyObj.historyData[i],
|
||||
cfgSignatureSecret,
|
||||
{ expiresIn: cfgSignatureSecretExpiresIn },
|
||||
);
|
||||
}
|
||||
}
|
||||
res.writeHead(200, { 'Content-Type': 'application/json' });
|
||||
res.write(JSON.stringify(historyObj));
|
||||
res.end();
|
||||
});
|
||||
|
||||
wopiApp.registerRoutes(app);
|
||||
|
||||
// "Not found" error with 404 status
|
||||
|
||||
@ -50,8 +50,8 @@
|
||||
"be": "Belarusian",
|
||||
"bg": "Bulgarian",
|
||||
"ca": "Catalan",
|
||||
"zh": "Chinese",
|
||||
"zh-TW": "Chinese (Taiwan)",
|
||||
"zh": "Chinese (Simplified)",
|
||||
"zh-TW": "Chinese (Traditional)",
|
||||
"cs": "Czech",
|
||||
"da": "Danish",
|
||||
"nl": "Dutch",
|
||||
|
||||
@ -438,6 +438,78 @@ DocManager.prototype.countVersion = function countVersion(directory) {
|
||||
return i;
|
||||
};
|
||||
|
||||
DocManager.prototype.getHistoryObject = function getHistoryObject(fileName, userAddr = null, userDirectUrl = null) {
|
||||
const userAddress = userAddr || this.curUserHostAddress();
|
||||
const historyPath = this.historyPath(fileName, userAddress);
|
||||
const key = this.getKey(fileName);
|
||||
const directUrl = this.getDownloadUrl(fileName);
|
||||
const fileExt = fileUtility.getFileExtension(fileName);
|
||||
const url = this.getDownloadUrl(fileName, true);
|
||||
const history = [];
|
||||
const historyData = [];
|
||||
let countVersion = 1;
|
||||
let changes = null;
|
||||
let keyVersion = key;
|
||||
|
||||
if (historyPath !== '') {
|
||||
countVersion = this.countVersion(historyPath) + 1; // get the number of file versions
|
||||
for (let i = 1; i <= countVersion; i++) { // get keys to all the file versions
|
||||
if (i < countVersion) {
|
||||
const keyPath = this.keyPath(fileName, userAddress, i);
|
||||
if (!fileSystem.existsSync(keyPath)) continue;
|
||||
keyVersion = `${fileSystem.readFileSync(keyPath)}`;
|
||||
} else {
|
||||
keyVersion = key;
|
||||
}
|
||||
// write all the file history information
|
||||
history.push(this.getHistory(fileName, changes, keyVersion, i));
|
||||
|
||||
const userUrl = i === countVersion ? directUrl : (`${this.getServerUrl(false)}/history?fileName=`
|
||||
+ `${encodeURIComponent(fileName)}&file=prev${fileExt}&ver=${i}`);
|
||||
const historyD = {
|
||||
fileType: fileExt.slice(1),
|
||||
version: i,
|
||||
key: keyVersion,
|
||||
url: i === countVersion ? url : (`${this.getServerUrl(true)}/history?fileName=`
|
||||
+ `${encodeURIComponent(fileName)}&file=prev${fileExt}&ver=${i}&useraddress=${userAddress}`),
|
||||
directUrl: !userDirectUrl ? null : userUrl,
|
||||
};
|
||||
|
||||
// check if the path to the file with document versions differences exists
|
||||
if (i > 1 && this.existsSync(this.diffPath(fileName, userAddress, i - 1))) {
|
||||
historyD.previous = { // write information about previous file version
|
||||
fileType: historyData[i - 2].fileType,
|
||||
key: historyData[i - 2].key,
|
||||
url: historyData[i - 2].url,
|
||||
directUrl: !userDirectUrl ? null : historyData[i - 2].directUrl,
|
||||
};
|
||||
const changesUrl = `${this.getServerUrl(true)}/history?fileName=`
|
||||
+ `${encodeURIComponent(fileName)}&file=diff.zip&ver=${i - 1}&useraddress=${userAddress}`;
|
||||
historyD.changesUrl = changesUrl; // get the path to the diff.zip file and write it to the history object
|
||||
}
|
||||
|
||||
historyData.push(historyD);
|
||||
|
||||
if (i < countVersion) {
|
||||
// get the path to the file with document changes
|
||||
const changesFile = this.changesPath(fileName, userAddress, i);
|
||||
changes = this.getChanges(changesFile); // get changes made in the file
|
||||
}
|
||||
}
|
||||
} else { // if history path is empty
|
||||
// write the history information about the last file version
|
||||
history.push(this.getHistory(fileName, changes, keyVersion, countVersion));
|
||||
historyData.push({
|
||||
fileType: fileExt.slice(1),
|
||||
version: countVersion,
|
||||
key,
|
||||
url,
|
||||
directUrl: !userDirectUrl ? null : directUrl,
|
||||
});
|
||||
}
|
||||
|
||||
return { history, historyData, countVersion };
|
||||
};
|
||||
// get file history information
|
||||
DocManager.prototype.getHistory = function getHistory(fileName, content, keyVersion, version) {
|
||||
let oldVersion = false;
|
||||
|
||||
@ -125,7 +125,7 @@ users.getUser = function getUser(id) {
|
||||
return result || this[0];
|
||||
};
|
||||
|
||||
// get a list of users with their name and email
|
||||
// get a list of users with their name and email for mentions
|
||||
users.getUsersForMentions = function getUsersForMentions(id) {
|
||||
const result = [];
|
||||
this.forEach((user) => {
|
||||
@ -139,4 +139,19 @@ users.getUsersForMentions = function getUsersForMentions(id) {
|
||||
return result;
|
||||
};
|
||||
|
||||
// get a list of users with their name, id and email for protect
|
||||
users.getUsersForProtect = function getUsersForProtect(id) {
|
||||
const result = [];
|
||||
this.forEach((user) => {
|
||||
if (user.id !== id && user.name != null) {
|
||||
result.push({
|
||||
email: user.email,
|
||||
id: user.id,
|
||||
name: user.name,
|
||||
});
|
||||
}
|
||||
});
|
||||
return result;
|
||||
};
|
||||
|
||||
module.exports = users;
|
||||
|
||||
@ -80,7 +80,6 @@ exports.registerRoutes = function registerRoutes(app) {
|
||||
storedFiles: wopiEnable ? files : [],
|
||||
params: req.DocManager.getCustomParams(),
|
||||
users,
|
||||
serverUrl: req.DocManager.getServerUrl(),
|
||||
preloaderUrl: siteUrl + configServer.get('preloaderUrl'),
|
||||
convertExts: fileUtility.getConvertExtensions(),
|
||||
editedExts,
|
||||
|
||||
@ -34,30 +34,17 @@ if (typeof jQuery != "undefined") {
|
||||
else
|
||||
language = jq("#language").val();
|
||||
|
||||
|
||||
jq("#language").change(function() {
|
||||
window.location = "?lang=" + jq(this).val() + "&userid=" + userid + "&directUrl=" + directUrl;
|
||||
});
|
||||
|
||||
if ("" != userid && undefined != userid)
|
||||
jq("#user").val(userid);
|
||||
else
|
||||
userid = jq("#user").val();
|
||||
|
||||
jq("#user").change(function() {
|
||||
window.location = "?lang=" + language + "&userid=" + jq(this).val() + "&directUrl=" + directUrl;
|
||||
});
|
||||
|
||||
|
||||
if (directUrl)
|
||||
jq("#directUrl").prop("checked", directUrl);
|
||||
else
|
||||
directUrl = jq("#directUrl").prop("checked");
|
||||
|
||||
jq("#directUrl").change(function() {
|
||||
window.location = "?lang=" + language + "&userid=" + userid + "&directUrl=" + jq(this).prop("checked");
|
||||
});
|
||||
|
||||
|
||||
jq(function () {
|
||||
jq('#fileupload').fileupload({
|
||||
@ -111,7 +98,7 @@ if (typeof jQuery != "undefined") {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
var timer = null;
|
||||
var checkConvert = function (filePass) {
|
||||
filePass = filePass ? filePass : null;
|
||||
@ -230,6 +217,20 @@ if (typeof jQuery != "undefined") {
|
||||
}
|
||||
});
|
||||
|
||||
jq(document).on("click", ".action-link", function (e) {
|
||||
e.preventDefault();
|
||||
let url = this.href + collectParams(true);
|
||||
let target = null;
|
||||
|
||||
if (e.target.hasAttribute("target")) {
|
||||
target = e.target.getAttribute("target");
|
||||
} else if (e.target.parentNode.hasAttribute("target")) {
|
||||
target = e.target.parentNode.getAttribute("target");
|
||||
}
|
||||
|
||||
target !== null ? window.open(url, target) : window.location = url;
|
||||
});
|
||||
|
||||
jq(document).on("click", "#skipPass", function () {
|
||||
jq("#blockPassword").hide();
|
||||
loadScripts();
|
||||
@ -238,32 +239,32 @@ if (typeof jQuery != "undefined") {
|
||||
jq(document).on("click", "#beginEdit:not(.disable)", function () {
|
||||
var fileId = encodeURIComponent(jq('#hiddenFileName').val());
|
||||
if (UrlEditor == "wopi-action"){
|
||||
var url = UrlEditor + "/" + fileId + "?action=edit";
|
||||
var url = UrlEditor + "/" + fileId + "?action=edit" + collectParams(true);
|
||||
}else{
|
||||
var url = UrlEditor + "?fileName=" + fileId + "&lang=" + language + "&userid=" + userid + "&directUrl=" + directUrl;
|
||||
var url = UrlEditor + "?fileName=" + fileId + collectParams(true);
|
||||
}
|
||||
window.open(url, "_blank");
|
||||
jq('#hiddenFileName').val("");
|
||||
jq.unblockUI();
|
||||
document.location.reload(true);
|
||||
window.location = collectParams();
|
||||
});
|
||||
|
||||
jq(document).on("click", "#beginView:not(.disable)", function () {
|
||||
var fileId = encodeURIComponent(jq('#hiddenFileName').val());
|
||||
if (UrlEditor == "wopi-action"){
|
||||
var url = UrlEditor + "/" + fileId + "?action=view";
|
||||
var url = UrlEditor + "/" + fileId + "?action=view" + collectParams(true);
|
||||
}else{
|
||||
var url = UrlEditor + "?mode=view&fileName=" + fileId + "&lang=" + language + "&userid=" + userid + "&directUrl=" + directUrl;
|
||||
var url = UrlEditor + "?mode=view&fileName=" + fileId + collectParams(true);
|
||||
}
|
||||
window.open(url, "_blank");
|
||||
jq('#hiddenFileName').val("");
|
||||
jq.unblockUI();
|
||||
document.location.reload(true);
|
||||
window.location = collectParams();
|
||||
});
|
||||
|
||||
jq(document).on("click", "#beginEmbedded:not(.disable)", function () {
|
||||
var fileId = encodeURIComponent(jq('#hiddenFileName').val());
|
||||
var url = UrlEditor + "?type=embedded&fileName=" + fileId + "&lang=" + language + "&userid=" + userid + "&directUrl=" + directUrl;
|
||||
var url = UrlEditor + "?type=embedded&fileName=" + fileId + collectParams(true);
|
||||
|
||||
jq("#mainProgress").addClass("embedded");
|
||||
jq("#beginEmbedded").addClass("disable");
|
||||
@ -272,13 +273,13 @@ if (typeof jQuery != "undefined") {
|
||||
});
|
||||
|
||||
jq(document).on("click", ".reload-page", function () {
|
||||
setTimeout(function () { document.location.reload(true); }, 1000);
|
||||
setTimeout(function () { window.location = collectParams(); }, 1000);
|
||||
return true;
|
||||
});
|
||||
|
||||
jq(document).on("mouseup", ".reload-page", function (event) {
|
||||
if (event.which == 2) {
|
||||
setTimeout(function () { document.location.reload(true); }, 1000);
|
||||
setTimeout(function () { window.location = collectParams(); }, 1000);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
@ -288,12 +289,13 @@ if (typeof jQuery != "undefined") {
|
||||
jq("#embeddedView").remove();
|
||||
jq.unblockUI();
|
||||
if (mustReload) {
|
||||
document.location.reload(true);
|
||||
window.location = collectParams();
|
||||
}
|
||||
});
|
||||
|
||||
jq(document).on("click", ".delete-file", function () {
|
||||
var fileName = jq(this).attr("data");
|
||||
const currentElement = jq(this);
|
||||
var fileName = currentElement.attr("data");
|
||||
|
||||
var requestAddress = "file?filename=" + fileName;
|
||||
|
||||
@ -303,7 +305,16 @@ if (typeof jQuery != "undefined") {
|
||||
type: "delete",
|
||||
url: requestAddress,
|
||||
complete: function (data) {
|
||||
document.location.reload(true);
|
||||
if (JSON.parse(data.responseText).success) {
|
||||
const parentRow = currentElement.parents('tr')[0];
|
||||
if (parentRow) {
|
||||
jq(parentRow).remove();
|
||||
}
|
||||
const remainingRows = jq('tr.tableRow');
|
||||
if (remainingRows.length === 0) {
|
||||
window.location = collectParams();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
@ -394,4 +405,32 @@ function getUrlVars() {
|
||||
vars[hash[0]] = hash[1];
|
||||
}
|
||||
return vars;
|
||||
};
|
||||
};
|
||||
|
||||
function collectParams(startParams) {
|
||||
let paramsObjects = Array.prototype.slice.call(document.getElementsByClassName('collectable'));
|
||||
let params = [];
|
||||
let startChar = startParams ? "&" : "?";
|
||||
paramsObjects.forEach( function (element) {
|
||||
if (element.name) {
|
||||
switch (element.type) {
|
||||
case "select-one":
|
||||
case "text":
|
||||
if (element.value) {
|
||||
params.push(element.name + "=" + element.value);
|
||||
}
|
||||
break;
|
||||
case "checkbox":
|
||||
params.push(element.name + "=" + element.checked);
|
||||
break;
|
||||
case "radio":
|
||||
if (element.checked) {
|
||||
params.push(element.name + "=" + element.value);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
});
|
||||
return startChar + params.join("&");
|
||||
}
|
||||
|
||||
@ -39,6 +39,7 @@
|
||||
|
||||
var docEditor;
|
||||
var config;
|
||||
let historyObject;
|
||||
|
||||
var innerAlert = function (message, inEditor) {
|
||||
if (console && console.log)
|
||||
@ -72,26 +73,72 @@
|
||||
};
|
||||
|
||||
var onRequestHistory = function (event) { // the user is trying to show the document version history
|
||||
var historyObj = <%- JSON.stringify(history) %> || null;
|
||||
|
||||
docEditor.refreshHistory( // show the document version history
|
||||
const fileName = "<%- file.name %>" || null;
|
||||
const directUrl = "<%- file.directUrl %>" || null;
|
||||
const data = {
|
||||
fileName: fileName,
|
||||
directUrl: directUrl
|
||||
};
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", "historyObj");
|
||||
xhr.setRequestHeader("Content-Type", "application/json");
|
||||
xhr.send(JSON.stringify(data));
|
||||
xhr.onload = function () {
|
||||
historyObject = JSON.parse(xhr.responseText);
|
||||
docEditor.refreshHistory( // show the document version history
|
||||
{
|
||||
currentVersion: "<%- file.version %>",
|
||||
history: historyObj
|
||||
currentVersion: historyObject.countVersion,
|
||||
history: historyObject.history
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
var onRequestHistoryData = function (data) { // the user is trying to click the specific document version in the document version history
|
||||
var version = data.data;
|
||||
var historyData = <%- JSON.stringify(historyData) %> || null;
|
||||
|
||||
docEditor.setHistoryData(historyData[version-1]); // send the link to the document for viewing the version history
|
||||
var onRequestHistoryData = function (event) { // the user is trying to click the specific document version in the document version history
|
||||
const version = event.data;
|
||||
docEditor.setHistoryData(historyObject.historyData[version-1]); // send the link to the document for viewing the version history
|
||||
};
|
||||
|
||||
var onRequestHistoryClose = function (event){ // the user is trying to go back to the document from viewing the document version history
|
||||
document.location.reload();
|
||||
};
|
||||
|
||||
var onRequestRestore = function (event) { // the user is trying to restore file version
|
||||
const version = event.data.version;
|
||||
const fileName = "<%- file.name %>" || null;
|
||||
const directUrl = "<%- file.directUrl %>" || null;
|
||||
const restoreData = {
|
||||
version: version,
|
||||
fileName: fileName,
|
||||
};
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open("PUT", "restore");
|
||||
xhr.setRequestHeader('Content-Type', 'application/json');
|
||||
xhr.send(JSON.stringify(restoreData));
|
||||
xhr.onload = function () {
|
||||
const response = JSON.parse(xhr.responseText);
|
||||
if (response.success && !response.error) {
|
||||
const dataForHistory = {
|
||||
fileName: fileName,
|
||||
directUrl: directUrl
|
||||
};
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", "historyObj");
|
||||
xhr.setRequestHeader("Content-Type", "application/json");
|
||||
xhr.send(JSON.stringify(dataForHistory));
|
||||
xhr.onload = function () {
|
||||
historyObject = JSON.parse(xhr.responseText);
|
||||
docEditor.refreshHistory( // show the document version history
|
||||
{
|
||||
currentVersion: historyObject.countVersion,
|
||||
history: historyObject.history
|
||||
});
|
||||
}
|
||||
} else {
|
||||
innerAlert(response.error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var onError = function (event) { // an error or some other specific event occurs
|
||||
if (event)
|
||||
innerAlert(event.data);
|
||||
@ -139,9 +186,22 @@
|
||||
docEditor.setMailMergeRecipients(<%- JSON.stringify(dataMailMergeRecipients) %>); // insert recipient data for mail merge into the file
|
||||
};
|
||||
|
||||
var onRequestUsers = function () {
|
||||
docEditor.setUsers({ // set a list of users to mention in the comments
|
||||
"users": <%- JSON.stringify(usersForMentions) %>
|
||||
var onRequestUsers = function (event) {
|
||||
if (event && event.data){
|
||||
var c = event.data.c;
|
||||
}
|
||||
|
||||
switch (c) {
|
||||
case "protect":
|
||||
var users = <%- JSON.stringify(usersForProtect) %>;
|
||||
break;
|
||||
default:
|
||||
users = <%- JSON.stringify(usersForMentions) %>;
|
||||
}
|
||||
|
||||
docEditor.setUsers({
|
||||
"c": c,
|
||||
"users": users,
|
||||
});
|
||||
};
|
||||
|
||||
@ -222,6 +282,7 @@
|
||||
config.events.onRequestHistory = onRequestHistory;
|
||||
config.events.onRequestHistoryData = onRequestHistoryData;
|
||||
config.events.onRequestHistoryClose = onRequestHistoryClose;
|
||||
config.events.onRequestRestore = onRequestRestore;
|
||||
config.events.onRequestRename = onRequestRename;
|
||||
config.events.onRequestUsers = onRequestUsers;
|
||||
config.events.onRequestSendNotify = onRequestSendNotify;
|
||||
|
||||
@ -32,7 +32,7 @@
|
||||
<body>
|
||||
<header>
|
||||
<div class="center">
|
||||
<a href="">
|
||||
<a href="./">
|
||||
<img src ="images/logo.svg" alt="ONLYOFFICE" />
|
||||
</a>
|
||||
</div>
|
||||
@ -48,16 +48,16 @@
|
||||
<div class="create-panel clearFix">
|
||||
<ul class="try-editor-list clearFix">
|
||||
<li>
|
||||
<a class="try-editor word reload-page" target="_blank" href="editor?fileExt=docx<%= params %>" title="Create new document">Document</a>
|
||||
<a class="try-editor word reload-page action-link" target="_blank" href="editor?fileExt=docx" title="Create new document">Document</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="try-editor cell reload-page" target="_blank" href="editor?fileExt=xlsx<%= params %>" title="Create new spreadsheet">Spreadsheet</a>
|
||||
<a class="try-editor cell reload-page action-link" target="_blank" href="editor?fileExt=xlsx" title="Create new spreadsheet">Spreadsheet</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="try-editor slide reload-page" target="_blank" href="editor?fileExt=pptx<%= params %>" title="Create new presentation">Presentation</a>
|
||||
<a class="try-editor slide reload-page action-link" target="_blank" href="editor?fileExt=pptx" title="Create new presentation">Presentation</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="try-editor form reload-page" target="_blank" href="editor?fileExt=docxf<%= params %>" title="Create new form template">Form template</a>
|
||||
<a class="try-editor form reload-page action-link" target="_blank" href="editor?fileExt=docxf" title="Create new form template">Form template</a>
|
||||
</li>
|
||||
</ul>
|
||||
<label class="side-option">
|
||||
@ -67,7 +67,7 @@
|
||||
|
||||
<div class="upload-panel clearFix">
|
||||
<a class="file-upload">Upload file
|
||||
<input type="file" id="fileupload" name="uploadedFile" data-url="upload?<%= params %>" />
|
||||
<input type="file" id="fileupload" name="uploadedFile" data-url="upload" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@ -77,7 +77,7 @@
|
||||
<td valign="middle">
|
||||
<span class="select-user">Username</span>
|
||||
<img id="info" class="info" src="images/info.svg" />
|
||||
<select class="select-user" id="user">
|
||||
<select class="select-user collectable" name="userid" id="user">
|
||||
<% users.forEach(user => { %>
|
||||
<option value="<%= user.id %>"><%= user.name == null ? "Anonymous" : user.name %></option>
|
||||
<% }) %>
|
||||
@ -88,7 +88,7 @@
|
||||
<td valign="middle">
|
||||
<span class="select-user">Language</span>
|
||||
<img class="info info-tooltip" data-id="language" data-tooltip="Choose the language for ONLYOFFICE editors interface" src="images/info.svg" />
|
||||
<select class="select-user" id="language">
|
||||
<select class="select-user collectable" name="lang" id="language">
|
||||
<% Object.keys(languages).forEach(key => { %>
|
||||
<option value="<%= key %>"><%= languages[key] %></option>
|
||||
<% }) %>
|
||||
@ -98,7 +98,7 @@
|
||||
<tr>
|
||||
<td valign="middle">
|
||||
<label class="side-option">
|
||||
<input id="directUrl" type="checkbox" class="checkbox" />Try opening on client
|
||||
<input id="directUrl" type="checkbox" class="checkbox collectable" name="directUrl" />Try opening on client
|
||||
<img id="directUrlInfo" class="info info-tooltip" data-id="directUrlInfo" data-tooltip="Some files can be opened in the user's browser without connecting to the document server." src="images/info.svg" />
|
||||
</label>
|
||||
</td>
|
||||
@ -107,7 +107,7 @@
|
||||
</table>
|
||||
|
||||
<div class="links-panel links-panel-border clearFix">
|
||||
<a href="<%= serverUrl %>/wopi" class="">Go to WOPI page</a>
|
||||
<a href="wopi" class="">Go to WOPI page</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -154,33 +154,33 @@
|
||||
<% for (var i = 0; i < storedFiles.length; i++) { %>
|
||||
<tr class="tableRow" title="<%= storedFiles[i].name %> [<%= storedFiles[i].version %>]">
|
||||
<td class="contentCells">
|
||||
<a class="stored-edit <%= storedFiles[i].documentType %>" href="editor?fileName=<%= encodeURIComponent(storedFiles[i].name) + params %>" target="_blank">
|
||||
<a class="stored-edit <%= storedFiles[i].documentType %> action-link" href="editor?fileName=<%= encodeURIComponent(storedFiles[i].name) %>" target="_blank">
|
||||
<span><%= storedFiles[i].name %></span>
|
||||
</a>
|
||||
</td>
|
||||
<% if (storedFiles[i].canEdit) { %>
|
||||
<td class="contentCells contentCells-icon">
|
||||
<a href="editor?type=desktop&fileName=<%= encodeURIComponent(storedFiles[i].name) + params %>" target="_blank">
|
||||
<a class="action-link" href="editor?type=desktop&fileName=<%= encodeURIComponent(storedFiles[i].name) %>" target="_blank">
|
||||
<img src="images/desktop.svg" alt="Open in editor for full size screens" title="Open in editor for full size screens" /></a>
|
||||
</td>
|
||||
<td class="contentCells contentCells-icon">
|
||||
<a href="editor?type=desktop&mode=comment&fileName=<%= encodeURIComponent(storedFiles[i].name) + params %>" target="_blank">
|
||||
<a class="action-link" href="editor?type=desktop&mode=comment&fileName=<%= encodeURIComponent(storedFiles[i].name) %>" target="_blank">
|
||||
<img src="images/comment.svg" alt="Open in editor for comment" title="Open in editor for comment" /></a>
|
||||
</td>
|
||||
<% if (storedFiles[i].documentType == "word") { %>
|
||||
<td class="contentCells contentCells-icon">
|
||||
<a href="editor?type=desktop&mode=review&fileName=<%= encodeURIComponent(storedFiles[i].name) + params %>" target="_blank">
|
||||
<a class="action-link" href="editor?type=desktop&mode=review&fileName=<%= encodeURIComponent(storedFiles[i].name) %>" target="_blank">
|
||||
<img src="images/review.svg" alt="Open in editor for review" title="Open in editor for review" /></a>
|
||||
</td>
|
||||
<% } else if (storedFiles[i].documentType == "cell") { %>
|
||||
<td class="contentCells contentCells-icon">
|
||||
<a href="editor?type=desktop&mode=filter&fileName=<%= encodeURIComponent(storedFiles[i].name) + params %>" target="_blank">
|
||||
<a class="action-link" href="editor?type=desktop&mode=filter&fileName=<%= encodeURIComponent(storedFiles[i].name) %>" target="_blank">
|
||||
<img src="images/filter.svg" alt="Open in editor without access to change the filter" title="Open in editor without access to change the filter" /></a>
|
||||
</td>
|
||||
<% } %>
|
||||
<% if (storedFiles[i].documentType == "word") { %>
|
||||
<td class="contentCells contentCells-icon">
|
||||
<a href="editor?type=desktop&mode=blockcontent&fileName=<%= encodeURIComponent(storedFiles[i].name) + params %>" target="_blank">
|
||||
<a class="action-link" href="editor?type=desktop&mode=blockcontent&fileName=<%= encodeURIComponent(storedFiles[i].name) %>" target="_blank">
|
||||
<img src="images/block-content.svg" alt="Open in editor without content control modification" title="Open in editor without content control modification" /></a>
|
||||
</td>
|
||||
<% } else { %>
|
||||
@ -191,14 +191,14 @@
|
||||
<% } %>
|
||||
<% if (fillExts.indexOf(storedFiles[i].name.substring(storedFiles[i].name.lastIndexOf('.') + 1).trim().toLowerCase()) !== -1) { %>
|
||||
<td class="contentCells contentCells-icon">
|
||||
<a href="editor?type=desktop&mode=fillForms&fileName=<%= encodeURIComponent(storedFiles[i].name) + params %>" target="_blank">
|
||||
<a class="action-link" href="editor?type=desktop&mode=fillForms&fileName=<%= encodeURIComponent(storedFiles[i].name) %>" target="_blank">
|
||||
<img src="images/fill-forms.svg" alt="Open in editor for filling in forms" title="Open in editor for filling in forms" /></a>
|
||||
</td>
|
||||
<% } else {%>
|
||||
<td class="contentCells contentCells-icon"></td>
|
||||
<%}%>
|
||||
<td class="contentCells contentCells-shift contentCells-icon firstContentCellShift">
|
||||
<a href="editor?type=mobile&mode=edit&fileName=<%= encodeURIComponent(storedFiles[i].name) + params %>" target="_blank">
|
||||
<a class="action-link" href="editor?type=mobile&mode=edit&fileName=<%= encodeURIComponent(storedFiles[i].name) %>" target="_blank">
|
||||
<img src="images/mobile.svg" alt="Open in editor for mobile devices" title="Open in editor for mobile devices" /></a>
|
||||
</td>
|
||||
<% } else if (fillExts.indexOf(storedFiles[i].name.substring(storedFiles[i].name.lastIndexOf('.') + 1).trim().toLowerCase()) !== -1) { %>
|
||||
@ -207,26 +207,26 @@
|
||||
<td class="contentCells contentCells-icon "></td>
|
||||
<td class="contentCells contentCells-icon "></td>
|
||||
<td class="contentCells contentCells-icon">
|
||||
<a href="editor?type=desktop&mode=fillForms&fileName=<%= encodeURIComponent(storedFiles[i].name) + params %>" target="_blank">
|
||||
<a class="action-link" href="editor?type=desktop&mode=fillForms&fileName=<%= encodeURIComponent(storedFiles[i].name) %>" target="_blank">
|
||||
<img src="images/fill-forms.svg" alt="Open in editor for filling in forms" title="Open in editor for filling in forms" /></a>
|
||||
</td>
|
||||
<td class="contentCells contentCells-shift contentCells-icon firstContentCellShift">
|
||||
<a href="editor?type=mobile&mode=fillForms&fileName=<%= encodeURIComponent(storedFiles[i].name) + params %>" target="_blank">
|
||||
<a class="action-link" href="editor?type=mobile&mode=fillForms&fileName=<%= encodeURIComponent(storedFiles[i].name) %>" target="_blank">
|
||||
<img src="images/mobile-fill-forms.svg" alt="Open in editor for filling in forms for mobile devices" title="Open in editor for filling in forms for mobile devices" /></a>
|
||||
</td>
|
||||
<% } else { %>
|
||||
<td class="contentCells contentCells-shift contentCells-icon contentCellsEmpty" colspan="6"></td>
|
||||
<% } %>
|
||||
<td class="contentCells contentCells-icon firstContentCellViewers">
|
||||
<a href="editor?type=desktop&mode=view&fileName=<%= encodeURIComponent(storedFiles[i].name) + params %>" target="_blank">
|
||||
<a class="action-link" href="editor?type=desktop&mode=view&fileName=<%= encodeURIComponent(storedFiles[i].name) %>" target="_blank">
|
||||
<img src="images/desktop.svg" alt="Open in viewer for full size screens" title="Open in viewer for full size screens" /></a>
|
||||
</td>
|
||||
<td class="contentCells contentCells-icon">
|
||||
<a href="editor?type=mobile&mode=view&fileName=<%= encodeURIComponent(storedFiles[i].name) + params %>" target="_blank">
|
||||
<a class="action-link" href="editor?type=mobile&mode=view&fileName=<%= encodeURIComponent(storedFiles[i].name) %>" target="_blank">
|
||||
<img src="images/mobile.svg" alt="Open in viewer for mobile devices" title="Open in viewer for mobile devices" /></a>
|
||||
</td>
|
||||
<td class="contentCells contentCells-icon contentCells-shift">
|
||||
<a href="editor?type=embedded&mode=embedded&fileName=<%= encodeURIComponent(storedFiles[i].name) + params %>" target="_blank">
|
||||
<a class="action-link" href="editor?type=embedded&mode=embedded&fileName=<%= encodeURIComponent(storedFiles[i].name) %>" target="_blank">
|
||||
<img src="images/embeded.svg" alt="Open in embedded mode" title="Open in embedded mode" /></a>
|
||||
</td>
|
||||
<td class="contentCells contentCells-icon contentCells-shift downloadContentCellShift">
|
||||
|
||||
@ -35,7 +35,7 @@
|
||||
<body>
|
||||
<header>
|
||||
<div class="center">
|
||||
<a href="">
|
||||
<a href="wopi">
|
||||
<img src="images/logo.svg" alt="ONLYOFFICE" />
|
||||
</a>
|
||||
</div>
|
||||
@ -51,16 +51,16 @@
|
||||
<div class="create-panel clearFix">
|
||||
<ul class="try-editor-list clearFix">
|
||||
<li>
|
||||
<a class="try-editor word reload-page" target="_blank" href="<%= serverUrl %>/wopi-new?fileExt=docx<%= params %>" title="Create new document">Document</a>
|
||||
<a class="try-editor word reload-page action-link" target="_blank" href="wopi-new?fileExt=docx" title="Create new document">Document</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="try-editor cell reload-page" target="_blank" href="<%= serverUrl %>/wopi-new?fileExt=xlsx<%= params %>" title="Create new spreadsheet">Spreadsheet</a>
|
||||
<a class="try-editor cell reload-page action-link" target="_blank" href="wopi-new?fileExt=xlsx" title="Create new spreadsheet">Spreadsheet</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="try-editor slide reload-page" target="_blank" href="<%= serverUrl %>/wopi-new?fileExt=pptx<%= params %>" title="Create new presentation">Presentation</a>
|
||||
<a class="try-editor slide reload-page action-link" target="_blank" href="wopi-new?fileExt=pptx" title="Create new presentation">Presentation</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="try-editor form reload-page" target="_blank" href="<%= serverUrl %>/wopi-new?fileExt=docxf<%= params %>" title="Create new form template">Form template</a>
|
||||
<a class="try-editor form reload-page action-link" target="_blank" href="wopi-new?fileExt=docxf" title="Create new form template">Form template</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@ -68,7 +68,7 @@
|
||||
|
||||
<div class="upload-panel clearFix">
|
||||
<a class="file-upload">Upload file
|
||||
<input type="file" id="fileupload" name="uploadedFile" data-url="upload?<%= params %>" />
|
||||
<input type="file" id="fileupload" name="uploadedFile" data-url="upload" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@ -78,7 +78,7 @@
|
||||
<td valign="middle">
|
||||
<span class="select-user">Username</span>
|
||||
<img id="info" class="info" data-id="user" src="images/info.svg" />
|
||||
<select class="select-user" id="user">
|
||||
<select class="select-user collectable" name="userid" id="user">
|
||||
<% users.forEach(user => { %>
|
||||
<option value="<%= user.id %>"><%= user.name == null ? "Anonymous" : user.name %></option>
|
||||
<% }) %>
|
||||
@ -89,7 +89,7 @@
|
||||
<td valign="middle">
|
||||
<span class="select-user">Language</span>
|
||||
<img class="info info-tooltip" data-id="language" data-tooltip="Choose the language for ONLYOFFICE editors interface" src="images/info.svg" />
|
||||
<select class="select-user" id="language">
|
||||
<select class="select-user collectable" name="lang" id="language">
|
||||
<% Object.keys(languages).forEach(key => { %>
|
||||
<option value="<%= key %>"><%= languages[key] %></option>
|
||||
<% }) %>
|
||||
@ -100,7 +100,7 @@
|
||||
</table>
|
||||
|
||||
<div class="links-panel links-panel-border clearFix">
|
||||
<a href="<%= serverUrl %>/" class="">Go to Index page</a>
|
||||
<a href="./" class="">Go to Index page</a>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
@ -148,7 +148,7 @@
|
||||
<tr class="tableRow" title="<%= storedFiles[i].name %> [<%= storedFiles[i].version %>]">
|
||||
<td class="contentCells">
|
||||
<% if (storedFiles[i].defaultAction) { %>
|
||||
<a class="stored-edit <%= storedFiles[i].documentType %>" href="<%= serverUrl %>/wopi-action/<%= encodeURIComponent(storedFiles[i].name) %>?action=<%= storedFiles[i].defaultAction.name %><%= params %>" target="_blank">
|
||||
<a class="stored-edit <%= storedFiles[i].documentType %> action-link" href="wopi-action/<%= encodeURIComponent(storedFiles[i].name) %>?action=<%= storedFiles[i].defaultAction.name %>" target="_blank">
|
||||
<%} else { %>
|
||||
<a class="stored-edit <%= storedFiles[i].documentType %>" href="#">
|
||||
<% } %>
|
||||
@ -158,7 +158,7 @@
|
||||
<% if (storedFiles[i].actions && storedFiles[i].actions.length > 0) { %>
|
||||
<td class="contentCells contentCells-wopi contentCells-shift">
|
||||
<% for (var j = 0; j < storedFiles[i].actions.length; j++) { %>
|
||||
<a href="<%= serverUrl %>/wopi-action/<%= encodeURIComponent(storedFiles[i].name) %>?action=<%= storedFiles[i].actions[j].name %><%= params %>" target="_blank">
|
||||
<a class="action-link" href="wopi-action/<%= encodeURIComponent(storedFiles[i].name) %>?action=<%= storedFiles[i].actions[j].name %>" target="_blank">
|
||||
<img
|
||||
src="images/wopi-<%= storedFiles[i].actions[j].name %>.svg"
|
||||
alt="<%= storedFiles[i].actions[j].name %>" title="<%= storedFiles[i].actions[j].name %>" />
|
||||
@ -167,7 +167,7 @@
|
||||
</td>
|
||||
<% } %>
|
||||
<td class="contentCells contentCells-icon contentCells-shift downloadContentCells">
|
||||
<a href="<%= serverUrl %>/wopi/files/<%= encodeURIComponent(storedFiles[i].name) %>/contents">
|
||||
<a href="wopi/files/<%= encodeURIComponent(storedFiles[i].name) %>/contents">
|
||||
<img class="icon-download" src="images/download.svg" alt="Download" title="Download" /></a>
|
||||
</td>
|
||||
<td class="contentCells contentCells-icon contentCells-shift">
|
||||
@ -252,7 +252,8 @@
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script type="text/javascript" src="javascripts/jquery-1.8.2.js"></script>
|
||||
<script type="text/javascript" src="javascripts/jquery-3.6.4.min.js"></script>
|
||||
<script type="text/javascript" src="javascripts/jquery-migrate-3.4.1.min.js"></script>
|
||||
<script type="text/javascript" src="javascripts/jquery-ui.js"></script>
|
||||
<script type="text/javascript" src="javascripts/jquery.blockUI.js"></script>
|
||||
<script type="text/javascript" src="javascripts/jquery.iframe-transport.js"></script>
|
||||
|
||||
Reference in New Issue
Block a user