mirror of
https://github.com/ONLYOFFICE/document-server-integration.git
synced 2026-04-07 14:06:11 +08:00
Compare commits
142 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3ec226109e | |||
| b1f0fa6ecc | |||
| b02ffff33e | |||
| f74f0ba376 | |||
| 96d3bf2e63 | |||
| daf4f62acd | |||
| ade8a07e95 | |||
| 8b613627d1 | |||
| 3d3a10005c | |||
| 801c451899 | |||
| df034c2af2 | |||
| 9726c06c84 | |||
| 3a45e1b0f3 | |||
| ed8d0194b7 | |||
| a59da2d5df | |||
| f5c9a9e924 | |||
| 7b12b970c0 | |||
| 87a11c8633 | |||
| 01e0cefae5 | |||
| 98d42249fa | |||
| fd9454dd5f | |||
| fbf4153dea | |||
| 83b0411a4d | |||
| c60e4e25e2 | |||
| 4ebbecf580 | |||
| 6dbf383e2d | |||
| 1012bf13a6 | |||
| a24e081564 | |||
| 187ee212a9 | |||
| 106d9bfed3 | |||
| 13e243f900 | |||
| 4ccc3fa35e | |||
| be1fa2da14 | |||
| b6645427a8 | |||
| 39d7c366e3 | |||
| 075f464701 | |||
| 9414dff70c | |||
| 05b8989a87 | |||
| 43b6f53652 | |||
| c22c0d72aa | |||
| d61c112aa2 | |||
| ae3def67f5 | |||
| 7c22ba4e9e | |||
| 320881f1cf | |||
| 90c31eb887 | |||
| 702d0f1aa8 | |||
| dbf1047f29 | |||
| 0d27d142d4 | |||
| 807cbbf236 | |||
| e6b0bfd0be | |||
| 943d059c7c | |||
| 399ab0714d | |||
| 8cabbe9c71 | |||
| e40b6b2e28 | |||
| 0a390094e5 | |||
| f7bb668f8b | |||
| 808712ad34 | |||
| 2b0ba914dc | |||
| 249adaab48 | |||
| ee99a80ead | |||
| d61fdaaa53 | |||
| 270cbee160 | |||
| e9721dd655 | |||
| a31a24a871 | |||
| df0e197cb5 | |||
| 09802afc6f | |||
| 1c43679d87 | |||
| 573eeb6e18 | |||
| 78cf6c35f8 | |||
| c7f5003d69 | |||
| 19baff4340 | |||
| cc5c912658 | |||
| 64f2d605c2 | |||
| c9fca685bf | |||
| 820883a584 | |||
| 05a00a33a3 | |||
| 613cb713cc | |||
| 9216ff3a97 | |||
| dbaa7c5113 | |||
| d6ad145111 | |||
| 456df162e6 | |||
| 50fd47cf7c | |||
| f9c0da1696 | |||
| a7807513c6 | |||
| 128430d698 | |||
| 8077a66f16 | |||
| b3d8695a26 | |||
| 00872758ee | |||
| 3301c24de5 | |||
| dd0c049a70 | |||
| 44fb3a089c | |||
| 513bf99adb | |||
| 6f92633ef8 | |||
| b67e768dce | |||
| 751a886bfa | |||
| 66ea4b144b | |||
| 7a73422231 | |||
| 5319e18fb5 | |||
| 93accdac7c | |||
| def268f5f2 | |||
| 6054bffb3f | |||
| a7c917db3f | |||
| 30481005a1 | |||
| 5544768500 | |||
| 14e53970c8 | |||
| 82efd0f18a | |||
| 8ce90d89ed | |||
| 2b184972dc | |||
| 0fb9da4d89 | |||
| 9277d3de58 | |||
| baf7a1e5dd | |||
| e2a14a74db | |||
| 848cfb20bc | |||
| ddd3ec82a8 | |||
| 0ed08fd7b2 | |||
| e1c5907003 | |||
| 9dd2d7c0db | |||
| 8f0cbb78af | |||
| 72e48914aa | |||
| 82a282029a | |||
| 9b7c12b5c0 | |||
| 6ea5546099 | |||
| 92fbd1e293 | |||
| 855c1ed9f9 | |||
| 7e60ec15fd | |||
| 3697a4a888 | |||
| 0b8107d167 | |||
| 885850ee33 | |||
| 98c61250a6 | |||
| 457487844c | |||
| ff72956b68 | |||
| 1593df6aec | |||
| cda8a86c2a | |||
| 16584c0abb | |||
| 1ddda89001 | |||
| 5b76d798fb | |||
| e96200df85 | |||
| de75b11e18 | |||
| f27afe1535 | |||
| 59e17079ff | |||
| 1bdb3c03bc | |||
| 111dc14f2b |
31
.github/workflows/lint-java.yml
vendored
Normal file
31
.github/workflows/lint-java.yml
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
name: Lint Java
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches: [master, main]
|
||||
paths: ['web/documentserver-example/java/**']
|
||||
pull_request:
|
||||
branches: [master, main, develop]
|
||||
paths: ['web/documentserver-example/java/**']
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./web/documentserver-example/java
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install Java 11
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '11'
|
||||
|
||||
- name: Run linter
|
||||
run: |
|
||||
mvn -version
|
||||
mvn package
|
||||
35
.github/workflows/lint-nodejs.yml
vendored
Normal file
35
.github/workflows/lint-nodejs.yml
vendored
Normal file
@ -0,0 +1,35 @@
|
||||
name: ESLint
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches: [master, main]
|
||||
paths: ['web/documentserver-example/nodejs/**']
|
||||
pull_request:
|
||||
branches: [master, main, develop]
|
||||
paths: ['web/documentserver-example/nodejs/**']
|
||||
|
||||
env:
|
||||
NODE_VERSION: 16
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
name: Lint
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./web/documentserver-example/nodejs
|
||||
steps:
|
||||
- name: Install NodeJS
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
|
||||
- name: Code Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install Dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Code Linting
|
||||
run: npm run lint
|
||||
29
.github/workflows/lint-php.yml
vendored
Normal file
29
.github/workflows/lint-php.yml
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
name: PHPCs
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches: [master, main]
|
||||
paths: ['web/documentserver-example/php/**']
|
||||
pull_request:
|
||||
branches: [master, main, develop]
|
||||
paths: ['web/documentserver-example/php/**']
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./web/documentserver-example/php
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: '8.1'
|
||||
tools: cs2pr, phpcs
|
||||
|
||||
- name: Run phpcs
|
||||
run: phpcs -q --extensions=php,module,inc,install,test,profile,theme,css,info,txt,md,yml --ignore=node_modules,bower_components,vendor ./
|
||||
40
.github/workflows/lint-python.yml
vendored
Normal file
40
.github/workflows/lint-python.yml
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
name: PyLint
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches: [master, main]
|
||||
paths: ['web/documentserver-example/python/**']
|
||||
pull_request:
|
||||
branches: [master, main, develop]
|
||||
paths: ['web/documentserver-example/python/**']
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./web/documentserver-example/python
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.10'
|
||||
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install flake8
|
||||
pip install pylint
|
||||
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
|
||||
|
||||
- name: Lint Flake8
|
||||
run: |
|
||||
flake8 ./**/*.py --count --select=E9,F63,F7,F82 --show-source --statistics
|
||||
flake8 ./**/*.py --count --max-complexity=10 --max-line-length=79 --statistics
|
||||
|
||||
- name: Lint Pylint
|
||||
run: |
|
||||
pylint ./**/*.py
|
||||
31
.github/workflows/lint-ruby.yml
vendored
Normal file
31
.github/workflows/lint-ruby.yml
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
name: Rubocop
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches: [master, main]
|
||||
paths: ['web/documentserver-example/ruby/**']
|
||||
pull_request:
|
||||
branches: [master, main, develop]
|
||||
paths: ['web/documentserver-example/ruby/**']
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./web/documentserver-example/ruby
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v3
|
||||
- uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
ruby-version: '3.0'
|
||||
bundler-cache: true
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
bundle install
|
||||
- name: Rubocop
|
||||
run: |
|
||||
gem install rubocop
|
||||
rubocop
|
||||
31
.github/workflows/lint-spring.yml
vendored
Normal file
31
.github/workflows/lint-spring.yml
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
name: Lint Spring
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches: [master, main]
|
||||
paths: ['web/documentserver-example/java-spring/**']
|
||||
pull_request:
|
||||
branches: [master, main, develop]
|
||||
paths: ['web/documentserver-example/java-spring/**']
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./web/documentserver-example/java-spring
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install Java 11
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '11'
|
||||
|
||||
- name: Run linter
|
||||
run: |
|
||||
mvn -version
|
||||
mvn package
|
||||
11
CHANGELOG.md
11
CHANGELOG.md
@ -1,11 +1,21 @@
|
||||
# Change Log
|
||||
|
||||
- nodejs: fix wopi actions after restart
|
||||
- setting an unavailable language
|
||||
- description in the tooltip on the main page
|
||||
- nodejs: referenceData
|
||||
- option to send directUrl
|
||||
|
||||
## 1.4.0
|
||||
- nodejs: option to send directUrl
|
||||
- opening file on client by directUrl
|
||||
- offline viewer for anonymous
|
||||
- added hy, eu, zh-TW, ms, pt-PT
|
||||
|
||||
## 1.3.1
|
||||
- charp: fix references
|
||||
- ruby: update rails
|
||||
|
||||
## 1.3.0
|
||||
- update empty files
|
||||
- anonymous without chat
|
||||
@ -30,6 +40,5 @@
|
||||
- creating docxf
|
||||
- opening docxf, oform
|
||||
|
||||
|
||||
## 1.0.0
|
||||
- added java spring
|
||||
@ -167,7 +167,7 @@ label .checkbox {
|
||||
background-image: url("images/file_docxf.svg");
|
||||
}
|
||||
|
||||
.create-sample {
|
||||
.side-option {
|
||||
color: #666666;
|
||||
line-height: 24px;
|
||||
}
|
||||
@ -740,3 +740,28 @@ html {
|
||||
.user-descr > b {
|
||||
margin-left: 25px;
|
||||
}
|
||||
|
||||
.tooltip {
|
||||
background: #FFFFFF;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0px 7px 25px rgba(85, 85, 85, 0.15);
|
||||
color: #666666;
|
||||
line-height: 160%;
|
||||
max-width: 455px;
|
||||
padding: 14px;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.tooltip ul {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.arrow {
|
||||
border-top: 8px solid transparent;
|
||||
border-bottom: 8px solid transparent;
|
||||
border-right: 8px solid #FFFFFF;
|
||||
left: -4px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
@ -16,6 +16,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Web.Mvc;
|
||||
using OnlineEditorsExampleMVC.Helpers;
|
||||
@ -31,13 +32,14 @@ namespace OnlineEditorsExampleMVC.Controllers
|
||||
}
|
||||
|
||||
// viewing file in the editor
|
||||
public ActionResult Editor(string fileName, string editorsMode, string editorsType)
|
||||
public ActionResult Editor(string fileName, string editorsMode, string editorsType, string directUrl)
|
||||
{
|
||||
var file = new FileModel
|
||||
{
|
||||
Mode = editorsMode, // editor mode: edit or view
|
||||
Type = editorsType, // editor type: desktop, mobile, embedded
|
||||
FileName = Path.GetFileName(fileName) // file name
|
||||
FileName = Path.GetFileName(fileName), // file name
|
||||
IsEnabledDirectUrl = directUrl != null ? Convert.ToBoolean(directUrl) : false
|
||||
};
|
||||
|
||||
return View("Editor", file);
|
||||
|
||||
@ -442,5 +442,11 @@ namespace OnlineEditorsExampleMVC.Helpers
|
||||
}
|
||||
return languages;
|
||||
}
|
||||
|
||||
public static string GetDirectUrl()
|
||||
{
|
||||
string isEnabledDirectUrl = HttpUtility.ParseQueryString(HttpContext.Current.Request.Url.Query).Get("directUrl");
|
||||
return isEnabledDirectUrl != null ? isEnabledDirectUrl : "false";
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -321,6 +321,7 @@ namespace OnlineEditorsExampleMVC.Helpers
|
||||
if (string.IsNullOrEmpty(path)) throw new ArgumentException("path"); // file isn't specified
|
||||
|
||||
var req = (HttpWebRequest)WebRequest.Create(url);
|
||||
req.Timeout = 5000;
|
||||
using (var stream = req.GetResponse().GetResponseStream()) // get input stream of the file information from the url
|
||||
{
|
||||
if (stream == null) throw new Exception("stream is null");
|
||||
|
||||
@ -33,6 +33,7 @@ namespace OnlineEditorsExampleMVC.Models
|
||||
{
|
||||
public string Mode { get; set; } // editor mode
|
||||
public string Type { get; set; } // editor type
|
||||
public bool IsEnabledDirectUrl { get; set; } // is enabled direct url
|
||||
|
||||
// get file url for Document Server
|
||||
public string FileUri
|
||||
@ -126,7 +127,7 @@ namespace OnlineEditorsExampleMVC.Models
|
||||
{
|
||||
{ "title", FileName },
|
||||
{ "url", DownloadUrl },
|
||||
{ "directUrl", directUrl },
|
||||
{ "directUrl", IsEnabledDirectUrl ? directUrl : "" },
|
||||
{ "fileType", ext.Trim('.') },
|
||||
{ "key", Key },
|
||||
{
|
||||
@ -286,7 +287,10 @@ namespace OnlineEditorsExampleMVC.Models
|
||||
}
|
||||
|
||||
dataObj.Add("url", prevFileUrl);
|
||||
dataObj.Add("directUrl", directPrevFileUrl);
|
||||
if (IsEnabledDirectUrl)
|
||||
{
|
||||
dataObj.Add("directUrl", directPrevFileUrl);
|
||||
}
|
||||
dataObj.Add("version", i);
|
||||
if (i > 1) // check if the version number is greater than 1 (the file was modified)
|
||||
{
|
||||
@ -304,11 +308,15 @@ namespace OnlineEditorsExampleMVC.Models
|
||||
obj.Add("user", change.Count > 0 ? change["user"] : null);
|
||||
|
||||
var prev = (Dictionary<string, object>)histData[(i - 2).ToString()]; // get the history data from the previous file version
|
||||
dataObj.Add("previous", new Dictionary<string, object>() { // write information about previous file version to the data object
|
||||
dataObj.Add("previous", IsEnabledDirectUrl ? new Dictionary<string, object>() { // write information about previous file version to the data object with direct url
|
||||
{ "fileType", prev["fileType"] },
|
||||
{ "key", prev["key"] }, // write key and url information about previous file version
|
||||
{ "url", prev["url"] },
|
||||
{ "directUrl", prev["directUrl"] },
|
||||
} : new Dictionary<string, object>() { // write information about previous file version to the data object without direct url
|
||||
{ "fileType", prev["fileType"] },
|
||||
{ "key", prev["key"] }, // write key and url information about previous file version
|
||||
{ "url", prev["url"] },
|
||||
});
|
||||
// write the path to the diff.zip archive with differences in this file version
|
||||
var changesUrl = DocManagerHelper.GetHistoryDownloadUrl(FileName, (i - 1).ToString(), "diff.zip");
|
||||
@ -359,10 +367,14 @@ namespace OnlineEditorsExampleMVC.Models
|
||||
var dataCompareFile = new Dictionary<string, object>
|
||||
{
|
||||
{ "fileType", "docx" },
|
||||
{ "url", compareFileUrl.ToString() },
|
||||
{ "directUrl", directCompareFileUrl.ToString()}
|
||||
{ "url", compareFileUrl.ToString() }
|
||||
};
|
||||
|
||||
if (IsEnabledDirectUrl)
|
||||
{
|
||||
dataCompareFile.Add("directUrl", directCompareFileUrl.ToString());
|
||||
}
|
||||
|
||||
if (JwtManager.Enabled) // if the secret key to generate token exists
|
||||
{
|
||||
var compareFileToken = JwtManager.Encode(dataCompareFile); // encode the dataCompareFile object into the token
|
||||
@ -396,10 +408,14 @@ namespace OnlineEditorsExampleMVC.Models
|
||||
var logoConfig = new Dictionary<string, object>
|
||||
{
|
||||
{ "fileType", "png"},
|
||||
{ "url", mailMergeUrl.ToString()},
|
||||
{ "directUrl", directMailMergeUrl.ToString()}
|
||||
{ "url", mailMergeUrl.ToString()}
|
||||
};
|
||||
|
||||
if (IsEnabledDirectUrl)
|
||||
{
|
||||
logoConfig.Add("directUrl", directMailMergeUrl.ToString());
|
||||
}
|
||||
|
||||
if (JwtManager.Enabled) // if the secret key to generate token exists
|
||||
{
|
||||
var token = JwtManager.Encode(logoConfig); // encode logoConfig into the token
|
||||
@ -437,10 +453,14 @@ namespace OnlineEditorsExampleMVC.Models
|
||||
var mailMergeConfig = new Dictionary<string, object>
|
||||
{
|
||||
{ "fileType", "csv" },
|
||||
{ "url", mailMergeUrl.ToString()},
|
||||
{ "directUrl", directMailMergeUrl.ToString()}
|
||||
{ "url", mailMergeUrl.ToString()}
|
||||
};
|
||||
|
||||
if (IsEnabledDirectUrl)
|
||||
{
|
||||
mailMergeConfig.Add("directUrl", directMailMergeUrl.ToString());
|
||||
}
|
||||
|
||||
if (JwtManager.Enabled) // if the secret key to generate token exists
|
||||
{
|
||||
var mailmergeToken = JwtManager.Encode(mailMergeConfig); // encode mailMergeConfig into the token
|
||||
|
||||
@ -16,11 +16,24 @@
|
||||
*
|
||||
*/
|
||||
|
||||
var directUrl;
|
||||
|
||||
if (typeof jQuery != "undefined") {
|
||||
jq = jQuery.noConflict();
|
||||
|
||||
directUrl = getUrlVars()["directUrl"] == "true";
|
||||
|
||||
mustReload = false;
|
||||
|
||||
if (directUrl)
|
||||
jq("#directUrl").prop("checked", directUrl);
|
||||
else
|
||||
directUrl = jq("#directUrl").prop("checked");
|
||||
|
||||
jq("#directUrl").change(function () {
|
||||
window.location = "?directUrl=" + jq(this).prop("checked");
|
||||
});
|
||||
|
||||
jq(function () {
|
||||
jq('#fileupload').fileupload({
|
||||
dataType: 'json',
|
||||
@ -219,7 +232,7 @@ if (typeof jQuery != "undefined") {
|
||||
|
||||
jq(document).on("click", "#beginEdit:not(.disable)", function () {
|
||||
var fileId = encodeURIComponent(jq('#hiddenFileName').val());
|
||||
var url = UrlEditor + "?fileName=" + fileId;
|
||||
var url = UrlEditor + "?fileName=" + fileId + "&directUrl=" + directUrl;
|
||||
window.open(url, "_blank");
|
||||
jq('#hiddenFileName').val("");
|
||||
jq.unblockUI();
|
||||
@ -227,7 +240,7 @@ if (typeof jQuery != "undefined") {
|
||||
|
||||
jq(document).on("click", "#beginView:not(.disable)", function () {
|
||||
var fileId = encodeURIComponent(jq('#hiddenFileName').val());
|
||||
var url = UrlEditor + "?editorsMode=view&fileName=" + fileId;
|
||||
var url = UrlEditor + "?editorsMode=view&fileName=" + fileId + "&directUrl=" + directUrl;
|
||||
window.open(url, "_blank");
|
||||
jq('#hiddenFileName').val("");
|
||||
jq.unblockUI();
|
||||
@ -235,7 +248,7 @@ if (typeof jQuery != "undefined") {
|
||||
|
||||
jq(document).on("click", "#beginEmbedded:not(.disable)", function () {
|
||||
var fileId = encodeURIComponent(jq('#hiddenFileName').val());
|
||||
var url = UrlEditor + "?editorsType=embedded&editorsMode=embedded&fileName=" + fileId;
|
||||
var url = UrlEditor + "?editorsType=embedded&editorsMode=embedded&fileName=" + fileId + "&directUrl=" + directUrl;
|
||||
|
||||
jq("#mainProgress").addClass("embedded");
|
||||
jq("#beginEmbedded").addClass("disable");
|
||||
@ -289,6 +302,17 @@ if (typeof jQuery != "undefined") {
|
||||
}
|
||||
};
|
||||
|
||||
function getUrlVars() {
|
||||
var vars = [], hash;
|
||||
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
|
||||
for (var i = 0; i < hashes.length; i++) {
|
||||
hash = hashes[i].split('=');
|
||||
vars.push(hash[0]);
|
||||
vars[hash[0]] = hash[1];
|
||||
}
|
||||
return vars;
|
||||
};
|
||||
|
||||
var fileList = jq("tr.tableRow");
|
||||
|
||||
var mouseIsOverTooltip = false;
|
||||
@ -299,12 +323,12 @@ if (typeof jQuery != "undefined") {
|
||||
if (hideTooltipTimeout != null) {
|
||||
clearTimeout(hideTooltipTimeout);
|
||||
}
|
||||
jq(".info").on("touchend", function () {
|
||||
jq("#info").on("touchend", function () {
|
||||
showUserTooltip(true);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
jq(".info").mouseover(function (event) {
|
||||
jq("#info").mouseover(function (event) {
|
||||
if (fileList.length > 0) {
|
||||
if (hideTooltipTimeout != null) {
|
||||
clearTimeout(hideTooltipTimeout);
|
||||
@ -328,4 +352,18 @@ if (typeof jQuery != "undefined") {
|
||||
}, 500);
|
||||
});
|
||||
}
|
||||
|
||||
jq(".info-tooltip").mouseover(function (event) {
|
||||
var target = event.target;
|
||||
var id = target.dataset.id ? target.dataset.id : target.id;
|
||||
var tooltip = target.dataset.tooltip;
|
||||
|
||||
jq("<div class='tooltip'>" + tooltip + "<div class='arrow'></div></div>").appendTo("body");
|
||||
|
||||
var top = jq("#" + id).offset().top + jq("#" + id).outerHeight() / 2 - jq("div.tooltip").outerHeight() / 2;
|
||||
var left = jq("#" + id).offset().left + jq("#" + id).outerWidth() + 20;
|
||||
jq("div.tooltip").css({ "top": top, "left": left });
|
||||
}).mouseout(function () {
|
||||
jq("div.tooltip").remove();
|
||||
});
|
||||
}
|
||||
@ -70,7 +70,7 @@
|
||||
<a class="try-editor form" data-type="docxf">Form template</a>
|
||||
</li>
|
||||
</ul>
|
||||
<label class="create-sample">
|
||||
<label class="side-option">
|
||||
<input id="createSample" class="checkbox" type="checkbox" />With sample content
|
||||
</label>
|
||||
</div>
|
||||
@ -86,7 +86,7 @@
|
||||
<tr>
|
||||
<td valign="middle">
|
||||
<span class="select-user">Username</span>
|
||||
<img class="info" src="content/images/info.svg" />
|
||||
<img id="info" class="info" src="content/images/info.svg" />
|
||||
<select class="select-user" id="user">
|
||||
<% foreach (User user in Users.getAllUsers())
|
||||
{ %>
|
||||
@ -97,7 +97,10 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="middle">
|
||||
<span class="select-user">Language editors interface</span>
|
||||
<span class="select-user">Language</span>
|
||||
<img class="info info-tooltip" data-id="language"
|
||||
data-tooltip="Choose the language for ONLYOFFICE editors interface"
|
||||
src="content/images/info.svg" />
|
||||
<select class="select-user" id="language">
|
||||
<% Dictionary<string, string> languages = DocManagerHelper.GetLanguages();
|
||||
foreach (var lang in languages)
|
||||
@ -107,6 +110,14 @@
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="middle">
|
||||
<label class="side-option">
|
||||
<input id="directUrl" type="checkbox" class="checkbox" />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="content/images/info.svg" />
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@ -156,7 +167,8 @@
|
||||
<tbody>
|
||||
<% foreach (var storedFile in storedFiles)
|
||||
{
|
||||
var editUrl = "doceditor.aspx?fileID=" + HttpUtility.UrlEncode(storedFile.Name);
|
||||
var isEnabledDirectUrl = DocManagerHelper.GetDirectUrl();
|
||||
var editUrl = "doceditor.aspx?fileID=" + HttpUtility.UrlEncode(storedFile.Name);
|
||||
var docType = FileUtility.GetFileType(storedFile.Name).ToString().ToLower();
|
||||
var ext = Path.GetExtension(storedFile.Name).ToLower();
|
||||
var canEdit = DocManagerHelper.EditedExts.Contains(ext);
|
||||
@ -165,42 +177,42 @@
|
||||
|
||||
<tr class="tableRow" title="<%= storedFile.Name %> [<%= DocManagerHelper.GetFileVersion(storedFile.Name, HttpContext.Current.Request.UserHostAddress.Replace(':', '_')) %>]">
|
||||
<td class="contentCells">
|
||||
<a class="stored-edit <%= docType %>" href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name }) %>" target="_blank">
|
||||
<a class="stored-edit <%= docType %>" href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, directUrl = isEnabledDirectUrl }) %>" target="_blank">
|
||||
<span><%= storedFile.Name %></span>
|
||||
</a>
|
||||
</td>
|
||||
<% if (canEdit) { %>
|
||||
<td class="contentCells contentCells-icon">
|
||||
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "edit" }) %>" target="_blank">
|
||||
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "edit", directUrl = isEnabledDirectUrl }) %>" target="_blank">
|
||||
<img src="content/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="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "mobile", editorsMode = "edit" }) %>" target="_blank">
|
||||
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "mobile", editorsMode = "edit", directUrl = isEnabledDirectUrl }) %>" target="_blank">
|
||||
<img src="content/images/mobile.svg" alt="Open in editor for mobile devices" title="Open in editor for mobile devices"/>
|
||||
</a>
|
||||
</td>
|
||||
<td class="contentCells contentCells-icon">
|
||||
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "comment" }) %>" target="_blank">
|
||||
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "comment", directUrl = isEnabledDirectUrl }) %>" target="_blank">
|
||||
<img src="content/images/comment.svg" alt="Open in editor for comment" title="Open in editor for comment"/>
|
||||
</a>
|
||||
</td>
|
||||
<% if (docType == "word") { %>
|
||||
<td class="contentCells contentCells-icon">
|
||||
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "review" }) %>" target="_blank">
|
||||
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "review", directUrl = isEnabledDirectUrl }) %>" target="_blank">
|
||||
<img src="content/images/review.svg" alt="Open in editor for review" title="Open in editor for review"/>
|
||||
</a>
|
||||
</td>
|
||||
<% } else if (docType == "cell") { %>
|
||||
<td class="contentCells contentCells-icon">
|
||||
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "filter" }) %>" target="_blank">
|
||||
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "filter", directUrl = isEnabledDirectUrl }) %>" target="_blank">
|
||||
<img src="content/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 (docType == "word") { %>
|
||||
<td class="contentCells contentCells-icon">
|
||||
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "blockcontent" }) %>" target="_blank">
|
||||
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "blockcontent", directUrl = isEnabledDirectUrl }) %>" target="_blank">
|
||||
<img src="content/images/block-content.svg" alt="Open in editor without content control modification" title="Open in editor without content control modification"/>
|
||||
</a>
|
||||
</td>
|
||||
@ -212,7 +224,7 @@
|
||||
<% } %>
|
||||
<% if (isFillFormDoc) { %>
|
||||
<td class="contentCells contentCells-shift contentCells-icon firstContentCellShift">
|
||||
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "fillForms" }) %>" target="_blank">
|
||||
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "fillForms", directUrl = isEnabledDirectUrl }) %>" target="_blank">
|
||||
<img src="content/images/fill-forms.svg" alt="Open in editor for filling in forms" title="Open in editor for filling in forms"/>
|
||||
</a>
|
||||
</td>
|
||||
@ -222,7 +234,7 @@
|
||||
<% } else if (isFillFormDoc) { %>
|
||||
<td class="contentCells contentCells-icon "></td>
|
||||
<td class="contentCells contentCells-icon">
|
||||
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "mobile", editorsMode = "fillForms" }) %>" target="_blank">
|
||||
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "mobile", editorsMode = "fillForms", directUrl = isEnabledDirectUrl }) %>" target="_blank">
|
||||
<img src="content/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>
|
||||
@ -230,7 +242,7 @@
|
||||
<td class="contentCells contentCells-icon "></td>
|
||||
<td class="contentCells contentCells-icon "></td>
|
||||
<td class="contentCells contentCells-shift contentCells-icon firstContentCellShift">
|
||||
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "fillForms" }) %>" target="_blank">
|
||||
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "fillForms", directUrl = isEnabledDirectUrl }) %>" target="_blank">
|
||||
<img src="content/images/fill-forms.svg" alt="Open in editor for filling in forms" title="Open in editor for filling in forms"/>
|
||||
</a>
|
||||
</td>
|
||||
@ -238,17 +250,17 @@
|
||||
<td class="contentCells contentCells-shift contentCells-icon contentCellsEmpty" colspan="6"></td>
|
||||
<% } %>
|
||||
<td class="contentCells contentCells-icon firstContentCellViewers">
|
||||
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "view" }) %>" target="_blank">
|
||||
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "desktop", editorsMode = "view", directUrl = isEnabledDirectUrl }) %>" target="_blank">
|
||||
<img src="content/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="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "mobile", editorsMode = "view" }) %>" target="_blank">
|
||||
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "mobile", editorsMode = "view", directUrl = isEnabledDirectUrl }) %>" target="_blank">
|
||||
<img src="content/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="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "embedded", editorsMode = "embedded" }) %>" target="_blank">
|
||||
<a href="<%= Url.Action("Editor", "Home", new { fileName = storedFile.Name, editorsType = "embedded", editorsMode = "embedded", directUrl = isEnabledDirectUrl }) %>" target="_blank">
|
||||
<img src="content/images/embeded.svg" alt="Open in embedded mode" title="Open in embedded mode"/>
|
||||
</a>
|
||||
</td>
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
|
||||
<add key="files.docservice.verify-peer-off" value="true"/>
|
||||
|
||||
<add key="files.docservice.languages" value="en:English|hy:Armenian|az:Azerbaijani|eu:Basque|be:Belarusian|bg:Bulgarian|ca:Catalan|zh:Chinese (People's Republic of China)|zh-TW:Chinese (Traditional, Taiwan)|cs:Czech|da:Danish|nl:Dutch|fi:Finnish|fr:French|gl:Galego|de:German|el:Greek|hu:Hungarian|id:Indonesian|it:Italian|ja:Japanese|ko:Korean|lv:Latvian|lo:Lao|ms:Malay (Malaysia)|nb:Norwegian|pl:Polish|pt:Portuguese (Brazil)|pt-PT:Portuguese (Portugal)|ro:Romanian|ru:Russian|sk:Slovak|sl:Slovenian|es:Spanish|sv:Swedish|tr:Turkish|uk:Ukrainian|vi:Vietnamese"/>
|
||||
<add key="files.docservice.languages" value="en:English|hy:Armenian|az:Azerbaijani|eu:Basque|be:Belarusian|bg:Bulgarian|ca:Catalan|zh:Chinese (People's Republic of China)|zh-TW:Chinese (Traditional, Taiwan)|cs:Czech|da:Danish|nl:Dutch|fi:Finnish|fr:French|gl:Galego|de:German|el:Greek|hu:Hungarian|id:Indonesian|it:Italian|ja:Japanese|ko:Korean|lv:Latvian|lo:Lao|ms:Malay (Malaysia)|nb:Norwegian|pl:Polish|pt:Portuguese (Brazil)|pt-PT:Portuguese (Portugal)|ro:Romanian|ru:Russian|sk:Slovak|sl:Slovenian|es:Spanish|sv:Swedish|tr:Turkish|uk:Ukrainian|vi:Vietnamese|aa-AA: Test Language"/>
|
||||
|
||||
<add key="files.docservice.url.site" value="http://documentserver/"/>
|
||||
|
||||
|
||||
@ -167,7 +167,7 @@ label .checkbox {
|
||||
background-image: url("images/file_docxf.svg");
|
||||
}
|
||||
|
||||
.create-sample {
|
||||
.side-option {
|
||||
color: #666666;
|
||||
line-height: 24px;
|
||||
}
|
||||
@ -744,3 +744,28 @@ html {
|
||||
.user-descr > b {
|
||||
margin-left: 25px;
|
||||
}
|
||||
|
||||
.tooltip {
|
||||
background: #FFFFFF;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0px 7px 25px rgba(85, 85, 85, 0.15);
|
||||
color: #666666;
|
||||
line-height: 160%;
|
||||
max-width: 455px;
|
||||
padding: 14px;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.tooltip ul {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.arrow {
|
||||
border-top: 8px solid transparent;
|
||||
border-bottom: 8px solid transparent;
|
||||
border-right: 8px solid #FFFFFF;
|
||||
left: -4px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
@ -73,7 +73,7 @@
|
||||
<a class="try-editor form" data-type="docxf">Form template</a>
|
||||
</li>
|
||||
</ul>
|
||||
<label class="create-sample">
|
||||
<label class="side-option">
|
||||
<input id="createSample" class="checkbox" type="checkbox" />With sample content
|
||||
</label>
|
||||
</div>
|
||||
@ -88,7 +88,7 @@
|
||||
<tr>
|
||||
<td valign="middle">
|
||||
<span class="select-user">Username</span>
|
||||
<img class="info" src="app_themes/images/info.svg" />
|
||||
<img id="info" class="info" src="app_themes/images/info.svg" />
|
||||
<select class="select-user" id="user">
|
||||
<% foreach (User user in Users.getAllUsers())
|
||||
{ %>
|
||||
@ -99,7 +99,10 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="middle">
|
||||
<span class="select-user">Language editors interface</span>
|
||||
<span class="select-user">Language</span>
|
||||
<img class="info info-tooltip" data-id="language"
|
||||
data-tooltip="Choose the language for ONLYOFFICE editors interface"
|
||||
src="app_themes/images/info.svg" />
|
||||
<select class="select-user" id="language">
|
||||
<% Dictionary<string, string> languages = GetLanguages();
|
||||
foreach (var lang in languages)
|
||||
@ -109,6 +112,14 @@
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="middle">
|
||||
<label class="side-option">
|
||||
<input id="directUrl" type="checkbox" class="checkbox" />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="app_themes/images/info.svg" />
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@ -158,7 +169,8 @@
|
||||
<tbody>
|
||||
<% foreach (var storedFile in storedFiles)
|
||||
{
|
||||
var editUrl = "doceditor.aspx?fileID=" + HttpUtility.UrlEncode(storedFile.Name);
|
||||
var directUrlParam = GetDirectUrlParam();
|
||||
var editUrl = "doceditor.aspx?fileID=" + HttpUtility.UrlEncode(storedFile.Name) + directUrlParam;
|
||||
var ext = Path.GetExtension(storedFile.Name).ToLower();
|
||||
var docType = DocumentType(storedFile.Name);
|
||||
var canEdit = EditedExts.Contains(ext);
|
||||
|
||||
@ -626,5 +626,11 @@ namespace OnlineEditorsExample
|
||||
}
|
||||
return languages;
|
||||
}
|
||||
|
||||
public static string GetDirectUrlParam()
|
||||
{
|
||||
string isEnabledDirectUrl = HttpUtility.ParseQueryString(HttpContext.Current.Request.Url.Query).Get("directUrl");
|
||||
return "&directUrl=" + (isEnabledDirectUrl != null ? isEnabledDirectUrl : "false");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -195,7 +195,7 @@ namespace OnlineEditorsExample
|
||||
{
|
||||
{ "title", FileName },
|
||||
{ "url", getDownloadUrl(FileName) },
|
||||
{ "directUrl", directUrl },
|
||||
{ "directUrl", IsEnabledDirectUrl() ? directUrl : "" },
|
||||
{ "fileType", ext.Trim('.') },
|
||||
{ "key", Key },
|
||||
{
|
||||
@ -377,7 +377,12 @@ namespace OnlineEditorsExample
|
||||
}
|
||||
|
||||
dataObj.Add("url", prevFileUrl); // write file url to the data object
|
||||
dataObj.Add("directUrl", directPrevFileUrl); // write direct url to the data object
|
||||
|
||||
if (IsEnabledDirectUrl())
|
||||
{
|
||||
dataObj.Add("directUrl", directPrevFileUrl); // write direct url to the data object
|
||||
}
|
||||
|
||||
dataObj.Add("version", i);
|
||||
if (i > 1) // check if the version number is greater than 1 (the file was modified)
|
||||
{
|
||||
@ -395,12 +400,19 @@ namespace OnlineEditorsExample
|
||||
obj.Add("user", change.Count > 0 ? change["user"] : null);
|
||||
|
||||
var prev = (Dictionary<string, object>)histData[(i - 2).ToString()]; // get the history data from the previous file version
|
||||
dataObj.Add("previous", new Dictionary<string, object>() { // write information about previous file version to the data object
|
||||
|
||||
Dictionary<string, object> dataPrev = new Dictionary<string, object>() { // write information about previous file version to the data object
|
||||
{ "fileType", prev["fileType"] },
|
||||
{ "key", prev["key"] }, // write key and url information about previous file version
|
||||
{ "url", prev["url"] },
|
||||
{ "directUrl", prev["directUrl"] },
|
||||
});
|
||||
{ "url", prev["url"] }
|
||||
};
|
||||
|
||||
if (IsEnabledDirectUrl())
|
||||
{
|
||||
dataPrev.Add("directUrl", prev["directUrl"]);
|
||||
}
|
||||
|
||||
dataObj.Add("previous", dataPrev);
|
||||
// write the path to the diff.zip archive with differences in this file version
|
||||
var changesUrl = MakePublicHistoryUrl(FileName, (i - 1).ToString(), "diff.zip");
|
||||
dataObj.Add("changesUrl", changesUrl);
|
||||
@ -442,10 +454,14 @@ namespace OnlineEditorsExample
|
||||
Dictionary<string, object> logoConfig = new Dictionary<string, object>
|
||||
{
|
||||
{ "fileType", "png"},
|
||||
{ "url", InsertImageUrl.ToString()},
|
||||
{ "directUrl", DirectImageUrl.ToString()}
|
||||
{ "url", InsertImageUrl.ToString()}
|
||||
};
|
||||
|
||||
if (IsEnabledDirectUrl())
|
||||
{
|
||||
logoConfig.Add("directUrl", DirectImageUrl.ToString());
|
||||
}
|
||||
|
||||
if (JwtManager.Enabled) // if the secret key to generate token exists
|
||||
{
|
||||
var insImageToken = JwtManager.Encode(logoConfig); // encode logoConfig into the token
|
||||
@ -475,10 +491,14 @@ namespace OnlineEditorsExample
|
||||
Dictionary<string, object> dataCompareFile = new Dictionary<string, object>
|
||||
{
|
||||
{ "fileType", "docx" },
|
||||
{ "url", compareFileUrl.ToString() },
|
||||
{ "directUrl", DirectFileUrl.ToString() }
|
||||
{ "url", compareFileUrl.ToString() }
|
||||
};
|
||||
|
||||
if (IsEnabledDirectUrl())
|
||||
{
|
||||
dataCompareFile.Add("directUrl", DirectFileUrl.ToString());
|
||||
}
|
||||
|
||||
if (JwtManager.Enabled) // if the secret key to generate token exists
|
||||
{
|
||||
var compareFileToken = JwtManager.Encode(dataCompareFile); // encode the dataCompareFile object into the token
|
||||
@ -510,10 +530,14 @@ namespace OnlineEditorsExample
|
||||
Dictionary<string, object> mailMergeConfig = new Dictionary<string, object>
|
||||
{
|
||||
{ "fileType", "csv" },
|
||||
{ "url", mailmergeUrl.ToString() },
|
||||
{ "directUrl", DirectMailMergeUrl.ToString() }
|
||||
{ "url", mailmergeUrl.ToString() }
|
||||
};
|
||||
|
||||
if (IsEnabledDirectUrl())
|
||||
{
|
||||
mailMergeConfig.Add("directUrl", DirectMailMergeUrl.ToString());
|
||||
}
|
||||
|
||||
if (JwtManager.Enabled) // if the secret key to generate token exists
|
||||
{
|
||||
var mailmergeToken = JwtManager.Encode(mailMergeConfig); // encode mailMergeConfig into the token
|
||||
@ -615,5 +639,12 @@ namespace OnlineEditorsExample
|
||||
{ "name", uname }
|
||||
}));
|
||||
}
|
||||
|
||||
// get direct url flag
|
||||
private static bool IsEnabledDirectUrl()
|
||||
{
|
||||
string isEnabledDirectUrl = HttpUtility.ParseQueryString(HttpContext.Current.Request.Url.Query).Get("directUrl");
|
||||
return isEnabledDirectUrl != null ? Convert.ToBoolean(isEnabledDirectUrl) : false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -324,6 +324,7 @@ namespace OnlineEditorsExample
|
||||
if (string.IsNullOrEmpty(path)) throw new ArgumentException("path"); // file isn't specified
|
||||
|
||||
var req = (HttpWebRequest)WebRequest.Create(url);
|
||||
req.Timeout = 5000;
|
||||
using (var stream = req.GetResponse().GetResponseStream()) // get input stream of the file information from the url
|
||||
{
|
||||
if (stream == null) throw new Exception("stream is null");
|
||||
|
||||
@ -16,11 +16,24 @@
|
||||
*
|
||||
*/
|
||||
|
||||
var directUrl;
|
||||
|
||||
if (typeof jQuery != "undefined") {
|
||||
jq = jQuery.noConflict();
|
||||
|
||||
directUrl = getUrlVars()["directUrl"] == "true";
|
||||
|
||||
mustReload = false;
|
||||
|
||||
if (directUrl)
|
||||
jq("#directUrl").prop("checked", directUrl);
|
||||
else
|
||||
directUrl = jq("#directUrl").prop("checked");
|
||||
|
||||
jq("#directUrl").change(function () {
|
||||
window.location = "?directUrl=" + jq(this).prop("checked");
|
||||
});
|
||||
|
||||
jq(function () {
|
||||
jq('#fileupload').fileupload({
|
||||
dataType: 'json',
|
||||
@ -219,7 +232,7 @@ if (typeof jQuery != "undefined") {
|
||||
|
||||
jq(document).on("click", "#beginEdit:not(.disable)", function () {
|
||||
var fileId = encodeURIComponent(jq('#hiddenFileName').val());
|
||||
var url = "doceditor.aspx?fileID=" + fileId;
|
||||
var url = "doceditor.aspx?fileID=" + fileId + "&directUrl=" + directUrl;
|
||||
window.open(url, "_blank");
|
||||
jq('#hiddenFileName').val("");
|
||||
jq.unblockUI();
|
||||
@ -227,7 +240,7 @@ if (typeof jQuery != "undefined") {
|
||||
|
||||
jq(document).on("click", "#beginView:not(.disable)", function () {
|
||||
var fileId = encodeURIComponent(jq('#hiddenFileName').val());
|
||||
var url = "doceditor.aspx?editorsMode=view&fileID=" + fileId;
|
||||
var url = "doceditor.aspx?editorsMode=view&fileID=" + fileId + "&directUrl=" + directUrl;
|
||||
window.open(url, "_blank");
|
||||
jq('#hiddenFileName').val("");
|
||||
jq.unblockUI();
|
||||
@ -235,7 +248,7 @@ if (typeof jQuery != "undefined") {
|
||||
|
||||
jq(document).on("click", "#beginEmbedded:not(.disable)", function () {
|
||||
var fileId = encodeURIComponent(jq('#hiddenFileName').val());
|
||||
var url = "doceditor.aspx?editorsType=embedded&editorsMode=embedded&fileID=" + fileId;
|
||||
var url = "doceditor.aspx?editorsType=embedded&editorsMode=embedded&fileID=" + fileId + "&directUrl=" + directUrl;
|
||||
|
||||
jq("#mainProgress").addClass("embedded");
|
||||
jq("#beginEmbedded").addClass("disable");
|
||||
@ -288,6 +301,17 @@ if (typeof jQuery != "undefined") {
|
||||
}
|
||||
};
|
||||
|
||||
function getUrlVars() {
|
||||
var vars = [], hash;
|
||||
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
|
||||
for (var i = 0; i < hashes.length; i++) {
|
||||
hash = hashes[i].split('=');
|
||||
vars.push(hash[0]);
|
||||
vars[hash[0]] = hash[1];
|
||||
}
|
||||
return vars;
|
||||
};
|
||||
|
||||
var fileList = jq("tr.tableRow");
|
||||
|
||||
var mouseIsOverTooltip = false;
|
||||
@ -298,12 +322,12 @@ if (typeof jQuery != "undefined") {
|
||||
if (hideTooltipTimeout != null) {
|
||||
clearTimeout(hideTooltipTimeout);
|
||||
}
|
||||
jq(".info").on("touchend", function () {
|
||||
jq("#info").on("touchend", function () {
|
||||
showUserTooltip(true);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
jq(".info").mouseover(function (event) {
|
||||
jq("#info").mouseover(function (event) {
|
||||
if (fileList.length > 0) {
|
||||
if (hideTooltipTimeout != null) {
|
||||
clearTimeout(hideTooltipTimeout);
|
||||
@ -327,4 +351,18 @@ if (typeof jQuery != "undefined") {
|
||||
}, 500);
|
||||
});
|
||||
}
|
||||
|
||||
jq(".info-tooltip").mouseover(function (event) {
|
||||
var target = event.target;
|
||||
var id = target.dataset.id ? target.dataset.id : target.id;
|
||||
var tooltip = target.dataset.tooltip;
|
||||
|
||||
jq("<div class='tooltip'>" + tooltip + "<div class='arrow'></div></div>").appendTo("body");
|
||||
|
||||
var top = jq("#" + id).offset().top + jq("#" + id).outerHeight() / 2 - jq("div.tooltip").outerHeight() / 2;
|
||||
var left = jq("#" + id).offset().left + jq("#" + id).outerWidth() + 20;
|
||||
jq("div.tooltip").css({ "top": top, "left": left });
|
||||
}).mouseout(function () {
|
||||
jq("div.tooltip").remove();
|
||||
});
|
||||
}
|
||||
@ -15,7 +15,7 @@
|
||||
<add key="files.docservice.header" value="Authorization" />
|
||||
<add key="files.docservice.verify-peer-off" value="true"/>
|
||||
|
||||
<add key="files.docservice.languages" value="en:English|hy:Armenian|az:Azerbaijani|eu:Basque|be:Belarusian|bg:Bulgarian|ca:Catalan|zh:Chinese (People's Republic of China)|zh-TW:Chinese (Traditional, Taiwan)|cs:Czech|da:Danish|nl:Dutch|fi:Finnish|fr:French|gl:Galego|de:German|el:Greek|hu:Hungarian|id:Indonesian|it:Italian|ja:Japanese|ko:Korean|lv:Latvian|lo:Lao|ms:Malay (Malaysia)|nb:Norwegian|pl:Polish|pt:Portuguese (Brazil)|pt-PT:Portuguese (Portugal)|ro:Romanian|ru:Russian|sk:Slovak|sl:Slovenian|es:Spanish|sv:Swedish|tr:Turkish|uk:Ukrainian|vi:Vietnamese"/>
|
||||
<add key="files.docservice.languages" value="en:English|hy:Armenian|az:Azerbaijani|eu:Basque|be:Belarusian|bg:Bulgarian|ca:Catalan|zh:Chinese (People's Republic of China)|zh-TW:Chinese (Traditional, Taiwan)|cs:Czech|da:Danish|nl:Dutch|fi:Finnish|fr:French|gl:Galego|de:German|el:Greek|hu:Hungarian|id:Indonesian|it:Italian|ja:Japanese|ko:Korean|lv:Latvian|lo:Lao|ms:Malay (Malaysia)|nb:Norwegian|pl:Polish|pt:Portuguese (Brazil)|pt-PT:Portuguese (Portugal)|ro:Romanian|ru:Russian|sk:Slovak|sl:Slovenian|es:Spanish|sv:Swedish|tr:Turkish|uk:Ukrainian|vi:Vietnamese|aa-AA: Test Language"/>
|
||||
|
||||
<add key="files.docservice.url.site" value="http://documentserver/"/>
|
||||
|
||||
|
||||
@ -61,10 +61,15 @@
|
||||
<version>1.18.20</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-core</artifactId>
|
||||
<version>2.13.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>2.12.6.1</version>
|
||||
<version>2.13.4.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.modelmapper</groupId>
|
||||
@ -78,6 +83,31 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
<version>2.17</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>validate</id>
|
||||
<phase>validate</phase>
|
||||
<configuration>
|
||||
<configLocation>google_checks.xml</configLocation>
|
||||
<encoding>UTF-8</encoding>
|
||||
<failsOnError>true</failsOnError>
|
||||
<failOnViolation>true</failOnViolation>
|
||||
<logViolationsToConsole>true</logViolationsToConsole>
|
||||
<violationSeverity>warning</violationSeverity>
|
||||
<consoleOutput>true</consoleOutput>
|
||||
<includeTestSourceDirectory>true
|
||||
</includeTestSourceDirectory>
|
||||
</configuration>
|
||||
<goals>
|
||||
<goal>check</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
||||
@ -26,7 +26,6 @@ import com.onlyoffice.integration.documentserver.models.enums.Action;
|
||||
import com.onlyoffice.integration.documentserver.storage.FileStoragePathBuilder;
|
||||
import com.onlyoffice.integration.entities.User;
|
||||
import com.onlyoffice.integration.dto.Mentions;
|
||||
import com.onlyoffice.integration.documentserver.models.enums.Language;
|
||||
import com.onlyoffice.integration.documentserver.models.enums.Type;
|
||||
import com.onlyoffice.integration.documentserver.models.filemodel.FileModel;
|
||||
import com.onlyoffice.integration.services.UserServices;
|
||||
@ -53,6 +52,9 @@ public class EditorController {
|
||||
@Value("${files.docservice.url.api}")
|
||||
private String docserviceApiUrl;
|
||||
|
||||
@Value("${files.docservice.languages}")
|
||||
private String langs;
|
||||
|
||||
@Autowired
|
||||
private FileStoragePathBuilder storagePathBuilder;
|
||||
|
||||
@ -77,16 +79,25 @@ public class EditorController {
|
||||
@RequestParam(value = "action", required = false) String actionParam,
|
||||
@RequestParam(value = "type", required = false) String typeParam,
|
||||
@RequestParam(value = "actionLink", required = false) String actionLink,
|
||||
@RequestParam(value = "directUrl", required = false, defaultValue = "false") Boolean directUrl,
|
||||
@CookieValue(value = "uid") String uid,
|
||||
@CookieValue(value = "ulang") String lang,
|
||||
Model model) throws JsonProcessingException {
|
||||
Action action = Action.edit;
|
||||
Type type = Type.desktop;
|
||||
Language language = Language.en;
|
||||
Locale locale = new Locale("en");
|
||||
|
||||
if(actionParam != null) action = Action.valueOf(actionParam);
|
||||
if(typeParam != null) type = Type.valueOf(typeParam);
|
||||
if(lang != null) language = Language.valueOf(lang);
|
||||
|
||||
List<String> langsAndKeys = Arrays.asList(langs.split("\\|"));
|
||||
for (String langAndKey : langsAndKeys) {
|
||||
String[] couple = langAndKey.split(":");
|
||||
if (couple[0].equals(lang)) {
|
||||
String[] langAndCountry = couple[0].split("-");
|
||||
locale = new Locale(langAndCountry[0], langAndCountry.length > 1 ? langAndCountry[1] : "");
|
||||
}
|
||||
}
|
||||
|
||||
Optional<User> optionalUser = userService.findUserById(Integer.parseInt(uid));
|
||||
|
||||
@ -101,10 +112,11 @@ public class EditorController {
|
||||
.builder()
|
||||
.fileName(fileName)
|
||||
.type(type)
|
||||
.lang(language)
|
||||
.lang(locale.toLanguageTag())
|
||||
.action(action)
|
||||
.user(user)
|
||||
.actionData(actionLink)
|
||||
.isEnableDirectUrl(directUrl)
|
||||
.build()
|
||||
);
|
||||
|
||||
@ -112,9 +124,9 @@ public class EditorController {
|
||||
model.addAttribute("model", fileModel); // add file model with the default parameters to the original model
|
||||
model.addAttribute("fileHistory", historyManager.getHistory(fileModel.getDocument())); // get file history and add it to the model
|
||||
model.addAttribute("docserviceApiUrl",docserviceSite + docserviceApiUrl); // create the document service api URL and add it to the model
|
||||
model.addAttribute("dataInsertImage", getInsertImage()); // get an image and add it to the model
|
||||
model.addAttribute("dataCompareFile", getCompareFile()); // get a document for comparison and add it to the model
|
||||
model.addAttribute("dataMailMergeRecipients", getMailMerge()); // get recipients data for mail merging and add it to the model
|
||||
model.addAttribute("dataInsertImage", getInsertImage(directUrl)); // get an image and add it to the model
|
||||
model.addAttribute("dataCompareFile", getCompareFile(directUrl)); // get a document for comparison and add it to the model
|
||||
model.addAttribute("dataMailMergeRecipients", getMailMerge(directUrl)); // get recipients data for mail merging and add it to the model
|
||||
model.addAttribute("usersForMentions", getUserMentions(uid)); // get user data for mentions and add it to the model
|
||||
return "editor.html";
|
||||
}
|
||||
@ -134,11 +146,13 @@ public class EditorController {
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private String getInsertImage() { // get an image that will be inserted into the document
|
||||
private String getInsertImage(Boolean directUrl) { // get an image that will be inserted into the document
|
||||
Map<String, Object> dataInsertImage = new HashMap<>();
|
||||
dataInsertImage.put("fileType", "png");
|
||||
dataInsertImage.put("url", storagePathBuilder.getServerUrl(true) + "/css/img/logo.png");
|
||||
dataInsertImage.put("directUrl", storagePathBuilder.getServerUrl(false) + "/css/img/logo.png");
|
||||
if (directUrl) {
|
||||
dataInsertImage.put("directUrl", storagePathBuilder.getServerUrl(false) + "/css/img/logo.png");
|
||||
}
|
||||
|
||||
// check if the document token is enabled
|
||||
if(jwtManager.tokenEnabled()){
|
||||
@ -149,11 +163,13 @@ public class EditorController {
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private String getCompareFile(){ // get a document that will be compared with the current document
|
||||
private String getCompareFile(Boolean directUrl) { // get a document that will be compared with the current document
|
||||
Map<String, Object> dataCompareFile = new HashMap<>();
|
||||
dataCompareFile.put("fileType", "docx");
|
||||
dataCompareFile.put("url", storagePathBuilder.getServerUrl(true) + "/assets?name=sample.docx");
|
||||
dataCompareFile.put("directUrl", storagePathBuilder.getServerUrl(false) + "/assets?name=sample.docx");
|
||||
if (directUrl) {
|
||||
dataCompareFile.put("directUrl", storagePathBuilder.getServerUrl(false) + "/assets?name=sample.docx");
|
||||
}
|
||||
|
||||
// check if the document token is enabled
|
||||
if(jwtManager.tokenEnabled()){
|
||||
@ -164,11 +180,13 @@ public class EditorController {
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private String getMailMerge(){
|
||||
private String getMailMerge(Boolean directUrl) {
|
||||
Map<String, Object> dataMailMergeRecipients = new HashMap<>(); // get recipients data for mail merging
|
||||
dataMailMergeRecipients.put("fileType", "csv");
|
||||
dataMailMergeRecipients.put("url", storagePathBuilder.getServerUrl(true) + "/csv");
|
||||
dataMailMergeRecipients.put("directUrl", storagePathBuilder.getServerUrl(false) + "/csv");
|
||||
if (directUrl) {
|
||||
dataMailMergeRecipients.put("directUrl", storagePathBuilder.getServerUrl(false) + "/csv");
|
||||
}
|
||||
|
||||
// check if the document token is enabled
|
||||
if(jwtManager.tokenEnabled()){
|
||||
|
||||
@ -68,7 +68,8 @@ public class IndexController {
|
||||
private String langs;
|
||||
|
||||
@GetMapping("${url.index}")
|
||||
public String index(Model model){
|
||||
public String index(@RequestParam(value = "directUrl", required = false) Boolean directUrl,
|
||||
Model model){
|
||||
java.io.File[] files = storageMutator.getStoredFiles(); // get all the stored files from the storage
|
||||
List<String> docTypes = new ArrayList<>();
|
||||
List<Boolean> filesEditable = new ArrayList<>();
|
||||
@ -107,6 +108,7 @@ public class IndexController {
|
||||
model.addAttribute("tooltip", tooltip);
|
||||
model.addAttribute("users", users);
|
||||
model.addAttribute("languages", languages);
|
||||
model.addAttribute("directUrl", directUrl);
|
||||
|
||||
return "index.html";
|
||||
}
|
||||
|
||||
@ -76,8 +76,15 @@ public class DefaultCallbackManager implements CallbackManager {
|
||||
|
||||
URL uri = new URL(url);
|
||||
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) uri.openConnection();
|
||||
connection.setConnectTimeout(5000);
|
||||
InputStream stream = connection.getInputStream(); // get input stream of the file information from the URL
|
||||
|
||||
int statusCode = connection.getResponseCode();
|
||||
if (statusCode != 200) { // checking status code
|
||||
connection.disconnect();
|
||||
throw new RuntimeException("Document editing service returned status: " + statusCode);
|
||||
}
|
||||
|
||||
if (stream == null) {
|
||||
connection.disconnect();
|
||||
throw new RuntimeException("Input stream is null");
|
||||
|
||||
@ -91,8 +91,10 @@ public class DefaultHistoryManager implements HistoryManager {
|
||||
dataObj.put("key", key);
|
||||
dataObj.put("url", i == curVer ? document.getUrl() :
|
||||
documentManager.getHistoryFileUrl(document.getTitle(), i, "prev" + fileUtility.getFileExtension(document.getTitle()), true));
|
||||
dataObj.put("directUrl", i == curVer ? document.getDirectUrl() :
|
||||
documentManager.getHistoryFileUrl(document.getTitle(), i, "prev" + fileUtility.getFileExtension(document.getTitle()), false));
|
||||
if (!document.getDirectUrl().equals("")) {
|
||||
dataObj.put("directUrl", i == curVer ? document.getDirectUrl() :
|
||||
documentManager.getHistoryFileUrl(document.getTitle(), i, "prev" + fileUtility.getFileExtension(document.getTitle()), false));
|
||||
}
|
||||
dataObj.put("version", i);
|
||||
|
||||
if (i > 1) { //check if the version number is greater than 1
|
||||
@ -111,7 +113,9 @@ public class DefaultHistoryManager implements HistoryManager {
|
||||
prevInfo.put("fileType", prev.get("fileType"));
|
||||
prevInfo.put("key", prev.get("key")); // write key and URL information about previous file version
|
||||
prevInfo.put("url", prev.get("url"));
|
||||
prevInfo.put("directUrl", prev.get("directUrl"));
|
||||
if (!document.getDirectUrl().equals("")) {
|
||||
prevInfo.put("directUrl", prev.get("directUrl"));
|
||||
}
|
||||
dataObj.put("previous", prevInfo); // write information about previous file version to the data object
|
||||
// write the path to the diff.zip archive with differences in this file version
|
||||
Integer verdiff = i - 1;
|
||||
|
||||
@ -1,55 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* (c) Copyright Ascensio System SIA 2021
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.onlyoffice.integration.documentserver.models.enums;
|
||||
|
||||
public enum Language {
|
||||
en,
|
||||
de,
|
||||
ru,
|
||||
pl,
|
||||
be,
|
||||
bg,
|
||||
ca,
|
||||
zh,
|
||||
cs,
|
||||
da,
|
||||
nl,
|
||||
fi,
|
||||
fr,
|
||||
el,
|
||||
hu,
|
||||
id,
|
||||
it,
|
||||
ja,
|
||||
ko,
|
||||
lv,
|
||||
lo,
|
||||
nb,
|
||||
pt,
|
||||
ro,
|
||||
sk,
|
||||
sl,
|
||||
sv,
|
||||
es,
|
||||
tr,
|
||||
uk,
|
||||
vi,
|
||||
gl,
|
||||
az
|
||||
}
|
||||
@ -20,7 +20,6 @@ package com.onlyoffice.integration.documentserver.models.filemodel;
|
||||
|
||||
import com.onlyoffice.integration.documentserver.models.configurations.Customization;
|
||||
import com.onlyoffice.integration.documentserver.models.configurations.Embedded;
|
||||
import com.onlyoffice.integration.documentserver.models.enums.Language;
|
||||
import com.onlyoffice.integration.documentserver.models.enums.Mode;
|
||||
import lombok.*;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -44,7 +43,7 @@ public class EditorConfig { // the parameters pertaining to the editor interfac
|
||||
private Customization customization; // the parameters which allow to customize the editor interface so that it looked like your other products (if there are any) and change the presence or absence of the additional buttons, links, change logos and editor owner details
|
||||
@Autowired
|
||||
private Embedded embedded; // the parameters which allow to change the settings which define the behavior of the buttons in the embedded mode
|
||||
private Language lang; // the editor interface language
|
||||
private String lang; // the editor interface language
|
||||
private Mode mode; // the editor opening mode
|
||||
@Autowired
|
||||
private User user; // the user currently viewing or editing the document
|
||||
|
||||
@ -95,6 +95,13 @@ public class DefaultServiceConverter implements ServiceConverter
|
||||
}
|
||||
|
||||
connection.connect();
|
||||
|
||||
int statusCode = connection.getResponseCode();
|
||||
if (statusCode != 200) { // checking status code
|
||||
connection.disconnect();
|
||||
throw new RuntimeException("Convertation service returned status: " + statusCode);
|
||||
}
|
||||
|
||||
try (OutputStream os = connection.getOutputStream()) {
|
||||
os.write(bodyByte); // write bytes to the output stream
|
||||
os.flush(); // force write data to the output stream that can be cached in the current thread
|
||||
|
||||
@ -55,7 +55,7 @@ public class DefaultDocumentConfigurer implements DocumentConfigurer<DefaultDocu
|
||||
document.setTitle(fileName); // set the title to the document config
|
||||
document.setUrl(documentManager.getDownloadUrl(fileName, true)); // set the URL to download a file to the document config
|
||||
document.setUrlUser(documentManager.getFileUri(fileName, false)); // set the file URL to the document config
|
||||
document.setDirectUrl(documentManager.getDownloadUrl(fileName, false));
|
||||
document.setDirectUrl(wrapper.getIsEnableDirectUrl() ? documentManager.getDownloadUrl(fileName, false) : "");
|
||||
document.setFileType(fileUtility.getFileExtension(fileName).replace(".","")); // set the file type to the document config
|
||||
document.getInfo().setFavorite(wrapper.getFavorite()); // set the favorite parameter to the document config
|
||||
|
||||
|
||||
@ -80,6 +80,7 @@ public class DefaultFileConfigurer implements FileConfigurer<DefaultFileWrapper>
|
||||
.fileName(fileName)
|
||||
.permission(updatePermissions(userPermissions, action, canEdit))
|
||||
.favorite(wrapper.getUser().getFavorite())
|
||||
.isEnableDirectUrl(wrapper.getIsEnableDirectUrl())
|
||||
.build();
|
||||
|
||||
defaultDocumentConfigurer.configure(fileModel.getDocument(), documentWrapper); // define the document configurer
|
||||
|
||||
@ -28,4 +28,5 @@ public class DefaultDocumentWrapper {
|
||||
private Permission permission;
|
||||
private String fileName;
|
||||
private Boolean favorite;
|
||||
private Boolean isEnableDirectUrl;
|
||||
}
|
||||
|
||||
@ -20,7 +20,6 @@ package com.onlyoffice.integration.services.configurers.wrappers;
|
||||
|
||||
import com.onlyoffice.integration.documentserver.models.enums.Action;
|
||||
import com.onlyoffice.integration.entities.User;
|
||||
import com.onlyoffice.integration.documentserver.models.enums.Language;
|
||||
import com.onlyoffice.integration.documentserver.models.enums.Type;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
@ -33,8 +32,9 @@ public class DefaultFileWrapper {
|
||||
private String fileName;
|
||||
private Type type;
|
||||
private User user;
|
||||
private Language lang;
|
||||
private String lang;
|
||||
private Action action;
|
||||
private String actionData;
|
||||
private Boolean canEdit;
|
||||
private Boolean isEnableDirectUrl;
|
||||
}
|
||||
|
||||
@ -27,7 +27,7 @@ files.docservice.header=Authorization
|
||||
|
||||
files.docservice.verify-peer-off=true
|
||||
|
||||
files.docservice.languages=en:English|hy:Armenian|az:Azerbaijani|eu:Basque|be:Belarusian|bg:Bulgarian|ca:Catalan|zh:Chinese (People's Republic of China)|zh-TW:Chinese (Traditional, Taiwan)|cs:Czech|da:Danish|nl:Dutch|fi:Finnish|fr:French|gl:Galego|de:German|el:Greek|hu:Hungarian|id:Indonesian|it:Italian|ja:Japanese|ko:Korean|lv:Latvian|lo:Lao|ms:Malay (Malaysia)|nb:Norwegian|pl:Polish|pt:Portuguese (Brazil)|pt-PT:Portuguese (Portugal)|ro:Romanian|ru:Russian|sk:Slovak|sl:Slovenian|es:Spanish|sv:Swedish|tr:Turkish|uk:Ukrainian|vi:Vietnamese
|
||||
files.docservice.languages=en:English|hy:Armenian|az:Azerbaijani|eu:Basque|be:Belarusian|bg:Bulgarian|ca:Catalan|zh:Chinese (People's Republic of China)|zh-TW:Chinese (Traditional, Taiwan)|cs:Czech|da:Danish|nl:Dutch|fi:Finnish|fr:French|gl:Galego|de:German|el:Greek|hu:Hungarian|id:Indonesian|it:Italian|ja:Japanese|ko:Korean|lv:Latvian|lo:Lao|ms:Malay (Malaysia)|nb:Norwegian|pl:Polish|pt:Portuguese (Brazil)|pt-PT:Portuguese (Portugal)|ro:Romanian|ru:Russian|sk:Slovak|sl:Slovenian|es:Spanish|sv:Swedish|tr:Turkish|uk:Ukrainian|vi:Vietnamese|aa-AA:Test Language
|
||||
|
||||
spring.datasource.url=jdbc:h2:mem:usersdb
|
||||
spring.datasource.driverClassName=org.h2.Driver
|
||||
|
||||
@ -167,7 +167,7 @@ label .checkbox {
|
||||
background-image: url("img/file_docxf.svg");
|
||||
}
|
||||
|
||||
.create-sample {
|
||||
.side-option {
|
||||
color: #666666;
|
||||
line-height: 24px;
|
||||
}
|
||||
@ -751,3 +751,28 @@ html {
|
||||
.user-descr > b {
|
||||
margin-left: 25px;
|
||||
}
|
||||
|
||||
.tooltip {
|
||||
background: #FFFFFF;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0px 7px 25px rgba(85, 85, 85, 0.15);
|
||||
color: #666666;
|
||||
line-height: 160%;
|
||||
max-width: 455px;
|
||||
padding: 14px;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.tooltip ul {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.arrow {
|
||||
border-top: 8px solid transparent;
|
||||
border-bottom: 8px solid transparent;
|
||||
border-right: 8px solid #FFFFFF;
|
||||
left: -4px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
@ -16,11 +16,24 @@
|
||||
*
|
||||
*/
|
||||
|
||||
var directUrl;
|
||||
|
||||
if (typeof jQuery !== "undefined") {
|
||||
jq = jQuery.noConflict();
|
||||
|
||||
directUrl = getUrlVars()["directUrl"] == "true";
|
||||
|
||||
mustReload = false;
|
||||
|
||||
if (directUrl)
|
||||
jq("#directUrl").prop("checked", directUrl);
|
||||
else
|
||||
directUrl = jq("#directUrl").prop("checked");
|
||||
|
||||
jq("#directUrl").change(function() {
|
||||
window.location = "?directUrl=" + jq(this).prop("checked");
|
||||
});
|
||||
|
||||
jq(function () {
|
||||
jq("#fileupload").fileupload({
|
||||
dataType: "json",
|
||||
@ -228,7 +241,7 @@ if (typeof jQuery !== "undefined") {
|
||||
|
||||
jq(document).on("click", "#beginEdit:not(.disable)", function () {
|
||||
var fileId = encodeURIComponent(jq("#hiddenFileName").val());
|
||||
var url = UrlEditor + "?action=edit&fileName=" + fileId;
|
||||
var url = UrlEditor + "?action=edit&fileName=" + fileId + "&directUrl=" + directUrl;
|
||||
window.open(url, "_blank");
|
||||
jq("#hiddenFileName").val("");
|
||||
jq.unblockUI();
|
||||
@ -236,7 +249,7 @@ if (typeof jQuery !== "undefined") {
|
||||
|
||||
jq(document).on("click", "#beginView:not(.disable)", function () {
|
||||
var fileId = encodeURIComponent(jq("#hiddenFileName").val());
|
||||
var url = UrlEditor + "?action=view&fileName=" + fileId;
|
||||
var url = UrlEditor + "?action=view&fileName=" + fileId + "&directUrl=" + directUrl;
|
||||
window.open(url, "_blank");
|
||||
jq("#hiddenFileName").val("");
|
||||
jq.unblockUI();
|
||||
@ -244,7 +257,7 @@ if (typeof jQuery !== "undefined") {
|
||||
|
||||
jq(document).on("click", "#beginEmbedded:not(.disable)", function () {
|
||||
var fileId = encodeURIComponent(jq("#hiddenFileName").val());
|
||||
var url = UrlEditor + "?type=embedded&action=embedded&fileName=" + fileId;
|
||||
var url = UrlEditor + "?type=embedded&action=embedded&fileName=" + fileId + "&directUrl=" + directUrl;
|
||||
|
||||
jq("#mainProgress").addClass("embedded");
|
||||
jq("#beginEmbedded").addClass("disable");
|
||||
@ -300,6 +313,17 @@ if (typeof jQuery !== "undefined") {
|
||||
}
|
||||
};
|
||||
|
||||
function getUrlVars() {
|
||||
var vars = [], hash;
|
||||
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
|
||||
for (var i = 0; i < hashes.length; i++) {
|
||||
hash = hashes[i].split('=');
|
||||
vars.push(hash[0]);
|
||||
vars[hash[0]] = hash[1];
|
||||
}
|
||||
return vars;
|
||||
};
|
||||
|
||||
jq("#portal-info")[0].innerHTML += jq("#portal-info")[0].attributes.tooltip.value;
|
||||
|
||||
var fileList = jq("tr.tableRow");
|
||||
@ -312,12 +336,12 @@ if (typeof jQuery !== "undefined") {
|
||||
if (hideTooltipTimeout != null) {
|
||||
clearTimeout(hideTooltipTimeout);
|
||||
}
|
||||
jq(".info").on("touchend", function () {
|
||||
jq("#info").on("touchend", function () {
|
||||
showUserTooltip(true);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
jq(".info").mouseover(function (event) {
|
||||
jq("#info").mouseover(function (event) {
|
||||
if (fileList.length > 0) {
|
||||
if (hideTooltipTimeout != null) {
|
||||
clearTimeout(hideTooltipTimeout);
|
||||
@ -342,4 +366,18 @@ if (typeof jQuery !== "undefined") {
|
||||
});
|
||||
}
|
||||
|
||||
jq(".info-tooltip").mouseover(function (event) {
|
||||
var target = event.target;
|
||||
var id = target.dataset.id ? target.dataset.id : target.id;
|
||||
var tooltip = target.dataset.tooltip;
|
||||
|
||||
jq("<div class='tooltip'>" + tooltip + "<div class='arrow'></div></div>").appendTo("body");
|
||||
|
||||
var top = jq("#" + id).offset().top + jq("#" + id).outerHeight() / 2 - jq("div.tooltip").outerHeight() / 2;
|
||||
var left = jq("#" + id).offset().left + jq("#" + id).outerWidth() + 20;
|
||||
jq("div.tooltip").css({"top": top, "left": left});
|
||||
}).mouseout(function () {
|
||||
jq("div.tooltip").remove();
|
||||
});
|
||||
|
||||
}
|
||||
@ -59,7 +59,7 @@
|
||||
<a class="try-editor form" data-type="docxf">Form template</a>
|
||||
</li>
|
||||
</ul>
|
||||
<label class="create-sample">
|
||||
<label class="side-option">
|
||||
<input id="createSample" class="checkbox" type="checkbox" />With sample content
|
||||
</label>
|
||||
</div>
|
||||
@ -75,7 +75,7 @@
|
||||
<tr>
|
||||
<td valign="middle">
|
||||
<span class="select-user">Username</span>
|
||||
<img class="info" src="css/img/info.svg"/>
|
||||
<img id="info" class="info" src="css/img/info.svg"/>
|
||||
<select class="select-user" id="user">
|
||||
<option th:each="user : ${users}"
|
||||
th:value="${user.id}"
|
||||
@ -85,7 +85,10 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="middle">
|
||||
<span class="select-user">Language editors interface</span>
|
||||
<span class="select-user">Language</span>
|
||||
<img class="info info-tooltip" data-id="language"
|
||||
data-tooltip="Choose the language for ONLYOFFICE editors interface"
|
||||
src="css/img/info.svg" />
|
||||
<select class="select-user" id="language">
|
||||
<option th:each="language: ${languages}"
|
||||
th:value="${language.key}"
|
||||
@ -93,6 +96,14 @@
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="middle">
|
||||
<label class="side-option">
|
||||
<input id="directUrl" type="checkbox" class="checkbox" />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="css/img/info.svg" />
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@ -129,43 +140,50 @@
|
||||
<tr th:each="file,iState : ${files}" class="tableRow" th:title="${files[iState.index].getName() + versions[iState.index]}">
|
||||
<td class="contentCells">
|
||||
<a class="stored-edit" th:classappend="${docTypes[iState.index]}"
|
||||
th:href="@{/editor(fileName=${files[iState.index].getName()})}" target="_blank">
|
||||
th:with="directUrl=${directUrl}"
|
||||
th:href="@{/editor(fileName=${files[iState.index].getName()}, __(${#strings.isEmpty(directUrl)} ? '' : ('directUrl=' + ${directUrl}))__)}" target="_blank">
|
||||
<span th:text="${files[iState.index].getName()}"></span>
|
||||
</a>
|
||||
</td>
|
||||
<th:block th:if="${filesEditable[iState.index]}">
|
||||
<td class="contentCells contentCells-icon">
|
||||
<a th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='edit')}" target="_blank">
|
||||
<a th:with="directUrl=${directUrl}"
|
||||
th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='edit', __(${#strings.isEmpty(directUrl)} ? '' : ('directUrl=' + ${directUrl}))__)}" target="_blank">
|
||||
<img src="css/img/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 th:href="@{/editor(fileName=${files[iState.index].getName()},type='mobile',action='edit')}" target="_blank">
|
||||
<a th:with="directUrl=${directUrl}"
|
||||
th:href="@{/editor(fileName=${files[iState.index].getName()},type='mobile',action='edit', __(${#strings.isEmpty(directUrl)} ? '' : ('directUrl=' + ${directUrl}))__)}" target="_blank">
|
||||
<img src="css/img/mobile.svg" alt="Open in editor for mobile devices" title="Open in editor for mobile devices"/>
|
||||
</a>
|
||||
</td>
|
||||
<td class="contentCells contentCells-icon">
|
||||
<a th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='comment')}" target="_blank">
|
||||
<a th:with="directUrl=${directUrl}"
|
||||
th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='comment', __(${#strings.isEmpty(directUrl)} ? '' : ('directUrl=' + ${directUrl}))__)}" target="_blank">
|
||||
<img src="css/img/comment.svg" alt="Open in editor for comment" title="Open in editor for comment"/>
|
||||
</a>
|
||||
</td>
|
||||
<div th:if="${docTypes[iState.index]} eq 'word'">
|
||||
<td class="contentCells contentCells-icon">
|
||||
<a th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='review')}" target="_blank">
|
||||
<a th:with="directUrl=${directUrl}"
|
||||
th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='review', __(${#strings.isEmpty(directUrl)} ? '' : ('directUrl=' + ${directUrl}))__)}" target="_blank">
|
||||
<img src="css/img/review.svg" alt="Open in editor for review" title="Open in editor for review"/>
|
||||
</a>
|
||||
</td>
|
||||
</div>
|
||||
<div th:if="${docTypes[iState.index]} eq 'cell'">
|
||||
<td class="contentCells contentCells-icon">
|
||||
<a th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='filter')}" target="_blank">
|
||||
<a th:with="directUrl=${directUrl}"
|
||||
th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='filter', __(${#strings.isEmpty(directUrl)} ? '' : ('directUrl=' + ${directUrl}))__)}" target="_blank">
|
||||
<img src="css/img/filter.svg" alt="Open in editor without access to change the filter" title="Open in editor without access to change the filter" />
|
||||
</a>
|
||||
</td>
|
||||
</div>
|
||||
<div th:if="${docTypes[iState.index]} eq 'word'">
|
||||
<td class="contentCells contentCells-icon">
|
||||
<a th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='blockcontent')}" target="_blank">
|
||||
<a th:with="directUrl=${directUrl}"
|
||||
th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='blockcontent', __(${#strings.isEmpty(directUrl)} ? '' : ('directUrl=' + ${directUrl}))__)}" target="_blank">
|
||||
<img src="css/img/block-content.svg" alt="Open in editor without content control modification" title="Open in editor without content control modification"/>
|
||||
</a>
|
||||
</td>
|
||||
@ -178,7 +196,8 @@
|
||||
</div>
|
||||
<div th:if="${isFillFormDoc[iState.index]}">
|
||||
<td class="contentCells contentCells-shift contentCells-icon firstContentCellShift">
|
||||
<a th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='fillForms')}" target="_blank">
|
||||
<a th:with="directUrl=${directUrl}"
|
||||
th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='fillForms', __(${#strings.isEmpty(directUrl)} ? '' : ('directUrl=' + ${directUrl}))__)}" target="_blank">
|
||||
<img src="css/img/fill-forms.svg" alt="Open in editor for filling in forms" title="Open in editor for filling in forms"/>
|
||||
</a>
|
||||
</td>
|
||||
@ -190,7 +209,8 @@
|
||||
<th:block th:if="${isFillFormDoc[iState.index] and not filesEditable[iState.index]}">
|
||||
<td class="contentCells contentCells-icon "></td>
|
||||
<td class="contentCells contentCells-icon">
|
||||
<a th:href="@{/editor(fileName=${files[iState.index].getName()},type='mobile',action='fillForms')}" target="_blank">
|
||||
<a th:with="directUrl=${directUrl}"
|
||||
th:href="@{/editor(fileName=${files[iState.index].getName()},type='mobile',action='fillForms', __(${#strings.isEmpty(directUrl)} ? '' : ('directUrl=' + ${directUrl}))__)}" target="_blank">
|
||||
<img src="css/img/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>
|
||||
@ -198,7 +218,8 @@
|
||||
<td class="contentCells contentCells-icon "></td>
|
||||
<td class="contentCells contentCells-icon "></td>
|
||||
<td class="contentCells contentCells-shift contentCells-icon firstContentCellShift">
|
||||
<a th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='fillForms')}" target="_blank">
|
||||
<a th:with="directUrl=${directUrl}"
|
||||
th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='fillForms', __(${#strings.isEmpty(directUrl)} ? '' : ('directUrl=' + ${directUrl}))__)}" target="_blank">
|
||||
<img src="css/img/fill-forms.svg" alt="Open in editor for filling in forms" title="Open in editor for filling in forms"/>
|
||||
</a>
|
||||
</td>
|
||||
@ -207,17 +228,20 @@
|
||||
<td class="contentCells contentCells-shift contentCells-icon contentCellsEmpty" colspan="6"></td>
|
||||
</th:block>
|
||||
<td class="contentCells contentCells-icon firstContentCellViewers">
|
||||
<a th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='view')}" target="_blank">
|
||||
<a th:with="directUrl=${directUrl}"
|
||||
th:href="@{/editor(fileName=${files[iState.index].getName()},type='desktop',action='view', __(${#strings.isEmpty(directUrl)} ? '' : ('directUrl=' + ${directUrl}))__)}" target="_blank">
|
||||
<img src="css/img/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 th:href="@{/editor(fileName=${files[iState.index].getName()},type='mobile',action='view')}" target="_blank">
|
||||
<a th:with="directUrl=${directUrl}"
|
||||
th:href="@{/editor(fileName=${files[iState.index].getName()},type='mobile',action='view', __(${#strings.isEmpty(directUrl)} ? '' : ('directUrl=' + ${directUrl}))__)}" target="_blank">
|
||||
<img src="css/img/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 th:href="@{/editor(fileName=${files[iState.index].getName()},type='embedded',action='embedded')}" target="_blank">
|
||||
<a th:with="directUrl=${directUrl}"
|
||||
th:href="@{/editor(fileName=${files[iState.index].getName()},type='embedded',action='embedded', __(${#strings.isEmpty(directUrl)} ? '' : ('directUrl=' + ${directUrl}))__)}" target="_blank">
|
||||
<img src="css/img/embeded.svg" alt="Open in embedded mode" title="Open in embedded mode"/>
|
||||
</a>
|
||||
</td>
|
||||
@ -318,8 +342,19 @@
|
||||
<script type="text/javascript" src="scripts/jscript.js"></script>
|
||||
<script type="text/javascript" src="scripts/converter.js"></script>
|
||||
<script type="text/javascript">
|
||||
document.addEventListener('DOMContentLoaded', function(){
|
||||
document.getElementById("language").value="en";
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
var lang = document.cookie
|
||||
.split('; ')
|
||||
.find((row) => row.startsWith('ulang='))
|
||||
?.split('=')[1];
|
||||
|
||||
var languages = Array.from(document.getElementById("language").options).map(e => e.value)
|
||||
|
||||
if (!languages.includes(lang)) {
|
||||
lang = "en";
|
||||
}
|
||||
|
||||
document.getElementById("language").value=lang;
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
@ -85,6 +85,31 @@
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
<version>2.17</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>validate</id>
|
||||
<phase>validate</phase>
|
||||
<configuration>
|
||||
<configLocation>google_checks.xml</configLocation>
|
||||
<encoding>UTF-8</encoding>
|
||||
<failsOnError>true</failsOnError>
|
||||
<failOnViolation>true</failOnViolation>
|
||||
<logViolationsToConsole>true</logViolationsToConsole>
|
||||
<violationSeverity>warning</violationSeverity>
|
||||
<consoleOutput>true</consoleOutput>
|
||||
<includeTestSourceDirectory>true
|
||||
</includeTestSourceDirectory>
|
||||
</configuration>
|
||||
<goals>
|
||||
<goal>check</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
@ -47,6 +47,7 @@ public class EditorServlet extends HttpServlet
|
||||
String fileName = FileUtility.GetFileName(request.getParameter("fileName"));
|
||||
String fileExt = request.getParameter("fileExt");
|
||||
String sample = request.getParameter("sample");
|
||||
Boolean isEnableDirectUrl = Boolean.valueOf(request.getParameter("directUrl"));
|
||||
|
||||
// check if there is sample data in the request
|
||||
Boolean sampleData = (sample == null || sample.isEmpty()) ? false : sample.toLowerCase().equals("true");
|
||||
@ -70,7 +71,7 @@ public class EditorServlet extends HttpServlet
|
||||
}
|
||||
|
||||
// create file model (get all the necessary parameters from cookies)
|
||||
FileModel file = new FileModel(fileName, cm.getCookie("ulang"), request.getParameter("actionLink"), user);
|
||||
FileModel file = new FileModel(fileName, cm.getCookie("ulang"), request.getParameter("actionLink"), user, isEnableDirectUrl);
|
||||
// change type parameter if needed
|
||||
file.changeType(request.getParameter("mode"), request.getParameter("type"), user, fileName);
|
||||
|
||||
@ -78,19 +79,25 @@ public class EditorServlet extends HttpServlet
|
||||
Map<String, Object> dataInsertImage = new HashMap<>();
|
||||
dataInsertImage.put("fileType", "png");
|
||||
dataInsertImage.put("url", DocumentManager.GetServerUrl(true) + "/css/img/logo.png");
|
||||
dataInsertImage.put("directUrl", DocumentManager.GetServerUrl(false) + "/css/img/logo.png");
|
||||
if (isEnableDirectUrl) {
|
||||
dataInsertImage.put("directUrl", DocumentManager.GetServerUrl(false) + "/css/img/logo.png");
|
||||
}
|
||||
|
||||
// a document that will be compared with the current document
|
||||
Map<String, Object> dataCompareFile = new HashMap<>();
|
||||
dataCompareFile.put("fileType", "docx");
|
||||
dataCompareFile.put("url", DocumentManager.GetServerUrl(true) + "/IndexServlet?type=assets&name=sample.docx");
|
||||
dataCompareFile.put("directUrl", DocumentManager.GetServerUrl(false) + "/IndexServlet?type=assets&name=sample.docx");
|
||||
if (isEnableDirectUrl) {
|
||||
dataCompareFile.put("directUrl", DocumentManager.GetServerUrl(false) + "/IndexServlet?type=assets&name=sample.docx");
|
||||
}
|
||||
|
||||
// recipients data for mail merging
|
||||
Map<String, Object> dataMailMergeRecipients = new HashMap<>();
|
||||
dataMailMergeRecipients.put("fileType", "csv");
|
||||
dataMailMergeRecipients.put("url", DocumentManager.GetServerUrl(true) + "/IndexServlet?type=csv");
|
||||
dataMailMergeRecipients.put("directUrl", DocumentManager.GetServerUrl(false) + "/IndexServlet?type=csv");
|
||||
if (isEnableDirectUrl) {
|
||||
dataMailMergeRecipients.put("directUrl", DocumentManager.GetServerUrl(false) + "/IndexServlet?type=csv");
|
||||
}
|
||||
|
||||
// users data for mentions
|
||||
List<Map<String, Object>> usersForMentions = Users.getUsersForMentions(user.id);
|
||||
|
||||
@ -40,7 +40,7 @@ public class FileModel
|
||||
public String token;
|
||||
|
||||
// create file model
|
||||
public FileModel(String fileName, String lang, String actionData, User user)
|
||||
public FileModel(String fileName, String lang, String actionData, User user, Boolean isEnableDirectUrl)
|
||||
{
|
||||
if (fileName == null) fileName = "";
|
||||
fileName = fileName.trim(); // remove extra spaces in the file name
|
||||
@ -52,7 +52,7 @@ public class FileModel
|
||||
document = new Document();
|
||||
document.title = fileName;
|
||||
document.url = DocumentManager.GetDownloadUrl(fileName, true); // get file url
|
||||
document.directUrl = DocumentManager.GetDownloadUrl(fileName, false); // get direct url
|
||||
document.directUrl = isEnableDirectUrl ? DocumentManager.GetDownloadUrl(fileName, false) : ""; // get direct url
|
||||
document.fileType = FileUtility.GetFileExtension(fileName).replace(".", ""); // get file extension from the file name
|
||||
// generate document key
|
||||
document.key = ServiceConverter.GenerateRevisionId(DocumentManager.CurUserHostAddress(null) + "/" + fileName + "/" + Long.toString(new File(DocumentManager.StoragePath(fileName, null)).lastModified()));
|
||||
@ -185,7 +185,9 @@ public class FileModel
|
||||
dataObj.put("fileType", FileUtility.GetFileExtension(document.title).substring(1));
|
||||
dataObj.put("key", key);
|
||||
dataObj.put("url", i == curVer ? document.url : DocumentManager.GetDownloadHistoryUrl(document.title, i, "prev" + FileUtility.GetFileExtension(document.title), true));
|
||||
dataObj.put("directUrl", i == curVer ? document.url : DocumentManager.GetDownloadHistoryUrl(document.title, i, "prev" + FileUtility.GetFileExtension(document.title), false));
|
||||
if (!document.directUrl.equals("")) {
|
||||
dataObj.put("directUrl", i == curVer ? document.url : DocumentManager.GetDownloadHistoryUrl(document.title, i, "prev" + FileUtility.GetFileExtension(document.title), false));
|
||||
}
|
||||
dataObj.put("version", i);
|
||||
|
||||
if (i > 1) { //check if the version number is greater than 1
|
||||
|
||||
@ -143,6 +143,12 @@ public class ServiceConverter
|
||||
}
|
||||
|
||||
connection.connect();
|
||||
|
||||
int statusCode = connection.getResponseCode();
|
||||
if (statusCode != 200) { // checking status code
|
||||
connection.disconnect();
|
||||
throw new Exception("Conversion service returned status: " + statusCode);
|
||||
}
|
||||
try (OutputStream os = connection.getOutputStream()) {
|
||||
os.write(bodyByte);
|
||||
}
|
||||
|
||||
@ -253,6 +253,14 @@ public class TrackManager {
|
||||
|
||||
URL uri = new URL(url);
|
||||
java.net.HttpURLConnection connection = (java.net.HttpURLConnection) uri.openConnection();
|
||||
connection.setConnectTimeout(5000);
|
||||
|
||||
int statusCode = connection.getResponseCode();
|
||||
if (statusCode != 200) { // checking status code
|
||||
connection.disconnect();
|
||||
throw new RuntimeException("Document editing service returned status: " + statusCode);
|
||||
}
|
||||
|
||||
InputStream stream = connection.getInputStream(); // get input stream of the file information from the url
|
||||
|
||||
if (stream == null)
|
||||
|
||||
@ -16,7 +16,7 @@ files.docservice.url.api=web-apps/apps/api/documents/api.js
|
||||
files.docservice.url.preloader=web-apps/apps/api/documents/cache-scripts.html
|
||||
files.docservice.url.example=
|
||||
|
||||
files.docservice.languages=en:English|hy:Armenian|az:Azerbaijani|eu:Basque|be:Belarusian|bg:Bulgarian|ca:Catalan|zh:Chinese (People's Republic of China)|zh-TW:Chinese (Traditional, Taiwan)|cs:Czech|da:Danish|nl:Dutch|fi:Finnish|fr:French|gl:Galego|de:German|el:Greek|hu:Hungarian|id:Indonesian|it:Italian|ja:Japanese|ko:Korean|lv:Latvian|lo:Lao|ms:Malay (Malaysia)|nb:Norwegian|pl:Polish|pt:Portuguese (Brazil)|pt-PT:Portuguese (Portugal)|ro:Romanian|ru:Russian|sk:Slovak|sl:Slovenian|es:Spanish|sv:Swedish|tr:Turkish|uk:Ukrainian|vi:Vietnamese
|
||||
files.docservice.languages=en:English|hy:Armenian|az:Azerbaijani|eu:Basque|be:Belarusian|bg:Bulgarian|ca:Catalan|zh:Chinese (People's Republic of China)|zh-TW:Chinese (Traditional, Taiwan)|cs:Czech|da:Danish|nl:Dutch|fi:Finnish|fr:French|gl:Galego|de:German|el:Greek|hu:Hungarian|id:Indonesian|it:Italian|ja:Japanese|ko:Korean|lv:Latvian|lo:Lao|ms:Malay (Malaysia)|nb:Norwegian|pl:Polish|pt:Portuguese (Brazil)|pt-PT:Portuguese (Portugal)|ro:Romanian|ru:Russian|sk:Slovak|sl:Slovenian|es:Spanish|sv:Swedish|tr:Turkish|uk:Ukrainian|vi:Vietnamese|aa-AA:Test Language
|
||||
|
||||
files.docservice.secret=
|
||||
files.docservice.header=Authorization
|
||||
|
||||
@ -167,7 +167,7 @@ label .checkbox {
|
||||
background-image: url("img/file_docxf.svg");
|
||||
}
|
||||
|
||||
.create-sample {
|
||||
.side-option {
|
||||
color: #666666;
|
||||
line-height: 24px;
|
||||
}
|
||||
@ -747,3 +747,28 @@ html {
|
||||
.user-descr > b {
|
||||
margin-left: 25px;
|
||||
}
|
||||
|
||||
.tooltip {
|
||||
background: #FFFFFF;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0px 7px 25px rgba(85, 85, 85, 0.15);
|
||||
color: #666666;
|
||||
line-height: 160%;
|
||||
max-width: 455px;
|
||||
padding: 14px;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.tooltip ul {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.arrow {
|
||||
border-top: 8px solid transparent;
|
||||
border-bottom: 8px solid transparent;
|
||||
border-right: 8px solid #FFFFFF;
|
||||
left: -4px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
@ -87,7 +87,7 @@
|
||||
<tr>
|
||||
<td valign="middle">
|
||||
<span class="select-user">Username</span>
|
||||
<img class="info" src="css/img/info.svg" />
|
||||
<img id="info" class="info" src="css/img/info.svg" />
|
||||
<select class="select-user" id="user">
|
||||
<% for (User user : Users.getAllUsers()) { %>
|
||||
<option value="<%= user.id %>"><%= user.name == null ? "Anonymous" : user.name %></option>
|
||||
@ -97,7 +97,10 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="middle">
|
||||
<span class="select-user">Language editors interface</span>
|
||||
<span class="select-user">Language</span>
|
||||
<img class="info info-tooltip" data-id="language"
|
||||
data-tooltip="Choose the language for ONLYOFFICE editors interface"
|
||||
src="css/img/info.svg" />
|
||||
<select class="select-user" id="language">
|
||||
<% Map<String, String> languages = DocumentManager.GetLanguages(); %>
|
||||
<% for (Map.Entry<String, String> language : languages.entrySet()) { %>
|
||||
@ -106,6 +109,12 @@
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<td valign="middle">
|
||||
<label class="side-option">
|
||||
<input id="directUrl" type="checkbox" class="checkbox" />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="css/img/info.svg" />
|
||||
</label>
|
||||
</td>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@ -159,42 +168,44 @@
|
||||
%>
|
||||
<tr class="tableRow" title="<%= files[i].getName() %><%= version %>">
|
||||
<td class="contentCells">
|
||||
<a class="stored-edit <%= docType %>" href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8") %>" target="_blank">
|
||||
<a class="stored-edit <%= docType %>" href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8").concat(request.getParameter("directUrl") != null ? "&directUrl=".concat(request.getParameter("directUrl")) : "") %>" target="_blank">
|
||||
<span><%= files[i].getName() %></span>
|
||||
</a>
|
||||
</td>
|
||||
<% if (canEdit) { %>
|
||||
<td class="contentCells contentCells-icon">
|
||||
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8") %>&type=desktop&mode=edit" target="_blank">
|
||||
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8").concat(request.getParameter("directUrl") != null ? "&directUrl=".concat(request.getParameter("directUrl")) : "") %>&type=desktop&mode=edit" target="_blank">
|
||||
<img src="css/img/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="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8") %>&type=mobile&mode=edit" target="_blank">
|
||||
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8").concat(request.getParameter("directUrl") != null ? "&directUrl=".concat(request.getParameter("directUrl")) : "") %>&type=mobile&mode=edit" target="_blank">
|
||||
<img src="css/img/mobile.svg" alt="Open in editor for mobile devices" title="Open in editor for mobile devices"/>
|
||||
</a>
|
||||
</td>
|
||||
<td class="contentCells contentCells-icon">
|
||||
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8") %>&type=desktop&mode=comment" target="_blank">
|
||||
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8").concat(request.getParameter("directUrl") != null ? "&directUrl=".concat(request.getParameter("directUrl")) : "") %>&type=desktop&mode=comment" target="_blank">
|
||||
<img src="css/img/comment.svg" alt="Open in editor for comment" title="Open in editor for comment"/>
|
||||
</a>
|
||||
</td>
|
||||
<% if (docType.equals("word")) { %>
|
||||
<td class="contentCells contentCells-icon">
|
||||
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8") %>&type=desktop&mode=review" target="_blank">
|
||||
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8").concat(request.getParameter("directUrl") != null ? "&directUrl=".concat(request.getParameter("directUrl")) : "") %>&type=desktop&mode=review" target="_blank">
|
||||
<img src="css/img/review.svg" alt="Open in editor for review" title="Open in editor for review"/>
|
||||
</a>
|
||||
</td>
|
||||
<% } else if (docType.equals("cell")) { %>
|
||||
<td class="contentCells contentCells-icon">
|
||||
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8") %>&type=desktop&mode=filter" target="_blank">
|
||||
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8").concat(request.getParameter("directUrl") != null ? "&directUrl=".concat(request.getParameter("directUrl")) : "") %>&type=desktop&mode=filter" target="_blank">
|
||||
<img src="css/img/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 (docType.equals("word")) { %>
|
||||
<td class="contentCells contentCells-icon">
|
||||
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8") %>&type=desktop&mode=blockcontent" target="_blank">
|
||||
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8")
|
||||
.concat(request.getParameter("directUrl") != null ?
|
||||
"&directUrl=".concat(request.getParameter("directUrl")) : "") %>&type=desktop&mode=blockcontent" target="_blank">
|
||||
<img src="css/img/block-content.svg" alt="Open in editor without content control modification" title="Open in editor without content control modification"/>
|
||||
</a>
|
||||
</td>
|
||||
@ -206,7 +217,9 @@
|
||||
<% } %>
|
||||
<% if (isFillFormDoc) { %>
|
||||
<td class="contentCells contentCells-shift contentCells-icon firstContentCellShift">
|
||||
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8") %>&type=desktop&mode=fillForms" target="_blank">
|
||||
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8")
|
||||
.concat(request.getParameter("directUrl") != null ?
|
||||
"&directUrl=".concat(request.getParameter("directUrl")) : "") %>&type=desktop&mode=fillForms" target="_blank">
|
||||
<img src="css/img/fill-forms.svg" alt="Open in editor for filling in forms" title="Open in editor for filling in forms"/>
|
||||
</a>
|
||||
</td>
|
||||
@ -216,7 +229,9 @@
|
||||
<% } else if (isFillFormDoc) {%>
|
||||
<td class="contentCells contentCells-icon "></td>
|
||||
<td class="contentCells contentCells-icon">
|
||||
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8") %>&type=mobile&mode=fillForms" target="_blank">
|
||||
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8")
|
||||
.concat(request.getParameter("directUrl") != null ?
|
||||
"&directUrl=".concat(request.getParameter("directUrl")) : "") %>&type=mobile&mode=fillForms" target="_blank">
|
||||
<img src="css/img/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>
|
||||
@ -224,24 +239,32 @@
|
||||
<td class="contentCells contentCells-icon "></td>
|
||||
<td class="contentCells contentCells-icon "></td>
|
||||
<td class="contentCells contentCells-shift contentCells-icon firstContentCellShift">
|
||||
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8") %>&type=desktop&mode=fillForms" target="_blank">
|
||||
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8")
|
||||
.concat(request.getParameter("directUrl") != null ?
|
||||
"&directUrl=".concat(request.getParameter("directUrl")) : "") %>&type=desktop&mode=fillForms" target="_blank">
|
||||
<img src="css/img/fill-forms.svg" alt="Open in editor for filling in forms" title="Open in editor for filling in forms"/>
|
||||
</a>
|
||||
<% } else { %>
|
||||
<td class="contentCells contentCells-shift contentCells-icon contentCellsEmpty" colspan="6"></td>
|
||||
<% } %>
|
||||
<td class="contentCells contentCells-icon firstContentCellViewers">
|
||||
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8") %>&type=desktop&mode=view" target="_blank">
|
||||
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8")
|
||||
.concat(request.getParameter("directUrl") != null ?
|
||||
"&directUrl=".concat(request.getParameter("directUrl")) : "") %>&type=desktop&mode=view" target="_blank">
|
||||
<img src="css/img/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="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8") %>&type=mobile&mode=view" target="_blank">
|
||||
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8")
|
||||
.concat(request.getParameter("directUrl") != null ?
|
||||
"&directUrl=".concat(request.getParameter("directUrl")) : "") %>&type=mobile&mode=view" target="_blank">
|
||||
<img src="css/img/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="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8") %>&type=embedded&mode=embedded" target="_blank">
|
||||
<a href="EditorServlet?fileName=<%= URLEncoder.encode(files[i].getName(), "UTF-8")
|
||||
.concat(request.getParameter("directUrl") != null ?
|
||||
"&directUrl=".concat(request.getParameter("directUrl")) : "") %>&type=embedded&mode=embedded" target="_blank">
|
||||
<img src="css/img/embeded.svg" alt="Open in embedded mode" title="Open in embedded mode"/>
|
||||
</a>
|
||||
</td>
|
||||
@ -349,8 +372,19 @@
|
||||
var UrlConverter = "IndexServlet?type=convert";
|
||||
var UrlEditor = "EditorServlet";
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function(){
|
||||
document.getElementById("language").value="en";
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
var lang = document.cookie
|
||||
.split('; ')
|
||||
.find((row) => row.startsWith('ulang='))
|
||||
?.split('=')[1];
|
||||
|
||||
var languages = Array.from(document.getElementById("language").options).map(e => e.value)
|
||||
|
||||
if (!languages.includes(lang)) {
|
||||
lang = "en";
|
||||
}
|
||||
|
||||
document.getElementById("language").value=lang;
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
@ -16,11 +16,24 @@
|
||||
*
|
||||
*/
|
||||
|
||||
var directUrl;
|
||||
|
||||
if (typeof jQuery !== "undefined") {
|
||||
jq = jQuery.noConflict();
|
||||
|
||||
directUrl = getUrlVars()["directUrl"] == "true";
|
||||
|
||||
mustReload = false;
|
||||
|
||||
if (directUrl)
|
||||
jq("#directUrl").prop("checked", directUrl);
|
||||
else
|
||||
directUrl = jq("#directUrl").prop("checked");
|
||||
|
||||
jq("#directUrl").change(function() {
|
||||
window.location = "?directUrl=" + jq(this).prop("checked");
|
||||
});
|
||||
|
||||
jq(function () {
|
||||
jq("#fileupload").fileupload({
|
||||
dataType: "json",
|
||||
@ -218,7 +231,7 @@ if (typeof jQuery !== "undefined") {
|
||||
|
||||
jq(document).on("click", "#beginEdit:not(.disable)", function () {
|
||||
var fileId = encodeURIComponent(jq("#hiddenFileName").val());
|
||||
var url = UrlEditor + "?mode=edit&fileName=" + fileId;
|
||||
var url = UrlEditor + "?mode=edit&fileName=" + fileId + "&directUrl=" + directUrl;
|
||||
window.open(url, "_blank");
|
||||
jq("#hiddenFileName").val("");
|
||||
jq.unblockUI();
|
||||
@ -226,7 +239,7 @@ if (typeof jQuery !== "undefined") {
|
||||
|
||||
jq(document).on("click", "#beginView:not(.disable)", function () {
|
||||
var fileId = encodeURIComponent(jq("#hiddenFileName").val());
|
||||
var url = UrlEditor + "?mode=view&fileName=" + fileId;
|
||||
var url = UrlEditor + "?mode=view&fileName=" + fileId + "&directUrl=" + directUrl;
|
||||
window.open(url, "_blank");
|
||||
jq("#hiddenFileName").val("");
|
||||
jq.unblockUI();
|
||||
@ -234,7 +247,7 @@ if (typeof jQuery !== "undefined") {
|
||||
|
||||
jq(document).on("click", "#beginEmbedded:not(.disable)", function () {
|
||||
var fileId = encodeURIComponent(jq("#hiddenFileName").val());
|
||||
var url = UrlEditor + "?type=embedded&mode=embedded&fileName=" + fileId;
|
||||
var url = UrlEditor + "?type=embedded&mode=embedded&fileName=" + fileId + "&directUrl=" + directUrl;
|
||||
|
||||
jq("#mainProgress").addClass("embedded");
|
||||
jq("#beginEmbedded").addClass("disable");
|
||||
@ -287,6 +300,17 @@ if (typeof jQuery !== "undefined") {
|
||||
}
|
||||
};
|
||||
|
||||
function getUrlVars() {
|
||||
var vars = [], hash;
|
||||
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
|
||||
for (var i = 0; i < hashes.length; i++) {
|
||||
hash = hashes[i].split('=');
|
||||
vars.push(hash[0]);
|
||||
vars[hash[0]] = hash[1];
|
||||
}
|
||||
return vars;
|
||||
};
|
||||
|
||||
var fileList = jq("tr.tableRow");
|
||||
|
||||
var mouseIsOverTooltip = false;
|
||||
@ -297,12 +321,12 @@ if (typeof jQuery !== "undefined") {
|
||||
if (hideTooltipTimeout != null) {
|
||||
clearTimeout(hideTooltipTimeout);
|
||||
}
|
||||
jq(".info").on("touchend", function () {
|
||||
jq("#info").on("touchend", function () {
|
||||
showUserTooltip(true);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
jq(".info").mouseover(function (event) {
|
||||
jq("#info").mouseover(function (event) {
|
||||
if (fileList.length > 0) {
|
||||
if (hideTooltipTimeout != null) {
|
||||
clearTimeout(hideTooltipTimeout);
|
||||
@ -326,4 +350,18 @@ if (typeof jQuery !== "undefined") {
|
||||
}, 500);
|
||||
});
|
||||
}
|
||||
|
||||
jq(".info-tooltip").mouseover(function (event) {
|
||||
var target = event.target;
|
||||
var id = target.dataset.id ? target.dataset.id : target.id;
|
||||
var tooltip = target.dataset.tooltip;
|
||||
|
||||
jq("<div class='tooltip'>" + tooltip + "<div class='arrow'></div></div>").appendTo("body");
|
||||
|
||||
var top = jq("#" + id).offset().top + jq("#" + id).outerHeight() / 2 - jq("div.tooltip").outerHeight() / 2;
|
||||
var left = jq("#" + id).offset().left + jq("#" + id).outerWidth() + 20;
|
||||
jq("div.tooltip").css({"top": top, "left": left});
|
||||
}).mouseout(function () {
|
||||
jq("div.tooltip").remove();
|
||||
});
|
||||
}
|
||||
1
web/documentserver-example/nodejs/.eslintignore
Normal file
1
web/documentserver-example/nodejs/.eslintignore
Normal file
@ -0,0 +1 @@
|
||||
public
|
||||
15
web/documentserver-example/nodejs/.eslintrc.js
Normal file
15
web/documentserver-example/nodejs/.eslintrc.js
Normal file
@ -0,0 +1,15 @@
|
||||
module.exports = {
|
||||
env: {
|
||||
browser: true,
|
||||
commonjs: true,
|
||||
es2021: true,
|
||||
},
|
||||
extends: ['airbnb-base'],
|
||||
overrides: [
|
||||
],
|
||||
parserOptions: {
|
||||
ecmaVersion: 'latest',
|
||||
},
|
||||
rules: {
|
||||
},
|
||||
};
|
||||
@ -469,6 +469,61 @@ app.get("/csv", function (req, res) { // define a handler for downloading csv f
|
||||
filestream.pipe(res); // send file information to the response by streams
|
||||
})
|
||||
|
||||
app.post("/reference", function (req, res) { //define a handler for renaming file
|
||||
|
||||
req.docManager = new docManager(req, res);
|
||||
|
||||
var result = function(data) {
|
||||
res.writeHead(200, {"Content-Type": "application/json" });
|
||||
res.write(JSON.stringify(data));
|
||||
res.end();
|
||||
};
|
||||
|
||||
var referenceData = req.body.referenceData;
|
||||
if (!!referenceData) {
|
||||
var portalName = referenceData.portalName;
|
||||
|
||||
if (portalName != req.docManager.getServerUrl()) {
|
||||
result({ "error": "You do not have access to this site" });
|
||||
return;
|
||||
}
|
||||
|
||||
var fileId = JSON.parse(referenceData.fileId);
|
||||
var userAddress = fileId.userAddress;
|
||||
if (userAddress != req.docManager.curUserHostAddress()) {
|
||||
result({ "error": "You do not have access to this file" });
|
||||
return;
|
||||
}
|
||||
|
||||
var fileName = fileId.fileName;
|
||||
if (!req.docManager.existsSync(req.docManager.storagePath(fileName, userAddress))) {
|
||||
result({ "error": "File is not exist" });
|
||||
return;
|
||||
}
|
||||
} else if (!!req.body.path) {
|
||||
var fileName = fileUtility.getFileName(req.body.path);
|
||||
if (!req.docManager.existsSync(req.docManager.storagePath(fileName, userAddress))) {
|
||||
result({ "error": "File is not exist" });
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fileName) {
|
||||
result({ "error": "File is not found" });
|
||||
return;
|
||||
}
|
||||
|
||||
result({
|
||||
url: req.docManager.getDownloadUrl(fileName, true),
|
||||
directUrl: req.docManager.getDownloadUrl(fileName),
|
||||
referenceData: {
|
||||
fileId: JSON.stringify({ fileName: fileName, userAddress: req.docManager.curUserHostAddress()}),
|
||||
portalName: req.docManager.getServerUrl()
|
||||
},
|
||||
path: fileName,
|
||||
});
|
||||
});
|
||||
|
||||
app.post("/track", async function (req, res) { // define a handler for tracking file changes
|
||||
|
||||
req.docManager = new docManager(req, res);
|
||||
@ -779,6 +834,19 @@ app.get("/editor", function (req, res) { // define a handler for editing docume
|
||||
}
|
||||
}
|
||||
|
||||
var referenceData = {
|
||||
fileId: JSON.stringify({ fileName: fileName, userAddress: req.docManager.curUserHostAddress()}),
|
||||
portalName: req.docManager.getServerUrl()
|
||||
};
|
||||
|
||||
var type = req.query.type || ""; // type: embedded/mobile/desktop
|
||||
if (type == "") {
|
||||
type = new RegExp(configServer.get("mobileRegEx"), "i").test(req.get('User-Agent')) ? "mobile" : "desktop";
|
||||
} else if (type != "mobile"
|
||||
&& type != "embedded") {
|
||||
type = "desktop";
|
||||
}
|
||||
|
||||
var templatesImageUrl = req.docManager.getTemplateImageUrl(fileUtility.getFileType(fileName));
|
||||
var createUrl = req.docManager.getCreateUrl(fileUtility.getFileType(fileName), userid, type, lang);
|
||||
var templates = [
|
||||
@ -820,14 +888,6 @@ app.get("/editor", function (req, res) { // define a handler for editing docume
|
||||
var directUrl = req.docManager.getDownloadUrl(fileName);
|
||||
var mode = req.query.mode || "edit"; // mode: view/edit/review/comment/fillForms/embedded
|
||||
|
||||
var type = req.query.type || ""; // type: embedded/mobile/desktop
|
||||
if (type == "") {
|
||||
type = new RegExp(configServer.get("mobileRegEx"), "i").test(req.get('User-Agent')) ? "mobile" : "desktop";
|
||||
} else if (type != "mobile"
|
||||
&& type != "embedded") {
|
||||
type = "desktop";
|
||||
}
|
||||
|
||||
var canEdit = configServer.get('editedDocs').indexOf(fileExt) != -1; // check if this file can be edited
|
||||
if ((!canEdit && mode == "edit" || mode == "fillForms") && configServer.get('fillDocs').indexOf(fileExt) != -1) {
|
||||
mode = "fillForms";
|
||||
@ -945,7 +1005,8 @@ app.get("/editor", function (req, res) { // define a handler for editing docume
|
||||
fileChoiceUrl: fileChoiceUrl,
|
||||
submitForm: submitForm,
|
||||
plugins: JSON.stringify(plugins),
|
||||
actionData: actionData
|
||||
actionData: actionData,
|
||||
referenceData: userid != "uid-0" ? referenceData : null
|
||||
},
|
||||
history: history,
|
||||
historyData: historyData,
|
||||
|
||||
@ -84,7 +84,8 @@
|
||||
"sv": "Swedish",
|
||||
"tr": "Turkish",
|
||||
"uk": "Ukrainian",
|
||||
"vi": "Vietnamese"
|
||||
"vi": "Vietnamese",
|
||||
"aa-AA": "Test Language"
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
|
||||
@ -22,9 +22,20 @@ var urlModule = require("url");
|
||||
var urllib = require("urllib");
|
||||
const xmlParser = require("fast-xml-parser");
|
||||
const he = require("he");
|
||||
const siteUrl = configServer.get("siteUrl"); // the path to the editors installation
|
||||
|
||||
var cache = null;
|
||||
|
||||
async function initWopi(docManager) {
|
||||
let absSiteUrl = siteUrl;
|
||||
if (absSiteUrl.indexOf("/") === 0) {
|
||||
absSiteUrl = docManager.getServerHost() + siteUrl;
|
||||
}
|
||||
|
||||
// get the wopi discovery information
|
||||
await getDiscoveryInfo(absSiteUrl);
|
||||
}
|
||||
|
||||
// get the wopi discovery information
|
||||
async function getDiscoveryInfo(siteUrl) {
|
||||
let actions = [];
|
||||
@ -125,6 +136,7 @@ function getActionUrl(host, userAddress, action, filename) {
|
||||
return action.urlsrc.replace(/<.*&>/g, "") + "WOPISrc=" + host + "/wopi/files/" + filename + "@" + userAddress;
|
||||
}
|
||||
|
||||
exports.initWopi = initWopi;
|
||||
exports.getDiscoveryInfo = getDiscoveryInfo;
|
||||
exports.getAction = getAction;
|
||||
exports.getActions = getActions;
|
||||
|
||||
@ -23,7 +23,7 @@ const docManager = require("../docManager");
|
||||
const fileUtility = require("../fileUtility");
|
||||
const config = require('config');
|
||||
const configServer = config.get('server');
|
||||
const siteUrl = configServer.get('siteUrl'); // the path to the editors installation
|
||||
const siteUrl = configServer.get("siteUrl"); // the path to the editors installation
|
||||
const users = require("../users");
|
||||
|
||||
exports.registerRoutes = function(app) {
|
||||
@ -33,24 +33,10 @@ exports.registerRoutes = function(app) {
|
||||
|
||||
req.docManager = new docManager(req, res);
|
||||
|
||||
let absSiteUrl = siteUrl;
|
||||
if (absSiteUrl.indexOf("/") === 0) {
|
||||
absSiteUrl = req.docManager.getServerHost() + siteUrl;
|
||||
|
||||
//todo: remove
|
||||
if (absSiteUrl.indexOf("example") !== -1) {
|
||||
let host = req.get("host");
|
||||
let pos = host.indexOf("/", "https://".length);
|
||||
if (pos > -1)
|
||||
{
|
||||
host = host.substring(0, pos);
|
||||
}
|
||||
absSiteUrl = req.docManager.getProtocol() + "://" + host + siteUrl;
|
||||
}
|
||||
}
|
||||
await utils.initWopi(req.docManager);
|
||||
|
||||
// get the wopi discovery information
|
||||
let actions = await utils.getDiscoveryInfo(absSiteUrl);
|
||||
let actions = await utils.getDiscoveryInfo();
|
||||
let wopiEnable = actions.length != 0 ? true : false;
|
||||
let docsExtEdit = []; // Supported extensions for WOPI
|
||||
|
||||
@ -111,6 +97,8 @@ exports.registerRoutes = function(app) {
|
||||
try {
|
||||
req.docManager = new docManager(req, res);
|
||||
|
||||
await utils.initWopi(req.docManager);
|
||||
|
||||
var fileName = req.docManager.getCorrectName(req.params['id'])
|
||||
var fileExt = fileUtility.getFileExtension(fileName, true); // get the file extension from the request
|
||||
var user = users.getUser(req.query.userid); // get a user by the id
|
||||
|
||||
3281
web/documentserver-example/nodejs/npm-shrinkwrap.json
generated
3281
web/documentserver-example/nodejs/npm-shrinkwrap.json
generated
File diff suppressed because it is too large
Load Diff
@ -3,7 +3,9 @@
|
||||
"version": "4.1.0",
|
||||
"private": false,
|
||||
"scripts": {
|
||||
"start": "node ./bin/www"
|
||||
"start": "node ./bin/www",
|
||||
"lint": "eslint .",
|
||||
"lint:fix": "eslint --fix ."
|
||||
},
|
||||
"bin": "bin/www",
|
||||
"description": "OnlineEditorsExampleNodeJS",
|
||||
@ -40,5 +42,10 @@
|
||||
"public/**/*",
|
||||
"views/*"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^8.28.0",
|
||||
"eslint-config-airbnb-base": "^15.0.0",
|
||||
"eslint-plugin-import": "^2.26.0"
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
"commentGroups": <%- editor.commentGroups %>,
|
||||
"userInfoGroups": <%- editor.userInfoGroups %>
|
||||
},
|
||||
"referenceData": <%- JSON.stringify(editor.referenceData) %>,
|
||||
"title": "<%- file.name %>",
|
||||
"url": "<%- file.uri %>"
|
||||
},
|
||||
|
||||
@ -151,6 +151,20 @@
|
||||
innerAlert("onRequestSendNotify: " + data);
|
||||
};
|
||||
|
||||
var onRequestReferenceData = function(event) { // user refresh external data source
|
||||
innerAlert("onRequestReferenceData");
|
||||
innerAlert(event.data);
|
||||
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", "reference");
|
||||
xhr.setRequestHeader("Content-Type", "application/json");
|
||||
xhr.send(JSON.stringify(event.data));
|
||||
xhr.onload = function () {
|
||||
innerAlert(xhr.responseText);
|
||||
docEditor.setReferenceData(JSON.parse(xhr.responseText));
|
||||
}
|
||||
};
|
||||
|
||||
var onRequestSaveAs = function (event) { // the user is trying to save file by clicking Save Copy as... button
|
||||
var title = event.data.title;
|
||||
var url = event.data.url;
|
||||
@ -209,6 +223,7 @@
|
||||
config.events.onRequestRename = onRequestRename;
|
||||
config.events.onRequestUsers = onRequestUsers;
|
||||
config.events.onRequestSendNotify = onRequestSendNotify;
|
||||
config.events.onRequestReferenceData = onRequestReferenceData;
|
||||
}
|
||||
|
||||
if (config.editorConfig.createUrl) {
|
||||
|
||||
@ -84,6 +84,7 @@ $GLOBALS['LANGUAGES'] = array(
|
||||
'sv' => 'Swedish',
|
||||
'tr' => 'Turkish',
|
||||
'uk' => 'Ukrainian',
|
||||
'vi' => 'Vietnamese'
|
||||
'vi' => 'Vietnamese',
|
||||
'aa-AA' => 'Test Language'
|
||||
);
|
||||
?>
|
||||
@ -166,7 +166,7 @@ label .checkbox {
|
||||
background-image: url("images/file_docxf.svg");
|
||||
}
|
||||
|
||||
.create-sample {
|
||||
.side-option {
|
||||
color: #666666;
|
||||
line-height: 24px;
|
||||
}
|
||||
@ -740,3 +740,28 @@ html {
|
||||
.user-descr > b {
|
||||
margin-left: 25px;
|
||||
}
|
||||
|
||||
.tooltip {
|
||||
background: #FFFFFF;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0px 7px 25px rgba(85, 85, 85, 0.15);
|
||||
color: #666666;
|
||||
line-height: 160%;
|
||||
max-width: 455px;
|
||||
padding: 14px;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.tooltip ul {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.arrow {
|
||||
border-top: 8px solid transparent;
|
||||
border-bottom: 8px solid transparent;
|
||||
border-right: 8px solid #FFFFFF;
|
||||
left: -4px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
@ -26,6 +26,7 @@
|
||||
$filename;
|
||||
|
||||
$user = getUser($_GET["user"]);
|
||||
$isEnableDirectUrl = $_GET["directUrl"] != null ? filter_var($_GET["directUrl"], FILTER_VALIDATE_BOOLEAN) : false;
|
||||
|
||||
// get the file url and upload it
|
||||
$externalUrl = $_GET["fileUrl"];
|
||||
@ -90,7 +91,7 @@
|
||||
"document" => [
|
||||
"title" => $filename,
|
||||
"url" => getDownloadUrl($filename),
|
||||
"directUrl" => $directUrl,
|
||||
"directUrl" => $isEnableDirectUrl ? $directUrl : "",
|
||||
"fileType" => $filetype,
|
||||
"key" => $docKey,
|
||||
"info" => [
|
||||
@ -150,24 +151,33 @@
|
||||
];
|
||||
|
||||
// an image for inserting
|
||||
$dataInsertImage = [
|
||||
$dataInsertImage = $isEnableDirectUrl ? [
|
||||
"fileType" => "png",
|
||||
"url" => serverPath(true) . "/css/images/logo.png",
|
||||
"directUrl" => serverPath(false) . "/css/images/logo.png"
|
||||
] : [
|
||||
"fileType" => "png",
|
||||
"url" => serverPath(true) . "/css/images/logo.png"
|
||||
];
|
||||
|
||||
// a document for comparing
|
||||
$dataCompareFile = [
|
||||
$dataCompareFile = $isEnableDirectUrl ? [
|
||||
"fileType" => "docx",
|
||||
"url" => serverPath(true) . "/webeditor-ajax.php?type=assets&name=sample.docx",
|
||||
"directUrl" => serverPath(false) . "/webeditor-ajax.php?type=assets&name=sample.docx"
|
||||
] : [
|
||||
"fileType" => "docx",
|
||||
"url" => serverPath(true) . "/webeditor-ajax.php?type=assets&name=sample.docx"
|
||||
];
|
||||
|
||||
// recipients data for mail merging
|
||||
$dataMailMergeRecipients = [
|
||||
$dataMailMergeRecipients = $isEnableDirectUrl ? [
|
||||
"fileType" =>"csv",
|
||||
"url" => serverPath(true) . "/webeditor-ajax.php?type=csv",
|
||||
"directUrl" => serverPath(false) . "/webeditor-ajax.php?type=csv"
|
||||
] : [
|
||||
"fileType" =>"csv",
|
||||
"url" => serverPath(true) . "/webeditor-ajax.php?type=csv"
|
||||
];
|
||||
|
||||
// users data for mentions
|
||||
@ -240,7 +250,7 @@
|
||||
}
|
||||
|
||||
// get document history
|
||||
function getHistory($filename, $filetype, $docKey, $fileuri) {
|
||||
function getHistory($filename, $filetype, $docKey, $fileuri, $isEnableDirectUrl) {
|
||||
$storagePath = $GLOBALS['STORAGE_PATH'];
|
||||
$histDir = getHistoryDir(getStoragePath($filename)); // get the path to the file history
|
||||
|
||||
@ -282,11 +292,15 @@
|
||||
$prevFileUrl = $i == $curVer ? $fileuri : getHistoryDownloadUrl($filename, $i, "prev.".$fileExe);
|
||||
if (realpath($storagePath) === $storagePath) {
|
||||
$prevFileUrl = $i == $curVer ? getDownloadUrl($filename) : getHistoryDownloadUrl($filename, $i, "prev.".$fileExe);
|
||||
$directUrl = $i == $curVer ? getDownloadUrl($filename, FALSE) : getHistoryDownloadUrl($filename, $i, "prev.".$fileExe, FALSE);
|
||||
if ($isEnableDirectUrl) {
|
||||
$directUrl = $i == $curVer ? getDownloadUrl($filename, FALSE) : getHistoryDownloadUrl($filename, $i, "prev.".$fileExe, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
$dataObj["url"] = $prevFileUrl; // write file url to the data object
|
||||
$dataObj["directUrl"] = $directUrl; // write direct url to the data object
|
||||
if ($isEnableDirectUrl) {
|
||||
$dataObj["directUrl"] = $directUrl; // write direct url to the data object
|
||||
}
|
||||
$dataObj["version"] = $i;
|
||||
|
||||
if ($i > 1) { // check if the version number is greater than 1 (the document was modified)
|
||||
@ -299,11 +313,15 @@
|
||||
$obj["user"] = $change ? $change["user"] : null;
|
||||
|
||||
$prev = $histData[$i - 2]; // get the history data from the previous file version
|
||||
$dataObj["previous"] = [ // write information about previous file version to the data object
|
||||
$dataObj["previous"] = $isEnableDirectUrl ? [ // write information about previous file version to the data object
|
||||
"fileType" => $prev["fileType"],
|
||||
"key" => $prev["key"],
|
||||
"url" => $prev["url"],
|
||||
"directUrl" => $prev["directUrl"]
|
||||
] : [
|
||||
"fileType" => $prev["fileType"],
|
||||
"key" => $prev["key"],
|
||||
"url" => $prev["url"]
|
||||
];
|
||||
|
||||
// write the path to the diff.zip archive with differences in this file version
|
||||
@ -529,7 +547,7 @@
|
||||
};
|
||||
|
||||
<?php
|
||||
$out = getHistory($filename, $filetype, $docKey, $fileuri);
|
||||
$out = getHistory($filename, $filetype, $docKey, $fileuri, $isEnableDirectUrl);
|
||||
$history = $out[0];
|
||||
$historyData = $out[1];
|
||||
?>
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
require_once( dirname(__FILE__) . '/users.php' );
|
||||
|
||||
$user = $_GET["user"];
|
||||
$directUrlArg = $_GET["directUrl"] != null ? "&directUrl=" . $_GET["directUrl"] : "";
|
||||
?>
|
||||
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
@ -73,7 +74,7 @@
|
||||
<a class="try-editor form reload-page" target="_blank" href="doceditor.php?fileExt=docxf&user=<?php echo htmlentities($user); ?>">Form template</a>
|
||||
</li>
|
||||
</ul>
|
||||
<label class="create-sample">
|
||||
<label class="side-option">
|
||||
<input type="checkbox" id="createSample" class="checkbox" />With sample content
|
||||
</label>
|
||||
</div>
|
||||
@ -87,7 +88,7 @@
|
||||
<tr>
|
||||
<td valign="middle">
|
||||
<span class="select-user">Username</span>
|
||||
<img class="info" src="css/images/info.svg" />
|
||||
<img id="info" class="info" src="css/images/info.svg" />
|
||||
<select class="select-user" id="user">
|
||||
<?php foreach(getAllUsers() as $user_l) {
|
||||
$name = $user_l->name ? $user_l->name : "Anonymous";
|
||||
@ -98,7 +99,10 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="middle">
|
||||
<span class="select-user">Language editors interface</span>
|
||||
<span class="select-user">Language</span>
|
||||
<img class="info info-tooltip" data-id="language"
|
||||
data-tooltip="Choose the language for ONLYOFFICE editors interface"
|
||||
src="css/images/info.svg" />
|
||||
<select class="select-user" id="language">
|
||||
<?php foreach ($GLOBALS['LANGUAGES'] as $key => $language) { ?>
|
||||
<option value="<?=$key?>"><?=$language?></option>
|
||||
@ -106,6 +110,14 @@
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="middle">
|
||||
<label class="side-option">
|
||||
<input id="directUrl" type="checkbox" class="checkbox" />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="css/images/info.svg" />
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@ -159,37 +171,37 @@
|
||||
<?php foreach ($storedFiles as &$storeFile) {
|
||||
echo '<tr class="tableRow" title="'.$storeFile->name.' ['.getFileVersion(getHistoryDir(getStoragePath($storeFile->name))).']">';
|
||||
echo ' <td class="contentCells">';
|
||||
echo ' <a class="stored-edit '.$storeFile->documentType.'" href="doceditor.php?fileID='.urlencode($storeFile->name).'&user='.htmlentities($user).'" target="_blank">';
|
||||
echo ' <a class="stored-edit '.$storeFile->documentType.'" href="doceditor.php?fileID='.urlencode($storeFile->name).'&user='.htmlentities($user) . $directUrlArg .'" target="_blank">';
|
||||
echo ' <span>'.$storeFile->name.'</span>';
|
||||
echo ' </a>';
|
||||
echo ' </td>';
|
||||
if ($storeFile->canEdit) {
|
||||
echo ' <td class="contentCells contentCells-icon">';
|
||||
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . '&action=edit&type=desktop" target="_blank">';
|
||||
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . $directUrlArg . '&action=edit&type=desktop" target="_blank">';
|
||||
echo ' <img src="css/images/desktop.svg" alt="Open in editor for full size screens" title="Open in editor for full size screens" /></a>';
|
||||
echo ' </td>';
|
||||
echo ' <td class="contentCells contentCells-icon">';
|
||||
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . '&action=edit&type=mobile" target="_blank">';
|
||||
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . $directUrlArg . '&action=edit&type=mobile" target="_blank">';
|
||||
echo ' <img src="css/images/mobile.svg" alt="Open in editor for mobile devices" title="Open in editor for mobile devices" /></a>';
|
||||
echo ' </td>';
|
||||
echo ' <td class="contentCells contentCells-icon">';
|
||||
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . '&action=comment&type=desktop" target="_blank">';
|
||||
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . $directUrlArg . '&action=comment&type=desktop" target="_blank">';
|
||||
echo ' <img src="css/images/comment.svg" alt="Open in editor for comment" title="Open in editor for comment" /></a>';
|
||||
echo ' </td>';
|
||||
if ($storeFile->documentType == "word") {
|
||||
echo ' <td class="contentCells contentCells-icon">';
|
||||
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . '&action=review&type=desktop" target="_blank">';
|
||||
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . $directUrlArg . '&action=review&type=desktop" target="_blank">';
|
||||
echo ' <img src="css/images/review.svg" alt="Open in editor for review" title="Open in editor for review" /></a>';
|
||||
echo ' </td>';
|
||||
} else if ($storeFile->documentType == "cell") {
|
||||
echo ' <td class="contentCells contentCells-icon">';
|
||||
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . '&action=filter&type=desktop" target="_blank">';
|
||||
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . $directUrlArg . '&action=filter&type=desktop" target="_blank">';
|
||||
echo ' <img src="css/images/filter.svg" alt="Open in editor without access to change the filter" title="Open in editor without access to change the filter" /></a>';
|
||||
echo ' </td>';
|
||||
}
|
||||
if ($storeFile->documentType == "word") {
|
||||
echo ' <td class="contentCells contentCells-icon ">';
|
||||
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . '&action=blockcontent&type=desktop" target="_blank">';
|
||||
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . $directUrlArg . '&action=blockcontent&type=desktop" target="_blank">';
|
||||
echo ' <img src="css/images/block-content.svg" alt="Open in editor without content control modification" title="Open in editor without content control modification" /></a>';
|
||||
echo ' </td>';
|
||||
} else{
|
||||
@ -200,7 +212,7 @@
|
||||
}
|
||||
if ($storeFile->isFillFormDoc) {
|
||||
echo ' <td class="contentCells contentCells-shift contentCells-icon firstContentCellShift">';
|
||||
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . '&action=fillForms&type=desktop" target="_blank">';
|
||||
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . $directUrlArg . '&action=fillForms&type=desktop" target="_blank">';
|
||||
echo ' <img src="css/images/fill-forms.svg" alt="Open in editor for filling in forms" title="Open in editor for filling in forms" /></a>';
|
||||
echo ' </td>';
|
||||
} else {
|
||||
@ -209,29 +221,29 @@
|
||||
} else if ($storeFile->isFillFormDoc) {
|
||||
echo ' <td class="contentCells contentCells-icon"></td>';
|
||||
echo ' <td class="contentCells contentCells-icon">';
|
||||
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . '&action=fillForms&type=desktop" target="_blank">';
|
||||
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . $directUrlArg . '&action=fillForms&type=desktop" target="_blank">';
|
||||
echo ' <img src="css/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>';
|
||||
echo ' </td>';
|
||||
echo ' <td class="contentCells contentCells-icon"></td>';
|
||||
echo ' <td class="contentCells contentCells-icon"></td>';
|
||||
echo ' <td class="contentCells contentCells-icon"></td>';
|
||||
echo ' <td class="contentCells contentCells-shift contentCells-icon firstContentCellShift">';
|
||||
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . '&action=fillForms&type=desktop" target="_blank">';
|
||||
echo ' <a href="doceditor.php?fileID=' . urlencode($storeFile->name) . '&user=' . htmlentities($user) . $directUrlArg . '&action=fillForms&type=desktop" target="_blank">';
|
||||
echo ' <img src="css/images/fill-forms.svg" alt="Open in editor for filling in forms" title="Open in editor for filling in forms" /></a>';
|
||||
echo ' </td>';
|
||||
} else {
|
||||
echo '<td class="contentCells contentCells-shift contentCells-icon contentCellsEmpty" colspan="6"></td>';
|
||||
}
|
||||
echo ' <td class="contentCells contentCells-icon firstContentCellViewers">';
|
||||
echo ' <a href="doceditor.php?fileID='.urlencode($storeFile->name).'&user='.htmlentities($user).'&action=view&type=desktop" target="_blank">';
|
||||
echo ' <a href="doceditor.php?fileID='.urlencode($storeFile->name).'&user='.htmlentities($user) . $directUrlArg . '&action=view&type=desktop" target="_blank">';
|
||||
echo ' <img src="css/images/desktop.svg" alt="Open in viewer for full size screens" title="Open in viewer for full size screens" /></a>';
|
||||
echo ' </td>';
|
||||
echo ' <td class="contentCells contentCells-icon">';
|
||||
echo ' <a href="doceditor.php?fileID='.urlencode($storeFile->name).'&user='.htmlentities($user).'&action=view&type=mobile" target="_blank">';
|
||||
echo ' <a href="doceditor.php?fileID='.urlencode($storeFile->name).'&user='.htmlentities($user) . $directUrlArg . '&action=view&type=mobile" target="_blank">';
|
||||
echo ' <img src="css/images/mobile.svg" alt="Open in viewer for mobile devices" title="Open in viewer for mobile devices" /></a>';
|
||||
echo ' </td>';
|
||||
echo ' <td class="contentCells contentCells-icon contentCells-shift">';
|
||||
echo ' <a href="doceditor.php?fileID='.urlencode($storeFile->name).'&user='.htmlentities($user).'&action=embedded&type=embedded" target="_blank">';
|
||||
echo ' <a href="doceditor.php?fileID='.urlencode($storeFile->name).'&user='.htmlentities($user) . $directUrlArg . '&action=embedded&type=embedded" target="_blank">';
|
||||
echo ' <img src="css/images/embeded.svg" alt="Open in embedded mode" title="Open in embedded mode" /></a>';
|
||||
echo ' </td>';
|
||||
echo ' <td class="contentCells contentCells-icon contentCells-shift downloadContentCellShift">';
|
||||
|
||||
@ -16,11 +16,24 @@
|
||||
*
|
||||
*/
|
||||
|
||||
var directUrl;
|
||||
|
||||
if (typeof jQuery != "undefined") {
|
||||
jq = jQuery.noConflict();
|
||||
|
||||
directUrl = getUrlVars()["directUrl"] == "true";
|
||||
|
||||
mustReload = false;
|
||||
|
||||
if (directUrl)
|
||||
jq("#directUrl").prop("checked", directUrl);
|
||||
else
|
||||
directUrl = jq("#directUrl").prop("checked");
|
||||
|
||||
jq("#directUrl").change(function() {
|
||||
window.location = "?directUrl=" + jq(this).prop("checked");
|
||||
});
|
||||
|
||||
user = getUrlVars()["user"];
|
||||
if ("" != user && undefined != user)
|
||||
jq("#user").val(user);
|
||||
@ -234,7 +247,7 @@ if (typeof jQuery != "undefined") {
|
||||
|
||||
jq(document).on("click", "#beginEdit:not(.disable)", function () {
|
||||
var fileId = encodeURIComponent(jq('#hiddenFileName').val());
|
||||
var url = "doceditor.php?fileID=" + fileId + "&user=" + user;
|
||||
var url = "doceditor.php?fileID=" + fileId + "&user=" + user + "&directUrl=" + directUrl;
|
||||
window.open(url, "_blank");
|
||||
jq('#hiddenFileName').val("");
|
||||
jq.unblockUI();
|
||||
@ -243,7 +256,7 @@ if (typeof jQuery != "undefined") {
|
||||
|
||||
jq(document).on("click", "#beginView:not(.disable)", function () {
|
||||
var fileId = encodeURIComponent(jq('#hiddenFileName').val());
|
||||
var url = "doceditor.php?action=view&fileID=" + fileId + "&user=" + user;
|
||||
var url = "doceditor.php?action=view&fileID=" + fileId + "&user=" + user + "&directUrl=" + directUrl;
|
||||
window.open(url, "_blank");
|
||||
jq('#hiddenFileName').val("");
|
||||
jq.unblockUI();
|
||||
@ -252,7 +265,7 @@ if (typeof jQuery != "undefined") {
|
||||
|
||||
jq(document).on("click", "#beginEmbedded:not(.disable)", function () {
|
||||
var fileId = encodeURIComponent(jq('#hiddenFileName').val());
|
||||
var url = "doceditor.php?type=embedded&fileID=" + fileId + "&user=" + user;
|
||||
var url = "doceditor.php?type=embedded&fileID=" + fileId + "&user=" + user + "&directUrl=" + directUrl;
|
||||
|
||||
jq("#mainProgress").addClass("embedded");
|
||||
jq("#beginEmbedded").addClass("disable");
|
||||
@ -330,12 +343,12 @@ if (typeof jQuery != "undefined") {
|
||||
if (hideTooltipTimeout != null) {
|
||||
clearTimeout(hideTooltipTimeout);
|
||||
}
|
||||
jq(".info").on("touchend", function () {
|
||||
jq("#info").on("touchend", function () {
|
||||
showUserTooltip(true);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
jq(".info").mouseover(function (event) {
|
||||
jq("#info").mouseover(function (event) {
|
||||
if (fileList.length > 0) {
|
||||
if (hideTooltipTimeout != null) {
|
||||
clearTimeout(hideTooltipTimeout);
|
||||
@ -359,6 +372,20 @@ if (typeof jQuery != "undefined") {
|
||||
}, 500);
|
||||
});
|
||||
}
|
||||
|
||||
jq(".info-tooltip").mouseover(function (event) {
|
||||
var target = event.target;
|
||||
var id = target.dataset.id ? target.dataset.id : target.id;
|
||||
var tooltip = target.dataset.tooltip;
|
||||
|
||||
jq("<div class='tooltip'>" + tooltip + "<div class='arrow'></div></div>").appendTo("body");
|
||||
|
||||
var top = jq("#" + id).offset().top + jq("#" + id).outerHeight() / 2 - jq("div.tooltip").outerHeight() / 2;
|
||||
var left = jq("#" + id).offset().left + jq("#" + id).outerWidth() + 20;
|
||||
jq("div.tooltip").css({"top": top, "left": left});
|
||||
}).mouseout(function () {
|
||||
jq("div.tooltip").remove();
|
||||
});
|
||||
}
|
||||
|
||||
function getUrlVars() {
|
||||
|
||||
@ -115,7 +115,8 @@ function processSave($data, $fileName, $userAddress) {
|
||||
|
||||
$saved = 1;
|
||||
|
||||
if (!(($new_data = file_get_contents($downloadUri)) === FALSE)) {
|
||||
if (!(($new_data = file_get_contents($downloadUri, false,
|
||||
stream_context_create(["http"=>["timeout"=>5]]))) === FALSE)) {
|
||||
$storagePath = getStoragePath($newFileName, $userAddress); // get the file path
|
||||
$histDir = getHistoryDir($storagePath); // get the path to the history direction
|
||||
$verDir = getVersionDir($histDir, getFileVersion($histDir)); // get the path to the file version
|
||||
@ -125,7 +126,8 @@ function processSave($data, $fileName, $userAddress) {
|
||||
rename(getStoragePath($fileName, $userAddress), $verDir . DIRECTORY_SEPARATOR . "prev" . $curExt); // get the path to the previous file version and rename the storage path with it
|
||||
file_put_contents($storagePath, $new_data, LOCK_EX); // save file to the storage directory
|
||||
|
||||
if ($changesData = file_get_contents($data->changesurl)) {
|
||||
if ($changesData = file_get_contents($data->changesurl, false,
|
||||
stream_context_create(["http"=>["timeout"=>5]]))) {
|
||||
file_put_contents($verDir . DIRECTORY_SEPARATOR . "diff.zip", $changesData, LOCK_EX); // save file changes to the diff.zip archive
|
||||
}
|
||||
|
||||
@ -190,7 +192,8 @@ function processForceSave($data, $fileName, $userAddress) {
|
||||
|
||||
$saved = 1;
|
||||
|
||||
if (!(($new_data = file_get_contents($downloadUri)) === FALSE)) {
|
||||
if (!(($new_data = file_get_contents($downloadUri, false,
|
||||
stream_context_create(["http"=>["timeout"=>5]]))) === FALSE)) {
|
||||
$baseNameWithoutExt = substr($fileName, 0, strlen($fileName) - strlen($curExt));
|
||||
$isSubmitForm = $data->forcesavetype == 3; // SubmitForm
|
||||
|
||||
|
||||
@ -91,7 +91,8 @@ LANGUAGES = {
|
||||
'sv': 'Swedish',
|
||||
'tr': 'Turkish',
|
||||
'uk': 'Ukrainian',
|
||||
'vi': 'Vietnamese'
|
||||
'vi': 'Vietnamese',
|
||||
'aa-AA': 'Test Language'
|
||||
}
|
||||
|
||||
if os.environ.get("EXAMPLE_DOMAIN"): # generates a link for example domain
|
||||
|
||||
@ -35,7 +35,7 @@ See the detailed guide to learn how to install Document Server [for Windows](htt
|
||||
```
|
||||
pip install Django==3.1.3
|
||||
pip install requests==2.25.0
|
||||
pip install pyjwt==2.3.0
|
||||
pip install pyjwt==2.6.0
|
||||
pip install python-magic
|
||||
```
|
||||
|
||||
|
||||
@ -211,7 +211,9 @@ def createFile(stream, path, req = None, meta = False):
|
||||
|
||||
# create file response
|
||||
def createFileResponse(response, path, req, meta):
|
||||
response.raise_for_status()
|
||||
status_code = response.status_code
|
||||
if status_code != 200: # checking status code
|
||||
raise RuntimeError('Document editing service returned status: %s' % status_code)
|
||||
with open(path, 'wb') as file:
|
||||
for chunk in response.iter_content(chunk_size=8192):
|
||||
file.write(chunk)
|
||||
@ -219,7 +221,7 @@ def createFileResponse(response, path, req, meta):
|
||||
|
||||
# save file from the given url
|
||||
def saveFileFromUri(uri, path, req = None, meta = False):
|
||||
resp = requests.get(uri, stream=True, verify = config.DOC_SERV_VERIFY_PEER)
|
||||
resp = requests.get(uri, stream=True, verify = config.DOC_SERV_VERIFY_PEER, timeout=5)
|
||||
createFileResponse(resp, path, req, meta)
|
||||
return
|
||||
|
||||
|
||||
@ -152,7 +152,7 @@ def getMeta(storagePath):
|
||||
return None
|
||||
|
||||
# get the document history of a given file
|
||||
def getHistoryObject(storagePath, filename, docKey, docUrl, req):
|
||||
def getHistoryObject(storagePath, filename, docKey, docUrl, isEnableDirectUrl, req):
|
||||
histDir = getHistoryDir(storagePath)
|
||||
version = getFileVersion(histDir)
|
||||
if version > 0: # if the file was modified (the file version is greater than 0)
|
||||
@ -184,7 +184,8 @@ def getHistoryObject(storagePath, filename, docKey, docUrl, req):
|
||||
}
|
||||
|
||||
dataObj['url'] = docUrl if i == version else getPublicHistUri(filename, i, "prev" + fileUtils.getFileExt(filename), req) # write file url to the data object
|
||||
dataObj['directUrl'] = docManager.getDownloadUrl(filename, req, False) if i == version else getPublicHistUri(filename, i, "prev" + fileUtils.getFileExt(filename), req, False) # write file direct url to the data object
|
||||
if isEnableDirectUrl:
|
||||
dataObj['directUrl'] = docManager.getDownloadUrl(filename, req, False) if i == version else getPublicHistUri(filename, i, "prev" + fileUtils.getFileExt(filename), req, False) # write file direct url to the data object
|
||||
|
||||
if i > 1: # check if the version number is greater than 1 (the file was modified)
|
||||
changes = json.loads(readFile(getChangesHistoryPath(prevVerDir))) # get the path to the changes.json file
|
||||
@ -201,6 +202,10 @@ def getHistoryObject(storagePath, filename, docKey, docUrl, req):
|
||||
'key': prev['key'],
|
||||
'url': prev['url'],
|
||||
'directUrl': prev['directUrl']
|
||||
} if isEnableDirectUrl else { # write key and url information about previous file version
|
||||
'fileType': prev['fileType'],
|
||||
'key': prev['key'],
|
||||
'url': prev['url']
|
||||
}
|
||||
dataObj['previous'] = prevInfo # write information about previous file version to the data object
|
||||
dataObj['changesUrl'] = getPublicHistUri(filename, i - 1, "diff.zip", req) # write the path to the diff.zip archive with differences in this file version
|
||||
|
||||
@ -58,7 +58,10 @@ def getConverterUri(docUri, fromExt, toExt, docKey, isAsync, filePass = None, la
|
||||
payload['token'] = jwtManager.encode(payload) # encode a payload object into a body token
|
||||
headers[jwtHeader] = f'Bearer {headerToken}' # add a header Authorization with a header token with Authorization prefix in it
|
||||
|
||||
response = requests.post(config.DOC_SERV_SITE_URL + config.DOC_SERV_CONVERTER_URL, json=payload, headers=headers, verify = config.DOC_SERV_VERIFY_PEER) # send the headers and body values to the converter and write the result to the response
|
||||
response = requests.post(config.DOC_SERV_SITE_URL + config.DOC_SERV_CONVERTER_URL, json=payload, headers=headers, verify = config.DOC_SERV_VERIFY_PEER, timeout=5) # send the headers and body values to the converter and write the result to the response
|
||||
status_code = response.status_code
|
||||
if status_code != 200: # checking status code
|
||||
raise RuntimeError('Convertation service returned status: %s' % status_code)
|
||||
json = response.json()
|
||||
|
||||
return getResponseUri(json)
|
||||
|
||||
@ -171,6 +171,7 @@ def rename(request):
|
||||
# edit a file
|
||||
def edit(request):
|
||||
filename = fileUtils.getFileName(request.GET['filename'])
|
||||
isEnableDirectUrl = request.GET['directUrl'].lower() in ("true") if 'directUrl' in request.GET else False
|
||||
|
||||
ext = fileUtils.getFileExt(filename)
|
||||
|
||||
@ -234,7 +235,7 @@ def edit(request):
|
||||
'document': {
|
||||
'title': filename,
|
||||
'url': docManager.getDownloadUrl(filename, request),
|
||||
'directUrl': directUrl,
|
||||
'directUrl': directUrl if isEnableDirectUrl else "",
|
||||
'fileType': ext[1:],
|
||||
'key': docKey,
|
||||
'info': infObj,
|
||||
@ -295,6 +296,9 @@ def edit(request):
|
||||
'fileType': 'png',
|
||||
'url': docManager.getServerUrl(True, request) + 'static/images/logo.png',
|
||||
'directUrl': docManager.getServerUrl(False, request) + 'static/images/logo.png'
|
||||
} if isEnableDirectUrl else {
|
||||
'fileType': 'png',
|
||||
'url': docManager.getServerUrl(True, request) + 'static/images/logo.png'
|
||||
}
|
||||
|
||||
# a document which will be compared with the current document
|
||||
@ -302,6 +306,9 @@ def edit(request):
|
||||
'fileType': 'docx',
|
||||
'url': docManager.getServerUrl(True, request) + 'static/sample.docx',
|
||||
'directUrl': docManager.getServerUrl(False, request) + 'static/sample.docx'
|
||||
} if isEnableDirectUrl else {
|
||||
'fileType': 'docx',
|
||||
'url': docManager.getServerUrl(True, request) + 'static/sample.docx'
|
||||
}
|
||||
|
||||
# recipient data for mail merging
|
||||
@ -309,6 +316,9 @@ def edit(request):
|
||||
'fileType': 'csv',
|
||||
'url': docManager.getServerUrl(True, request) + 'csv',
|
||||
'directUrl': docManager.getServerUrl(False, request) + 'csv'
|
||||
} if isEnableDirectUrl else {
|
||||
'fileType': 'csv',
|
||||
'url': docManager.getServerUrl(True, request) + 'csv'
|
||||
}
|
||||
|
||||
# users data for mentions
|
||||
@ -320,7 +330,7 @@ def edit(request):
|
||||
dataCompareFile['token'] = jwtManager.encode(dataCompareFile) # encode the dataCompareFile object into a token
|
||||
dataMailMergeRecipients['token'] = jwtManager.encode(dataMailMergeRecipients) # encode the dataMailMergeRecipients object into a token
|
||||
|
||||
hist = historyManager.getHistoryObject(storagePath, filename, docKey, fileUri, request) # get the document history
|
||||
hist = historyManager.getHistoryObject(storagePath, filename, docKey, fileUri, isEnableDirectUrl, request) # get the document history
|
||||
|
||||
context = { # the data that will be passed to the template
|
||||
'cfg': json.dumps(edConfig), # the document config in json format
|
||||
@ -358,8 +368,8 @@ def track(request):
|
||||
trackManager.processForceSave(body, filename, usAddr)
|
||||
|
||||
except Exception as e:
|
||||
response.setdefault('error', 1) # set the default error value as 1 (document key is missing or no document with such key could be found)
|
||||
response.setdefault('message', e.args[0])
|
||||
response.setdefault("error", 1) # set the default error value as 1 (document key is missing or no document with such key could be found)
|
||||
response.setdefault("message", str(e.args[0]))
|
||||
|
||||
response.setdefault('error', 0) # if no exceptions are raised, the default error value is 0 (no errors)
|
||||
# the response status is 200 if the changes are saved successfully; otherwise, it is equal to 500
|
||||
|
||||
@ -24,6 +24,8 @@
|
||||
|
||||
"""
|
||||
|
||||
import re
|
||||
import sys
|
||||
import config
|
||||
import json
|
||||
|
||||
@ -32,6 +34,12 @@ from django.shortcuts import render
|
||||
from src.utils import users
|
||||
from src.utils import docManager
|
||||
|
||||
def getDirectUrlParam(request):
|
||||
if ('directUrl' in request.GET):
|
||||
return request.GET['directUrl'].lower() in ("true")
|
||||
else:
|
||||
return False;
|
||||
|
||||
def default(request): # default parameters that will be passed to the template
|
||||
context = {
|
||||
'users': users.USERS,
|
||||
@ -40,6 +48,7 @@ def default(request): # default parameters that will be passed to the template
|
||||
'editExt': json.dumps(config.DOC_SERV_EDITED), # file extensions that can be edited
|
||||
'convExt': json.dumps(config.DOC_SERV_CONVERT), # file extensions that can be converted
|
||||
'files': docManager.getStoredFiles(request), # information about stored files
|
||||
'fillExt': json.dumps(config.DOC_SERV_FILLFORMS)
|
||||
'fillExt': json.dumps(config.DOC_SERV_FILLFORMS),
|
||||
'directUrl': str(getDirectUrlParam(request)).lower
|
||||
}
|
||||
return render(request, 'index.html', context) # execute the "index.html" template with context data and return http response in json format
|
||||
@ -175,7 +175,7 @@ label .checkbox {
|
||||
background-image: url("../images/file_docxf.svg");
|
||||
}
|
||||
|
||||
.create-sample {
|
||||
.side-option {
|
||||
color: #666666;
|
||||
line-height: 24px;
|
||||
}
|
||||
@ -749,3 +749,28 @@ html {
|
||||
.user-descr > b {
|
||||
margin-left: 25px;
|
||||
}
|
||||
|
||||
.tooltip {
|
||||
background: #FFFFFF;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0px 7px 25px rgba(85, 85, 85, 0.15);
|
||||
color: #666666;
|
||||
line-height: 160%;
|
||||
max-width: 455px;
|
||||
padding: 14px;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.tooltip ul {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.arrow {
|
||||
border-top: 8px solid transparent;
|
||||
border-bottom: 8px solid transparent;
|
||||
border-right: 8px solid #FFFFFF;
|
||||
left: -4px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
@ -24,11 +24,24 @@
|
||||
*
|
||||
*/
|
||||
|
||||
var directUrl;
|
||||
|
||||
if (typeof jQuery !== "undefined") {
|
||||
jq = jQuery.noConflict();
|
||||
|
||||
directUrl = getUrlVars()["directUrl"] == "true";
|
||||
|
||||
mustReload = false;
|
||||
|
||||
if (directUrl)
|
||||
jq("#directUrl").prop("checked", directUrl);
|
||||
else
|
||||
directUrl = jq("#directUrl").prop("checked");
|
||||
|
||||
jq("#directUrl").change(function() {
|
||||
window.location = "?directUrl=" + jq(this).prop("checked");
|
||||
});
|
||||
|
||||
jq(function () {
|
||||
jq("#fileupload").fileupload({
|
||||
dataType: "json",
|
||||
@ -226,7 +239,7 @@ if (typeof jQuery !== "undefined") {
|
||||
|
||||
jq(document).on("click", "#beginEdit:not(.disable)", function () {
|
||||
var fileId = encodeURIComponent(jq("#hiddenFileName").val());
|
||||
var url = UrlEditor + "?mode=edit&filename=" + fileId;
|
||||
var url = UrlEditor + "?mode=edit&filename=" + fileId+ "&directUrl=" + directUrl;
|
||||
window.open(url, "_blank");
|
||||
jq("#hiddenFileName").val("");
|
||||
jq.unblockUI();
|
||||
@ -234,7 +247,7 @@ if (typeof jQuery !== "undefined") {
|
||||
|
||||
jq(document).on("click", "#beginView:not(.disable)", function () {
|
||||
var fileId = encodeURIComponent(jq("#hiddenFileName").val());
|
||||
var url = UrlEditor + "?mode=view&filename=" + fileId;
|
||||
var url = UrlEditor + "?mode=view&filename=" + fileId+ "&directUrl=" + directUrl;
|
||||
window.open(url, "_blank");
|
||||
jq("#hiddenFileName").val("");
|
||||
jq.unblockUI();
|
||||
@ -242,7 +255,7 @@ if (typeof jQuery !== "undefined") {
|
||||
|
||||
jq(document).on("click", "#beginEmbedded:not(.disable)", function () {
|
||||
var fileId = encodeURIComponent(jq("#hiddenFileName").val());
|
||||
var url = UrlEditor + "?type=embedded&mode=embedded&filename=" + fileId;
|
||||
var url = UrlEditor + "?type=embedded&mode=embedded&filename=" + fileId + "&directUrl=" + directUrl;
|
||||
|
||||
jq("#mainProgress").addClass("embedded");
|
||||
jq("#beginEmbedded").addClass("disable");
|
||||
@ -304,12 +317,12 @@ if (typeof jQuery !== "undefined") {
|
||||
if (hideTooltipTimeout != null) {
|
||||
clearTimeout(hideTooltipTimeout);
|
||||
}
|
||||
jq(".info").on("touchend", function () {
|
||||
jq("#info").on("touchend", function () {
|
||||
showUserTooltip(true);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
jq(".info").mouseover(function (event) {
|
||||
jq("#info").mouseover(function (event) {
|
||||
if (fileList.length > 0) {
|
||||
if (hideTooltipTimeout != null) {
|
||||
clearTimeout(hideTooltipTimeout);
|
||||
@ -333,4 +346,29 @@ if (typeof jQuery !== "undefined") {
|
||||
}, 500);
|
||||
});
|
||||
}
|
||||
|
||||
function getUrlVars() {
|
||||
var vars = [], hash;
|
||||
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
|
||||
for (var i = 0; i < hashes.length; i++) {
|
||||
hash = hashes[i].split('=');
|
||||
vars.push(hash[0]);
|
||||
vars[hash[0]] = hash[1];
|
||||
}
|
||||
return vars;
|
||||
};
|
||||
|
||||
jq(".info-tooltip").mouseover(function (event) {
|
||||
var target = event.target;
|
||||
var id = target.dataset.id ? target.dataset.id : target.id;
|
||||
var tooltip = target.dataset.tooltip;
|
||||
|
||||
jq("<div class='tooltip'>" + tooltip + "<div class='arrow'></div></div>").appendTo("body");
|
||||
|
||||
var top = jq("#" + id).offset().top + jq("#" + id).outerHeight() / 2 - jq("div.tooltip").outerHeight() / 2;
|
||||
var left = jq("#" + id).offset().left + jq("#" + id).outerWidth() + 20;
|
||||
jq("div.tooltip").css({"top": top, "left": left});
|
||||
}).mouseout(function () {
|
||||
jq("div.tooltip").remove();
|
||||
});
|
||||
}
|
||||
@ -71,7 +71,7 @@
|
||||
<a class="try-editor form reload-page" target="_blank" data-type="docxf">Form template</a>
|
||||
</li>
|
||||
</ul>
|
||||
<label class="create-sample">
|
||||
<label class="side-option">
|
||||
<input type="checkbox" id="createSample" class="checkbox" />With sample content
|
||||
</label>
|
||||
</div>
|
||||
@ -86,7 +86,7 @@
|
||||
<tr>
|
||||
<td valign="middle">
|
||||
<span class="select-user">Username</span>
|
||||
<img class="info" src="{% static "images/info.svg" %}" />
|
||||
<img id="info" class="info" src="{% static "images/info.svg" %}" />
|
||||
<select class="select-user" id="user">
|
||||
{% for user in users %}
|
||||
<option value="{{ user.id }}">{% if user.name %} {{ user.name }} {% else %} Anonymous {% endif %} </option>
|
||||
@ -96,7 +96,10 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="middle">
|
||||
<span class="select-user">Language editors interface</span>
|
||||
<span class="select-user">Language</span>
|
||||
<img class="info info-tooltip" data-id="language"
|
||||
data-tooltip="Choose the language for ONLYOFFICE editors interface"
|
||||
src="{% static "images/info.svg" %}" />
|
||||
<select class="select-user" id="language">
|
||||
{% for key, val in languages.items %}
|
||||
<option value="{{ key }}">{{ val }}</option>
|
||||
@ -104,6 +107,14 @@
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="middle">
|
||||
<label class="side-option">
|
||||
<input id="directUrl" type="checkbox" class="checkbox" />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="{% static "images/info.svg" %}" />
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@ -153,42 +164,42 @@
|
||||
{% for file in files %}
|
||||
<tr class="tableRow" title="{{ file.title }} [{{file.version}}]">
|
||||
<td class="contentCells">
|
||||
<a class="stored-edit {{ file.type }}" href="edit?filename={{ file.title }}" target="_blank">
|
||||
<a class="stored-edit {{ file.type }}" href="edit?filename={{ file.title }}&directUrl={{ directUrl }}" target="_blank">
|
||||
<span>{{ file.title }}</span>
|
||||
</a>
|
||||
</td>
|
||||
{% if file.canEdit %}
|
||||
<td class="contentCells contentCells-icon">
|
||||
<a href="edit?filename={{ file.title }}&type=desktop&mode=edit" target="_blank">
|
||||
<a href="edit?filename={{ file.title }}&type=desktop&mode=edit&directUrl={{ directUrl }}" target="_blank">
|
||||
<img src="{% static "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="edit?filename={{ file.title }}&type=mobile&mode=edit" target="_blank">
|
||||
<a href="edit?filename={{ file.title }}&type=mobile&mode=edit&directUrl={{ directUrl }}" target="_blank">
|
||||
<img src="{% static "images/mobile.svg" %}" alt="Open in editor for mobile devices" title="Open in editor for mobile devices"/>
|
||||
</a>
|
||||
</td>
|
||||
<td class="contentCells contentCells-icon">
|
||||
<a href="edit?filename={{ file.title }}&type=desktop&mode=comment" target="_blank">
|
||||
<a href="edit?filename={{ file.title }}&type=desktop&mode=comment&directUrl={{ directUrl }}" target="_blank">
|
||||
<img src="{% static "images/comment.svg" %}" alt="Open in editor for comment" title="Open in editor for comment"/>
|
||||
</a>
|
||||
</td>
|
||||
{% if file.type == 'word' %}
|
||||
<td class="contentCells contentCells-icon">
|
||||
<a href="edit?filename={{ file.title }}&type=desktop&mode=review" target="_blank">
|
||||
<a href="edit?filename={{ file.title }}&type=desktop&mode=review&directUrl={{ directUrl }}" target="_blank">
|
||||
<img src="{% static "images/review.svg" %}" alt="Open in editor for review" title="Open in editor for review"/>
|
||||
</a>
|
||||
</td>
|
||||
{% elif file.type == 'cell' %}
|
||||
<td class="contentCells contentCells-icon">
|
||||
<a href="edit?filename={{ file.title }}&type=desktop&mode=filter" target="_blank">
|
||||
<a href="edit?filename={{ file.title }}&type=desktop&mode=filter&directUrl={{ directUrl }}" target="_blank">
|
||||
<img src="{% static "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>
|
||||
{% endif %}
|
||||
{% if file.type == 'word' %}
|
||||
<td class="contentCells contentCells-icon">
|
||||
<a href="edit?filename={{ file.title }}&type=desktop&mode=blockcontent" target="_blank">
|
||||
<a href="edit?filename={{ file.title }}&type=desktop&mode=blockcontent&directUrl={{ directUrl }}" target="_blank">
|
||||
<img src="{% static "images/block-content.svg" %}" alt="Open in editor without content control modification" title="Open in editor without content control modification"/>
|
||||
</a>
|
||||
</td>
|
||||
@ -200,7 +211,7 @@
|
||||
{% endif %}
|
||||
{% if file.isFillFormDoc %}
|
||||
<td class="contentCells contentCells-shift contentCells-icon firstContentCellShift">
|
||||
<a href="edit?filename={{ file.title }}&type=desktop&mode=fillForms" target="_blank">
|
||||
<a href="edit?filename={{ file.title }}&type=desktop&mode=fillForms&directUrl={{ directUrl }}" target="_blank">
|
||||
<img src="{% static "images/fill-forms.svg" %}" alt="Open in editor for filling in forms" title="Open in editor for filling in forms"/>
|
||||
</a>
|
||||
</td>
|
||||
@ -210,7 +221,7 @@
|
||||
{% elif file.isFillFormDoc %}
|
||||
<td class="contentCells contentCells-icon"></td>
|
||||
<td class="contentCells contentCells-icon">
|
||||
<a href="edit?filename={{ file.title }}&type=mobile&mode=fillForms" target="_blank">
|
||||
<a href="edit?filename={{ file.title }}&type=mobile&mode=fillForms&directUrl={{ directUrl }}" target="_blank">
|
||||
<img src="{% static "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>
|
||||
@ -218,7 +229,7 @@
|
||||
<td class="contentCells contentCells-icon"></td>
|
||||
<td class="contentCells contentCells-icon"></td>
|
||||
<td class="contentCells contentCells-icon">
|
||||
<a href="edit?filename={{ file.title }}&type=desktop&mode=fillForms" target="_blank">
|
||||
<a href="edit?filename={{ file.title }}&type=desktop&mode=fillForms&directUrl={{ directUrl }}" target="_blank">
|
||||
<img src="{% static "images/fill-forms.svg" %}" alt="Open in editor for filling in forms" title="Open in editor for filling in forms"/>
|
||||
</a>
|
||||
</td>
|
||||
@ -226,17 +237,17 @@
|
||||
<td class="contentCells contentCells-shift contentCells-icon contentCellsEmpty" colspan="6"></td>
|
||||
{% endif %}
|
||||
<td class="contentCells contentCells-icon firstContentCellViewers">
|
||||
<a href="edit?filename={{ file.title }}&type=desktop&mode=view" target="_blank">
|
||||
<a href="edit?filename={{ file.title }}&type=desktop&mode=view&directUrl={{ directUrl }}" target="_blank">
|
||||
<img src="{% static "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="edit?filename={{ file.title }}&type=mobile&mode=view" target="_blank">
|
||||
<a href="edit?filename={{ file.title }}&type=mobile&mode=view&directUrl={{ directUrl }}" target="_blank">
|
||||
<img src="{% static "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="edit?filename={{ file.title }}&type=embedded&mode=embedded" target="_blank">
|
||||
<a href="edit?filename={{ file.title }}&type=embedded&mode=embedded&directUrl={{ directUrl }}" target="_blank">
|
||||
<img src="{% static "images/embeded.svg" %}" alt="Open in embedded mode" title="Open in embedded mode"/>
|
||||
</a>
|
||||
</td>
|
||||
|
||||
@ -88,6 +88,7 @@ GEM
|
||||
digest (3.1.0)
|
||||
erubi (1.11.0)
|
||||
execjs (2.8.1)
|
||||
ffi (1.15.5)
|
||||
ffi (1.15.5-x64-mingw-ucrt)
|
||||
globalid (1.0.0)
|
||||
activesupport (>= 5.0)
|
||||
@ -127,7 +128,9 @@ GEM
|
||||
net-protocol
|
||||
timeout
|
||||
nio4r (2.5.8)
|
||||
nokogiri (1.13.8-x64-mingw-ucrt)
|
||||
nokogiri (1.13.9-x64-mingw-ucrt)
|
||||
racc (~> 1.4)
|
||||
nokogiri (1.13.9-x86_64-linux)
|
||||
racc (~> 1.4)
|
||||
psych (4.0.5)
|
||||
stringio
|
||||
@ -216,6 +219,7 @@ GEM
|
||||
|
||||
PLATFORMS
|
||||
x64-mingw-ucrt
|
||||
x86_64-linux
|
||||
|
||||
DEPENDENCIES
|
||||
byebug
|
||||
|
||||
@ -16,11 +16,35 @@
|
||||
*
|
||||
*/
|
||||
|
||||
var directUrl;
|
||||
var userId;
|
||||
|
||||
if (typeof jQuery != "undefined") {
|
||||
jq = jQuery.noConflict();
|
||||
|
||||
directUrl = getUrlVars()["directUrl"] == "true";
|
||||
userId = getUrlVars()["userId"];
|
||||
|
||||
mustReload = false;
|
||||
|
||||
if (directUrl)
|
||||
jq("#directUrl").prop("checked", directUrl);
|
||||
else
|
||||
directUrl = jq("#directUrl").prop("checked");
|
||||
|
||||
jq("#directUrl").change(function() {
|
||||
window.location = "?directUrl=" + jq(this).prop("checked") + "&userId=" + userId;
|
||||
});
|
||||
|
||||
if (userId)
|
||||
jq("#user").val(userId);
|
||||
else
|
||||
userId = jq("#user").val();
|
||||
|
||||
jq("#user").change(function() {
|
||||
window.location = "?directUrl=" + directUrl + "&userId=" + jq(this).val();
|
||||
});
|
||||
|
||||
jq(function () {
|
||||
jq('#fileupload').fileupload({
|
||||
dataType: 'json',
|
||||
@ -173,7 +197,6 @@ if (typeof jQuery != "undefined") {
|
||||
};
|
||||
|
||||
var initSelectors = function () {
|
||||
var userSel = jq("#user");
|
||||
var langSel = jq("#language");
|
||||
|
||||
function getCookie(name) {
|
||||
@ -186,14 +209,9 @@ if (typeof jQuery != "undefined") {
|
||||
document.cookie = name + "=" + value + "; expires=" + new Date(Date.now() + 1000 * 60 * 60 * 24 * 7).toUTCString(); //week
|
||||
}
|
||||
|
||||
var userId = getCookie("uid");
|
||||
if (userId) userSel.val(userId);
|
||||
var langId = getCookie("ulang");
|
||||
if (langId) langSel.val(langId);
|
||||
|
||||
userSel.on("change", function () {
|
||||
setCookie("uid", userSel.val());
|
||||
});
|
||||
langSel.on("change", function () {
|
||||
setCookie("ulang", langSel.val());
|
||||
});
|
||||
@ -218,7 +236,7 @@ if (typeof jQuery != "undefined") {
|
||||
|
||||
jq(document).on("click", "#beginEdit:not(.disable)", function () {
|
||||
var fileId = encodeURIComponent(jq('#hiddenFileName').val());
|
||||
var url = UrlEditor + "?fileName=" + fileId;
|
||||
var url = UrlEditor + "?fileName=" + fileId + "&directUrl=" + directUrl + "&userId=" + userId;
|
||||
window.open(url, "_blank");
|
||||
jq('#hiddenFileName').val("");
|
||||
jq.unblockUI();
|
||||
@ -226,7 +244,7 @@ if (typeof jQuery != "undefined") {
|
||||
|
||||
jq(document).on("click", "#beginView:not(.disable)", function () {
|
||||
var fileId = encodeURIComponent(jq('#hiddenFileName').val());
|
||||
var url = UrlEditor + "?editorsMode=view&fileName=" + fileId;
|
||||
var url = UrlEditor + "?editorsMode=view&fileName=" + fileId + "&directUrl=" + directUrl + "&userId=" + userId;
|
||||
window.open(url, "_blank");
|
||||
jq('#hiddenFileName').val("");
|
||||
jq.unblockUI();
|
||||
@ -234,7 +252,7 @@ if (typeof jQuery != "undefined") {
|
||||
|
||||
jq(document).on("click", "#beginEmbedded:not(.disable)", function () {
|
||||
var fileId = encodeURIComponent(jq('#hiddenFileName').val());
|
||||
var url = UrlEditor + "?editorsType=embedded&editorsMode=embedded&fileName=" + fileId;
|
||||
var url = UrlEditor + "?editorsType=embedded&editorsMode=embedded&fileName=" + fileId + "&directUrl=" + directUrl + "&userId=" + userId;
|
||||
|
||||
jq("#mainProgress").addClass("embedded");
|
||||
jq("#beginEmbedded").addClass("disable");
|
||||
@ -256,6 +274,9 @@ if (typeof jQuery != "undefined") {
|
||||
if (jq("#createSample").is(":checked")) {
|
||||
url += "&sample=true";
|
||||
}
|
||||
if (userId) {
|
||||
url += "&userId=" + userId;
|
||||
}
|
||||
var w = window.open(url, "_blank");
|
||||
w.onload = function () {
|
||||
window.location.reload();
|
||||
@ -286,6 +307,17 @@ if (typeof jQuery != "undefined") {
|
||||
}
|
||||
};
|
||||
|
||||
function getUrlVars() {
|
||||
var vars = [], hash;
|
||||
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
|
||||
for (var i = 0; i < hashes.length; i++) {
|
||||
hash = hashes[i].split('=');
|
||||
vars.push(hash[0]);
|
||||
vars[hash[0]] = hash[1];
|
||||
}
|
||||
return vars;
|
||||
};
|
||||
|
||||
var fileList = jq("tr.tableRow");
|
||||
|
||||
var mouseIsOverTooltip = false;
|
||||
@ -296,12 +328,12 @@ if (typeof jQuery != "undefined") {
|
||||
if (hideTooltipTimeout != null) {
|
||||
clearTimeout(hideTooltipTimeout);
|
||||
}
|
||||
jq(".info").on("touchend", function () {
|
||||
jq("#info").on("touchend", function () {
|
||||
showUserTooltip(true);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
jq(".info").mouseover(function (event) {
|
||||
jq("#info").mouseover(function (event) {
|
||||
if (fileList.length > 0) {
|
||||
if (hideTooltipTimeout != null) {
|
||||
clearTimeout(hideTooltipTimeout);
|
||||
@ -325,4 +357,18 @@ if (typeof jQuery != "undefined") {
|
||||
}, 500);
|
||||
});
|
||||
}
|
||||
|
||||
jq(".info-tooltip").mouseover(function (event) {
|
||||
var target = event.target;
|
||||
var id = target.dataset.id ? target.dataset.id : target.id;
|
||||
var tooltip = target.dataset.tooltip;
|
||||
|
||||
jq("<div class='tooltip'>" + tooltip + "<div class='arrow'></div></div>").appendTo("body");
|
||||
|
||||
var top = jq("#" + id).offset().top + jq("#" + id).outerHeight() / 2 - jq("div.tooltip").outerHeight() / 2;
|
||||
var left = jq("#" + id).offset().left + jq("#" + id).outerWidth() + 20;
|
||||
jq("div.tooltip").css({"top": top, "left": left});
|
||||
}).mouseout(function () {
|
||||
jq("div.tooltip").remove();
|
||||
});
|
||||
}
|
||||
@ -168,7 +168,7 @@ label .checkbox {
|
||||
background-image: url("file_docxf.svg");
|
||||
}
|
||||
|
||||
.create-sample {
|
||||
.side-option {
|
||||
color: #666666;
|
||||
line-height: 24px;
|
||||
}
|
||||
@ -742,3 +742,28 @@ html {
|
||||
.user-descr > b {
|
||||
margin-left: 25px;
|
||||
}
|
||||
|
||||
.tooltip {
|
||||
background: #FFFFFF;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0px 7px 25px rgba(85, 85, 85, 0.15);
|
||||
color: #666666;
|
||||
line-height: 160%;
|
||||
max-width: 455px;
|
||||
padding: 14px;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.tooltip ul {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.arrow {
|
||||
border-top: 8px solid transparent;
|
||||
border-bottom: 8px solid transparent;
|
||||
border-right: 8px solid #FFFFFF;
|
||||
left: -4px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
@ -24,9 +24,8 @@ class HomeController < ApplicationController
|
||||
def editor
|
||||
|
||||
DocumentHelper.init(request.remote_ip, request.base_url)
|
||||
user = Users.get_user(cookies[:uid])
|
||||
|
||||
@file = FileModel.new(:file_name => File.basename(params[:fileName]), :mode => params[:editorsMode], :type => params[:editorsType], :user_ip => request.remote_ip, :lang => cookies[:ulang], :user => user, :action_data => params[:actionLink])
|
||||
user = Users.get_user(params[:userId])
|
||||
@file = FileModel.new(:file_name => File.basename(params[:fileName]), :mode => params[:editorsMode], :type => params[:editorsType], :user_ip => request.remote_ip, :lang => cookies[:ulang], :user => user, :action_data => params[:actionLink], :direct_url => params[:directUrl])
|
||||
|
||||
end
|
||||
|
||||
@ -34,10 +33,9 @@ class HomeController < ApplicationController
|
||||
def sample
|
||||
|
||||
DocumentHelper.init(request.remote_ip, request.base_url)
|
||||
user = Users.get_user(cookies[:uid])
|
||||
|
||||
user = Users.get_user(params[:userId])
|
||||
file_name = DocumentHelper.create_demo(params[:fileExt], params[:sample], user)
|
||||
redirect_to :controller => 'home', :action => 'editor', :fileName => file_name
|
||||
redirect_to :controller => 'home', :action => 'editor', :fileName => file_name, :userId => user.id
|
||||
|
||||
end
|
||||
|
||||
@ -73,7 +71,7 @@ class HomeController < ApplicationController
|
||||
end
|
||||
|
||||
# create file meta information
|
||||
user = Users.get_user(cookies[:uid])
|
||||
user = Users.get_user(params[:userId])
|
||||
|
||||
DocumentHelper.create_meta(file_name, user.id, user.name, nil)
|
||||
|
||||
@ -134,7 +132,7 @@ class HomeController < ApplicationController
|
||||
end
|
||||
|
||||
file_name = correct_name
|
||||
user = Users.get_user(cookies[:uid])
|
||||
user = Users.get_user(params[:userId])
|
||||
|
||||
DocumentHelper.create_meta(file_name, user.id, user.name, nil) # create meta data of the new file
|
||||
end
|
||||
@ -335,7 +333,7 @@ class HomeController < ApplicationController
|
||||
File.open(DocumentHelper.storage_path(file_name, nil), 'wb') do |file|
|
||||
file.write(data)
|
||||
end
|
||||
user = Users.get_user(cookies[:uid])
|
||||
user = Users.get_user(params[:userId])
|
||||
DocumentHelper.create_meta(file_name, user.id, user.name, nil) # create meta data of the new file
|
||||
|
||||
render plain: '{"file" : "' + file_name + '"}'
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
|
||||
class FileModel
|
||||
|
||||
attr_accessor :file_name, :mode, :type, :user_ip, :lang, :user, :action_data
|
||||
attr_accessor :file_name, :mode, :type, :user_ip, :lang, :user, :action_data, :direct_url
|
||||
|
||||
# set file parameters
|
||||
def initialize(attributes = {})
|
||||
@ -27,6 +27,7 @@ class FileModel
|
||||
@lang = attributes[:lang]
|
||||
@user = attributes[:user]
|
||||
@action_data = attributes[:action_data]
|
||||
@direct_url = attributes[:direct_url]
|
||||
end
|
||||
|
||||
def type
|
||||
@ -110,7 +111,7 @@ class FileModel
|
||||
:document => {
|
||||
:title => @file_name,
|
||||
:url => download_url,
|
||||
:directUrl => download_url(false),
|
||||
:directUrl => is_enable_direct_url ? download_url(false) : "",
|
||||
:fileType => file_ext.delete("."),
|
||||
:key => key,
|
||||
:info => {
|
||||
@ -224,7 +225,9 @@ class FileModel
|
||||
dataObj["fileType"] = file_ext[1..file_ext.length]
|
||||
dataObj["key"] = cur_key
|
||||
dataObj["url"] = i == cur_ver ? doc_uri : DocumentHelper.get_historypath_uri(file_name, i, "prev#{file_ext}")
|
||||
dataObj["directUrl"] = i == cur_ver ? download_url(false) : DocumentHelper.get_historypath_uri(file_name, i, "prev#{file_ext}", false)
|
||||
if is_enable_direct_url == true
|
||||
dataObj["directUrl"] = i == cur_ver ? download_url(false) : DocumentHelper.get_historypath_uri(file_name, i, "prev#{file_ext}", false)
|
||||
end
|
||||
dataObj["version"] = i
|
||||
|
||||
if (i > 1) # check if the version number is greater than 1
|
||||
@ -243,11 +246,15 @@ class FileModel
|
||||
obj["user"] = change ? change["user"] : nil
|
||||
|
||||
prev = histData[(i - 2).to_s] # get the history data from the previous file version
|
||||
dataObj["previous"] = { # write key and url information about previous file version
|
||||
dataObj["previous"] = is_enable_direct_url == true ? { # write key and url information about previous file version with optional direct url
|
||||
:fileType => prev["fileType"],
|
||||
:key => prev["key"],
|
||||
:url => prev["url"],
|
||||
:directUrl => prev["directUrl"]
|
||||
} : {
|
||||
:fileType => prev["fileType"],
|
||||
:key => prev["key"],
|
||||
:url => prev["url"]
|
||||
}
|
||||
|
||||
# write the path to the diff.zip archive with differences in this file version
|
||||
@ -276,11 +283,14 @@ class FileModel
|
||||
end
|
||||
|
||||
# get image information
|
||||
def get_insert_image
|
||||
insert_image = {
|
||||
def get_insert_image
|
||||
insert_image = is_enable_direct_url == true ? {
|
||||
:fileType => "png", # image file type
|
||||
:url => DocumentHelper.get_server_url(true) + "/assets/logo.png", # server url to the image
|
||||
:directUrl => DocumentHelper.get_server_url(false) + "/assets/logo.png" # direct url to the image
|
||||
} : {
|
||||
:fileType => "png", # image file type
|
||||
:url => DocumentHelper.get_server_url(true) + "/assets/logo.png" # server url to the image
|
||||
}
|
||||
|
||||
if JwtHelper.is_enabled # check if a secret key to generate token exists or not
|
||||
@ -292,10 +302,13 @@ class FileModel
|
||||
|
||||
# get compared file information
|
||||
def get_compare_file
|
||||
compare_file = {
|
||||
compare_file = is_enable_direct_url == true ? {
|
||||
:fileType => "docx", # file type
|
||||
:url => DocumentHelper.get_server_url(true) + "/assets/sample/sample.docx", # server url to the compared file
|
||||
:directUrl => DocumentHelper.get_server_url(false) + "/assets/sample/sample.docx" # direct url to the compared file
|
||||
} : {
|
||||
:fileType => "docx", # file type
|
||||
:url => DocumentHelper.get_server_url(true) + "/assets/sample/sample.docx" # server url to the compared file
|
||||
}
|
||||
|
||||
if JwtHelper.is_enabled # check if a secret key to generate token exists or not
|
||||
@ -307,10 +320,13 @@ class FileModel
|
||||
|
||||
# get mail merge recipients information
|
||||
def dataMailMergeRecipients
|
||||
dataMailMergeRecipients = {
|
||||
dataMailMergeRecipients = is_enable_direct_url == true ? {
|
||||
:fileType => "csv", # file type
|
||||
:url => DocumentHelper.get_server_url(true) + "/csv", # server url to the mail merge recipients file
|
||||
:directUrl => DocumentHelper.get_server_url(false) + "/csv" # direct url to the mail merge recipients file
|
||||
} : {
|
||||
:fileType => "csv", # file type
|
||||
:url => DocumentHelper.get_server_url(true) + "/csv" # server url to the mail merge recipients file
|
||||
}
|
||||
|
||||
if JwtHelper.is_enabled # check if a secret key to generate token exists or not
|
||||
@ -325,4 +341,9 @@ class FileModel
|
||||
return !@user.id.eql?("uid-0") ? Users.get_users_for_mentions(@user.id) : nil
|
||||
end
|
||||
|
||||
# get direct url existence flag
|
||||
def is_enable_direct_url
|
||||
return @direct_url != nil && @direct_url == "true"
|
||||
end
|
||||
|
||||
end
|
||||
@ -54,6 +54,7 @@ class ServiceConverter
|
||||
DocumentHelper.verify_ssl(@@document_converter_url, http)
|
||||
|
||||
http.read_timeout = @@convert_timeout
|
||||
http.open_timeout = 5
|
||||
req = Net::HTTP::Post.new(uri.request_uri) # create the post request
|
||||
req.add_field("Accept", "application/json") # set headers
|
||||
req.add_field("Content-Type", "application/json")
|
||||
@ -66,6 +67,12 @@ class ServiceConverter
|
||||
|
||||
req.body = payload.to_json
|
||||
res = http.request(req) # get the response
|
||||
|
||||
status_code = res.code
|
||||
if status_code != 200 # checking status code
|
||||
raise "Conversion service returned status: #{status_code}"
|
||||
end
|
||||
|
||||
data = res.body # and take its body
|
||||
rescue TimeoutError
|
||||
# try again
|
||||
|
||||
@ -251,11 +251,17 @@ class TrackHelper
|
||||
def save_from_uri(path, uristr)
|
||||
uri = URI.parse(uristr) # parse the url string
|
||||
http = Net::HTTP.new(uri.host, uri.port) # create a connection to the http server
|
||||
http.open_timeout = 5
|
||||
|
||||
DocumentHelper.verify_ssl(uristr, http)
|
||||
|
||||
req = Net::HTTP::Get.new(uri)
|
||||
res = http.request(req) # get the response
|
||||
|
||||
status_code = res.code
|
||||
if status_code != 200 # checking status code
|
||||
raise "Document editing service returned status: #{status_code}"
|
||||
end
|
||||
data = res.body # and take its body
|
||||
|
||||
if data == nil
|
||||
|
||||
@ -44,7 +44,7 @@
|
||||
<a class="try-editor form" data-type="docxf">Form template</a>
|
||||
</li>
|
||||
</ul>
|
||||
<label class="create-sample">
|
||||
<label class="side-option">
|
||||
<input id="createSample" class="checkbox" type="checkbox" />With sample content
|
||||
</label>
|
||||
</div>
|
||||
@ -60,7 +60,7 @@
|
||||
<tr>
|
||||
<td valign="middle">
|
||||
<span class="select-user">Username</span>
|
||||
<img class="info" data-id="user" src="assets/info.svg" />
|
||||
<img id="info" class="info" data-id="user" src="assets/info.svg" />
|
||||
<select class="select-user" id="user">
|
||||
<% for user in Users.get_all_users() do %>
|
||||
<option value="<%= user.id %>"><%= user.name ? user.name : "Anonymous" %></option>
|
||||
@ -70,7 +70,10 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="middle">
|
||||
<span class="select-user">Language editors interface</span>
|
||||
<span class="select-user">Language</span>
|
||||
<img class="info info-tooltip" data-id="language"
|
||||
data-tooltip="Choose the language for ONLYOFFICE editors interface"
|
||||
src="assets/info.svg" />
|
||||
<select class="select-user" id="language">
|
||||
<% Rails.configuration.languages.each { |key, language|%>
|
||||
<option value="<%=key %>"> <%=language %> </option>
|
||||
@ -78,6 +81,14 @@
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="middle">
|
||||
<label class="side-option">
|
||||
<input id="directUrl" type="checkbox" class="checkbox" />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="assets/info.svg" />
|
||||
</label>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@ -87,6 +98,8 @@
|
||||
<%
|
||||
DocumentHelper.init(request.remote_ip, request.base_url)
|
||||
docs = DocumentHelper.get_stored_files(nil)
|
||||
directUrl = request.params[:directUrl]
|
||||
userId = request.params[:userId]
|
||||
%>
|
||||
<div class="main-panel">
|
||||
<div id="portal-info" style="display: <%= docs.length > 0 ? "none" : "table-cell" %>">
|
||||
@ -128,7 +141,9 @@
|
||||
<%
|
||||
docs.each { |d|
|
||||
isFillFormDoc = DocumentHelper.fill_forms_exts.include?(File.extname(d).downcase)
|
||||
editUrl = "editor?fileName=#{ERB::Util.url_encode(d)}"
|
||||
userIdParam = userId == nil ? "" : "&userId=#{userId}";
|
||||
directUrlParam = directUrl == nil ? "" : "&directUrl=#{directUrl}";
|
||||
editUrl = "editor?fileName=#{ERB::Util.url_encode(d)}" + directUrlParam + userIdParam;
|
||||
docType = FileUtility.get_file_type(d)
|
||||
canEdit = DocumentHelper.edited_exts.include?(File.extname(d).downcase) %>
|
||||
<tr class="tableRow" title="<%= d %> [<%= DocumentHelper.get_file_version(DocumentHelper.history_dir(DocumentHelper.storage_path(d, nil))) %>]">
|
||||
|
||||
@ -88,7 +88,8 @@ module OnlineEditorsExampleRuby
|
||||
'sv' => 'Swedish',
|
||||
'tr' => 'Turkish',
|
||||
'uk' => 'Ukrainian',
|
||||
'vi' => 'Vietnamese'
|
||||
'vi' => 'Vietnamese',
|
||||
'aa-AA' => 'Test Language'
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user