Move patches && remove welcome page for prod
/ create-package (push) Successful in 15m19s
Details
/ create-package (push) Successful in 15m19s
Details
parent
cd49aab3fe
commit
c84be1bced
56
Dockerfile
56
Dockerfile
|
|
@ -20,18 +20,14 @@ RUN apt-get update && \
|
|||
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list && \
|
||||
apt-get update && \
|
||||
apt-get install -y ${build_deps} && \
|
||||
npm install -g pkg grunt grunt-cli
|
||||
|
||||
|
||||
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
npm install -g pkg grunt grunt-cli && \
|
||||
apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||
|
||||
RUN node -v
|
||||
RUN npm -v
|
||||
|
||||
WORKDIR /build
|
||||
|
||||
|
||||
|
||||
## Clone
|
||||
FROM setup-stage as clone-stage
|
||||
|
||||
|
|
@ -44,50 +40,56 @@ RUN git config --global advice.detachedHead false && \
|
|||
git clone --quiet --branch $tag --depth 1 https://github.com/ONLYOFFICE/web-apps.git /build/web-apps
|
||||
|
||||
|
||||
# Patch Server
|
||||
COPY patches/server /build/server/patches
|
||||
# Needs a fake author to allow commits
|
||||
RUN git config --global user.email "contact@workstreams.ch" && \
|
||||
git config --global user.name "WS-Bot" && \
|
||||
cd /build/server && \
|
||||
git am --ignore-whitespace patches/*.patch && \
|
||||
make
|
||||
|
||||
COPY server.patch /build/
|
||||
COPY web-apps.patch /build/
|
||||
|
||||
RUN cd /build/server && git apply /build/server.patch
|
||||
RUN cd /build/web-apps && git apply /build/web-apps.patch
|
||||
|
||||
## Build
|
||||
FROM clone-stage as build-stage
|
||||
|
||||
# build server with license checks patched
|
||||
WORKDIR /build/server
|
||||
RUN make
|
||||
RUN pkg /build/build_tools/out/linux_64/onlyoffice/documentserver/server/FileConverter --targets=node16-linux -o /build/converter
|
||||
RUN pkg /build/build_tools/out/linux_64/onlyoffice/documentserver/server/DocService --targets=node16-linux --options max_old_space_size=4096 -o /build/docservice
|
||||
RUN make && \
|
||||
pkg /build/build_tools/out/linux_64/onlyoffice/documentserver/server/FileConverter --targets=node16-linux -o /build/converter && \
|
||||
pkg /build/build_tools/out/linux_64/onlyoffice/documentserver/server/DocService --targets=node16-linux --options max_old_space_size=4096 -o /build/docservice
|
||||
|
||||
|
||||
# build web-apps with mobile editing
|
||||
WORKDIR /build/web-apps/build
|
||||
RUN npm install
|
||||
RUN grunt --addon=web-apps-mobile
|
||||
RUN cd /build/web-apps/build && npm install
|
||||
COPY patches/web-apps /build/web-apps/patches
|
||||
COPY patches/web-apps-mobile /build/web-apps-mobile
|
||||
|
||||
RUN ls -l /build/web-apps/deploy/web-apps/apps/documenteditor/mobile/
|
||||
RUN ls -l /build/web-apps/deploy/web-apps/apps/presentationeditor/mobile/
|
||||
RUN ls -l /build/web-apps/deploy/web-apps/apps/spreadsheeteditor/mobile/
|
||||
RUN cd /build/web-apps && \
|
||||
git am --ignore-whitespace patches/*.patch && \
|
||||
cd /build/web-apps/build && grunt --addon=web-apps-mobile
|
||||
|
||||
## Final image
|
||||
FROM onlyoffice/documentserver:${product_version}.${build_number}
|
||||
ARG oo_root
|
||||
ARG COMPANY_NAME=onlyoffice
|
||||
ARG PRODUCT_NAME=documentserver
|
||||
ARG DS_SUPERVISOR_CONF=/etc/supervisor/conf.d/ds.conf
|
||||
|
||||
# Remove all documentserver-example data
|
||||
RUN rm -rf /var/www/$COMPANY_NAME/$PRODUCT_NAME-example \
|
||||
&& rm -rf /etc/$COMPANY_NAME/$PRODUCT_NAME-example \
|
||||
&& rm -f $DS_SUPERVISOR_CONF \
|
||||
&& rm -f /etc/nginx/includes/ds-example.conf \
|
||||
&& ln -s /etc/$COMPANY_NAME/$PRODUCT_NAME/supervisor/ds.conf $DS_SUPERVISOR_CONF
|
||||
|
||||
# server
|
||||
COPY --from=build-stage --chown=ds:ds /build/converter ${oo_root}/server/FileConverter/converter
|
||||
COPY --from=build-stage --chown=ds:ds /build/docservice ${oo_root}/server/DocService/docservice
|
||||
|
||||
|
||||
# web-apps
|
||||
COPY --from=build-stage --chown=ds:ds /build/web-apps/deploy/web-apps/apps/documenteditor/mobile ${oo_root}/web-apps/apps/documenteditor/mobile
|
||||
COPY --from=build-stage --chown=ds:ds /build/web-apps/deploy/web-apps/apps/presentationeditor/mobile ${oo_root}/web-apps/apps/presentationeditor/mobile
|
||||
COPY --from=build-stage --chown=ds:ds /build/web-apps/deploy/web-apps/apps/spreadsheeteditor/mobile ${oo_root}/web-apps/apps/spreadsheeteditor/mobile
|
||||
|
||||
COPY local-production-linux.json /etc/onlyoffice/documentserver/local-production-linux.json
|
||||
|
||||
# Replace welcome page
|
||||
COPY welcome.html ${oo_root}/web-apps/welcome/index.html
|
||||
COPY favicon.ico ${oo_root}/web-apps/welcome/favicon.ico
|
||||
COPY ws-logo.png ${oo_root}/web-apps/welcome/ws-logo.png
|
||||
COPY AGPLv3_Logo.svg.png ${oo_root}/web-apps/welcome/AGPLv3_Logo.svg.png
|
||||
|
|
@ -34,9 +34,9 @@ git clone --recursive https://git2.workstreams.ch/workstreams/wsoffice
|
|||
Create a Git patch for each repository
|
||||
```
|
||||
cd DocumentServer/server/
|
||||
git diff > ../../server.patch
|
||||
git format-patch -1 -o ../../patches/server/
|
||||
cd DocumentServer/web-apps/
|
||||
git diff > ../../web-apps.patch
|
||||
git format-patch -1 -o ../../patches/wed-apps/
|
||||
```
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,17 @@
|
|||
From fd17b0f68640cb90b81f516af52ab71e0242d410 Mon Sep 17 00:00:00 2001
|
||||
From: Fabrice <fabrice.roublot@workstreams.ch>
|
||||
Date: Mon, 14 Oct 2024 16:57:02 +0200
|
||||
Subject: [PATCH] fix licences
|
||||
|
||||
---
|
||||
Common/sources/commondefines.js | 4 ++--
|
||||
Common/sources/constants.js | 6 +++---
|
||||
Common/sources/license.js | 20 ++++++++++----------
|
||||
FileConverter/package.json | 3 ++-
|
||||
Makefile | 3 ++-
|
||||
package.json | 6 +++---
|
||||
6 files changed, 22 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/Common/sources/commondefines.js b/Common/sources/commondefines.js
|
||||
index fc8756b9..c1a9a7ff 100644
|
||||
--- a/Common/sources/commondefines.js
|
||||
|
|
@ -136,3 +150,6 @@ index 78c3c50d..36593a55 100644
|
|||
-}
|
||||
+}
|
||||
\ No newline at end of file
|
||||
--
|
||||
2.30.2
|
||||
|
||||
|
|
@ -0,0 +1,558 @@
|
|||
import React, {Fragment} from 'react';
|
||||
import {Link} from 'framework7-react';
|
||||
import { Device } from '../../web-apps/apps/common/mobile/utils/device';
|
||||
|
||||
const EditorUIController = () => {
|
||||
return null
|
||||
};
|
||||
|
||||
EditorUIController.isSupportEditFeature = () => {
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
This is the file where the magic happens.
|
||||
Try to figure out a working version from a both the old commits
|
||||
and my hunches from hacking around in the old webapp editor
|
||||
|
||||
https://github.com/ONLYOFFICE/web-apps/commit/7c72e8cb1b3e06ac72b0e7156d33b8a8d3206dc4
|
||||
*/
|
||||
|
||||
EditorUIController.toolbarOptions = {
|
||||
// This implementation is likely incomplete, since wsProps, focusOn, isShapeLocked are currently ununsed
|
||||
// and wsProps was specifically added to the options given to getEditOptions in order to handle protection
|
||||
// https://github.com/ONLYOFFICE/web-apps/commit/1508b2ee641e9f8e633628dfe7e76bfe8a2f82b2#diff-9358b4112e282a95c6f9568c509cfa89d866b92701dfd5d347349ad85971e53eR31
|
||||
// wsProps contains severals properties that are true if specific protection is enabled
|
||||
getEditOptions: (options) => {
|
||||
// console.log('EditorUIController.toolbarOptions.getEditOptions' ,options);
|
||||
return (
|
||||
<Fragment>
|
||||
<Link className={options.disabled && 'disabled'} id='btn-edit' icon='icon-edit-settings' href={false} onClick={() => options.onEditClick()}></Link>
|
||||
<Link className={options.disabled && 'disabled'} id='btn-add' icon='icon-plus' href={false} onClick={() => options.onAddClick()}></Link>
|
||||
</Fragment>
|
||||
);
|
||||
},
|
||||
|
||||
getUndoRedo: (options) => {
|
||||
return (
|
||||
<Fragment>
|
||||
<Link icon='icon-undo' className={options.disabledUndo && 'disabled'} onClick={() => options.onUndoClick()}></Link>
|
||||
<Link icon='icon-redo' className={options.disabledRedo && 'disabled'} onClick={() => options.onRedoClick()}></Link>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
EditorUIController.initCellInfo = (props) => {
|
||||
// console.log('EditorUIController.initCellInfo', props);
|
||||
|
||||
const storeFocusObjects = props.storeFocusObjects;
|
||||
const storeCellSettings = props.storeCellSettings;
|
||||
const storeTextSettings = props.storeTextSettings;
|
||||
const storeChartSettings = props.storeChartSettings;
|
||||
const api = Common.EditorApi.get();
|
||||
|
||||
storeFocusObjects.intf = EditorUIController.Intf(storeFocusObjects);
|
||||
|
||||
api.asc_registerCallback('asc_onSelectionChanged', cellInfo => {
|
||||
// console.log("asc_onSelectionChanged",cellInfo);
|
||||
// console.log('storeFocusObjects', {
|
||||
// 'isLocked': storeFocusObjects.isLocked,
|
||||
// 'isLockedText': storeFocusObjects.isLockedText,
|
||||
// 'isLockedShaped': storeFocusObjects.isLockedShaped,
|
||||
// 'editFormulaMode': storeFocusObjects.editFormulaMode,
|
||||
// 'isEditCell': storeFocusObjects.isEditCell,
|
||||
// 'functionDisabled': storeFocusObjects.functionDisabled
|
||||
// });
|
||||
|
||||
// TODO Not sure if good idea or not but maybe we should check if cell is locked
|
||||
// In that case, get the protected ranges and see if we should allow to select
|
||||
// that cell.
|
||||
// const api = Common.EditorApi.get();
|
||||
|
||||
// console.log({
|
||||
// 'api.asc_isProtectedSheet': api.asc_isProtectedSheet(),
|
||||
// 'api.asc_checkLockedCells': api.asc_checkLockedCells(),
|
||||
// 'shouldCheckProtectedRanges': api.asc_isProtectedSheet() && api.asc_checkLockedCells(),
|
||||
// 'iscelllocked': api.asc_isProtectedSheet() && api.asc_checkLockedCells() ? api.asc_checkProtectedRange() : false
|
||||
// });
|
||||
|
||||
// This changes the type of the selected focus to show different edit views.
|
||||
// The edit views needs the focusOn value to be set.
|
||||
// Since this change was made after the mobile editor has been made private, I'm not
|
||||
// sure if this is the way to know if the selection is a cell or an object but this
|
||||
// seems to work. this old commit shows how changeFocus used to work:
|
||||
// https://github.com/ONLYOFFICE/web-apps/commit/050c03096243448b040fc676cd350c090a1a8c59
|
||||
const isObject = cellInfo.asc_getSelectionType() !== Asc.c_oAscSelectionType.RangeCells;
|
||||
storeFocusObjects.changeFocus(isObject);
|
||||
|
||||
storeFocusObjects.resetCellInfo(cellInfo);
|
||||
storeCellSettings.initCellSettings(cellInfo);
|
||||
storeTextSettings.initTextSettings(cellInfo);
|
||||
|
||||
let selectedObjects = Common.EditorApi.get().asc_getGraphicObjectProps();
|
||||
|
||||
if(selectedObjects.length) {
|
||||
storeFocusObjects.resetFocusObjects(selectedObjects);
|
||||
|
||||
// Chart Settings
|
||||
|
||||
if (storeFocusObjects.chartObject) {
|
||||
storeChartSettings.updateChartStyles(api.asc_getChartPreviews(storeFocusObjects.chartObject.get_ChartProperties().getType()));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
EditorUIController.initFonts = (props) => {
|
||||
// console.log('EditorUIController.initFonts', storeTextSettings);
|
||||
|
||||
const storeCellSettings = props.storeCellSettings;
|
||||
const storeTextSettings = props.storeTextSettings;
|
||||
const api = Common.EditorApi.get();
|
||||
api.asc_registerCallback('asc_onInitEditorFonts', (fonts, select) => {
|
||||
// console.log('asc_onInitEditorFonts', fonts, select);
|
||||
storeCellSettings.initEditorFonts(fonts, select);
|
||||
storeTextSettings.initEditorFonts(fonts, select);
|
||||
});
|
||||
|
||||
// Maybe this go here ?
|
||||
api.asc_registerCallback('asc_onEditorSelectionChanged', fontObj => {
|
||||
// console.log(fontObj)
|
||||
storeCellSettings.initFontInfo(fontObj);
|
||||
storeTextSettings.initFontInfo(fontObj);
|
||||
});
|
||||
};
|
||||
EditorUIController.initEditorStyles = (storeCellSettings) => {
|
||||
// console.log('EditorUIController.initEditorStyles', storeCellSettings);
|
||||
|
||||
const api = Common.EditorApi.get();
|
||||
api.asc_registerCallback('asc_onInitEditorStyles', styles => {
|
||||
storeCellSettings.initCellStyles(styles);
|
||||
});
|
||||
}
|
||||
|
||||
EditorUIController.initThemeColors = () => {
|
||||
// console.log('EditorUIController.initThemeColors');
|
||||
const api = Common.EditorApi.get();
|
||||
api.asc_registerCallback('asc_onSendThemeColors', (colors, standart_colors) => {
|
||||
// console.log('asc_onSendThemeColors', colors, standart_colors);
|
||||
Common.Utils.ThemeColor.setColors(colors, standart_colors);
|
||||
});
|
||||
}
|
||||
|
||||
EditorUIController.ContextMenu = {
|
||||
// https://github.com/ONLYOFFICE/web-apps/commit/588a7f03863ebf9ec3251a36decc8b4e280dda59
|
||||
mapMenuItems: (contextMenu) => {
|
||||
// console.log('EditorUIController.ContextMenu.mapMenuItems', contextMenu);
|
||||
|
||||
if ( !Common.EditorApi ) return [];
|
||||
|
||||
const { t } = contextMenu.props;
|
||||
const _t = t("ContextMenu", { returnObjects: true });
|
||||
|
||||
const { canViewComments } = contextMenu.props;
|
||||
|
||||
const api = Common.EditorApi.get();
|
||||
const cellinfo = api.asc_getCellInfo();
|
||||
|
||||
const itemsIcon = [];
|
||||
const itemsText = [];
|
||||
|
||||
let iscellmenu, isrowmenu, iscolmenu, isallmenu, ischartmenu, isimagemenu, istextshapemenu, isshapemenu, istextchartmenu;
|
||||
let iscelllocked = cellinfo.asc_getLocked();
|
||||
const seltype = cellinfo.asc_getSelectionType();
|
||||
const xfs = cellinfo.asc_getXfs();
|
||||
const isComments = cellinfo.asc_getComments().length > 0; //prohibit adding multiple comments in one cell;
|
||||
|
||||
// Check if the individual cell is locked
|
||||
// This code is taken from ./web-apps/apps/spreadsheeteditor/main/app/controller/Main.js
|
||||
// It seems that api.asc_checkProtectedRange() returns null if the cell is locked.
|
||||
iscelllocked = api.asc_isProtectedSheet() && api.asc_checkLockedCells() ? api.asc_checkProtectedRange() : false;
|
||||
iscelllocked = iscelllocked === null ? true : false;
|
||||
|
||||
const { isDisconnected } = contextMenu.props;
|
||||
|
||||
switch (seltype) {
|
||||
case Asc.c_oAscSelectionType.RangeCells: iscellmenu = true; break;
|
||||
case Asc.c_oAscSelectionType.RangeRow: isrowmenu = true; break;
|
||||
case Asc.c_oAscSelectionType.RangeCol: iscolmenu = true; break;
|
||||
case Asc.c_oAscSelectionType.RangeMax: isallmenu = true; break;
|
||||
case Asc.c_oAscSelectionType.RangeImage: isimagemenu = true; break;
|
||||
case Asc.c_oAscSelectionType.RangeShape: isshapemenu = true; break;
|
||||
case Asc.c_oAscSelectionType.RangeChart: ischartmenu = true; break;
|
||||
case Asc.c_oAscSelectionType.RangeChartText: istextchartmenu = true; break;
|
||||
case Asc.c_oAscSelectionType.RangeShapeText: istextshapemenu = true; break;
|
||||
}
|
||||
|
||||
if (!iscelllocked && (isimagemenu || isshapemenu || ischartmenu || istextshapemenu || istextchartmenu)) {
|
||||
api.asc_getGraphicObjectProps().every((object) => {
|
||||
if (object.asc_getObjectType() == Asc.c_oAscTypeSelectElement.Image) {
|
||||
iscelllocked = object.asc_getObjectValue().asc_getLocked();
|
||||
}
|
||||
return !iscelllocked;
|
||||
});
|
||||
}
|
||||
|
||||
if (iscelllocked || api.isCellEdited) {
|
||||
itemsIcon.push({
|
||||
event: 'copy',
|
||||
icon: 'icon-copy'
|
||||
});
|
||||
|
||||
} else {
|
||||
itemsIcon.push({
|
||||
event: 'cut',
|
||||
icon: 'icon-cut'
|
||||
});
|
||||
itemsIcon.push({
|
||||
event: 'copy',
|
||||
icon: 'icon-copy'
|
||||
});
|
||||
itemsIcon.push({
|
||||
event: 'paste',
|
||||
icon: 'icon-paste'
|
||||
});
|
||||
itemsText.push({
|
||||
caption: _t.menuDelete,
|
||||
event: 'del'
|
||||
});
|
||||
|
||||
if (isimagemenu || isshapemenu || ischartmenu ||
|
||||
istextshapemenu || istextchartmenu) {
|
||||
itemsText.push({
|
||||
caption: _t.menuEdit,
|
||||
event: 'edit'
|
||||
});
|
||||
} else {
|
||||
if (iscolmenu || isrowmenu) {
|
||||
itemsText.push({
|
||||
caption: _t.menuHide,
|
||||
event: 'hide'
|
||||
});
|
||||
itemsText.push({
|
||||
caption: _t.menuShow,
|
||||
event: 'show'
|
||||
});
|
||||
} else if (iscellmenu) {
|
||||
if (!iscelllocked) {
|
||||
itemsText.push({
|
||||
caption: _t.menuCell,
|
||||
event: 'edit'
|
||||
});
|
||||
}
|
||||
|
||||
if (cellinfo.asc_getMerge() == Asc.c_oAscMergeOptions.None) {
|
||||
itemsText.push({
|
||||
caption: _t.menuMerge,
|
||||
event: 'merge'
|
||||
});
|
||||
}
|
||||
|
||||
if (cellinfo.asc_getMerge() == Asc.c_oAscMergeOptions.Merge) {
|
||||
itemsText.push({
|
||||
caption: _t.menuUnmerge,
|
||||
event: 'unmerge'
|
||||
});
|
||||
}
|
||||
|
||||
itemsText.push(
|
||||
xfs.asc_getWrapText() ?
|
||||
{
|
||||
caption: _t.menuUnwrap,
|
||||
event: 'unwrap'
|
||||
} :
|
||||
{
|
||||
caption: _t.menuWrap,
|
||||
event: 'wrap'
|
||||
});
|
||||
|
||||
if (cellinfo.asc_getHyperlink() && !cellinfo.asc_getMultiselect()) {
|
||||
itemsText.push({
|
||||
caption: _t.menuOpenLink,
|
||||
event: 'openlink'
|
||||
});
|
||||
itemsText.push({
|
||||
caption: _t.menuEditLink,
|
||||
event: 'editlink'
|
||||
});
|
||||
} else if (!cellinfo.asc_getHyperlink() && !cellinfo.asc_getMultiselect() &&
|
||||
!cellinfo.asc_getLockText() && !!cellinfo.asc_getText()) {
|
||||
itemsText.push({
|
||||
caption: _t.menuAddLink,
|
||||
event: 'addlink'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
itemsText.push({
|
||||
caption: api.asc_getSheetViewSettings().asc_getIsFreezePane() ? _t.menuUnfreezePanes : _t.menuFreezePanes,
|
||||
event: 'freezePanes'
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
if (canViewComments) {
|
||||
if (isComments) {
|
||||
itemsText.push({
|
||||
caption: _t.menuViewComment,
|
||||
event: 'viewcomment'
|
||||
});
|
||||
} else if (iscellmenu) {
|
||||
itemsText.push({
|
||||
caption: _t.menuAddComment,
|
||||
event: 'addcomment'
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The below is guesswork on how Onlyoffice should handle itself with locked cells.
|
||||
if(iscelllocked) {
|
||||
if (iscellmenu && cellinfo.asc_getHyperlink()) {
|
||||
itemsText.push({
|
||||
caption: _t.menuOpenLink,
|
||||
event: 'openlink'
|
||||
});
|
||||
}
|
||||
|
||||
const {isRestrictedEdit, canViewComments, canCoAuthoring, canComments, isResolvedComments, isVersionHistoryMode} = contextMenu.props;
|
||||
const comments = cellinfo.asc_getComments(); //prohibit adding multiple comments in one cell;
|
||||
|
||||
if(!isDisconnected && !isVersionHistoryMode) {
|
||||
if (canViewComments && comments && comments.length && ((!isSolvedComment && !isResolvedComments) || isResolvedComments)) {
|
||||
itemsText.push({
|
||||
caption: _t.menuViewComment,
|
||||
event: 'viewcomment'
|
||||
});
|
||||
}
|
||||
|
||||
if (iscellmenu && !api.isCellEdited && isRestrictedEdit && canCoAuthoring && canComments && comments && comments.length<1) {
|
||||
itemsText.push({
|
||||
caption: _t.menuAddComment,
|
||||
event: 'addcomment'
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( Device.phone && itemsText.length > 2 ) {
|
||||
contextMenu.extraItems = itemsText.splice(2,itemsText.length, {
|
||||
caption: _t.menuMore,
|
||||
event: 'showActionSheet'
|
||||
});
|
||||
}
|
||||
|
||||
return itemsIcon.concat(itemsText);
|
||||
} ,
|
||||
// https://github.com/ONLYOFFICE/web-apps/commit/588a7f03863ebf9ec3251a36decc8b4e280dda59
|
||||
handleMenuItemClick: (contextMenu, action) => {
|
||||
// console.log('EditorUIController.ContextMenu.handleMenuItemClick', contextMenu, action);
|
||||
|
||||
const api = Common.EditorApi.get();
|
||||
const info = api.asc_getCellInfo();
|
||||
switch (action) {
|
||||
case 'addcomment':
|
||||
Common.Notifications.trigger('addcomment');
|
||||
return true;
|
||||
case 'del':
|
||||
api.asc_emptyCells(Asc.c_oAscCleanOptions.All);
|
||||
return true;
|
||||
case 'wrap':
|
||||
api.asc_setCellTextWrap(true);
|
||||
return true;
|
||||
case 'unwrap':
|
||||
api.asc_setCellTextWrap(false);
|
||||
return true;
|
||||
case 'edit':
|
||||
setTimeout(() => {
|
||||
contextMenu.props.openOptions('edit');
|
||||
}, 0);
|
||||
return true;
|
||||
case 'merge':
|
||||
if (api.asc_mergeCellsDataLost(Asc.c_oAscMergeOptions.Merge)) {
|
||||
setTimeout(() => {
|
||||
f7.dialog.confirm(_t.warnMergeLostData, _t.notcriticalErrorTitle, () => {
|
||||
api.asc_mergeCells(Asc.c_oAscMergeOptions.Merge);
|
||||
});
|
||||
}, 0);
|
||||
} else {
|
||||
api.asc_mergeCells(Asc.c_oAscMergeOptions.Merge);
|
||||
}
|
||||
return true;
|
||||
case 'unmerge':
|
||||
api.asc_mergeCells(Asc.c_oAscMergeOptions.None);
|
||||
return true;
|
||||
case 'hide':
|
||||
api[info.asc_getSelectionType() == Asc.c_oAscSelectionType.RangeRow ? 'asc_hideRows' : 'asc_hideColumns']();
|
||||
return true;
|
||||
case 'show':
|
||||
api[info.asc_getSelectionType() == Asc.c_oAscSelectionType.RangeRow ? 'asc_showRows' : 'asc_showColumns']();
|
||||
return true;
|
||||
case 'addlink':
|
||||
setTimeout(() => {
|
||||
contextMenu.props.openOptions('add', 'link');
|
||||
}, 400)
|
||||
return true;
|
||||
case 'editlink':
|
||||
setTimeout(() => {
|
||||
contextMenu.props.openOptions('edit', 'link');
|
||||
}, 400)
|
||||
return true;
|
||||
case 'freezePanes':
|
||||
api.asc_freezePane();
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
};
|
||||
|
||||
// This objects holds the mysterious functions in focusObjects.js inside the intf object
|
||||
// These for now are based on the latest valid implementation from the mobile editor
|
||||
// https://github.com/ONLYOFFICE/web-apps/commit/7c72e8cb1b3e06ac72b0e7156d33b8a8d3206dc4#diff-a9931472dbd29941dda676251382f80122ff2f08aadc849684e08b505d174bf2
|
||||
EditorUIController.Intf = function (storeFocusObjects) {
|
||||
var obj = {};
|
||||
|
||||
obj.getSelections = () => {
|
||||
const _selections = [];
|
||||
|
||||
let isCell, isRow, isCol, isAll, isChart, isImage, isTextShape, isShape, isTextChart,
|
||||
selType = storeFocusObjects._cellInfo.asc_getSelectionType(),
|
||||
isObjLocked = false;
|
||||
|
||||
switch (selType) {
|
||||
case Asc.c_oAscSelectionType.RangeCells: isCell = true; break;
|
||||
case Asc.c_oAscSelectionType.RangeRow: isRow = true; break;
|
||||
case Asc.c_oAscSelectionType.RangeCol: isCol = true; break;
|
||||
case Asc.c_oAscSelectionType.RangeMax: isAll = true; break;
|
||||
case Asc.c_oAscSelectionType.RangeImage: isImage = true; break;
|
||||
case Asc.c_oAscSelectionType.RangeShape: isShape = true; break;
|
||||
case Asc.c_oAscSelectionType.RangeChart: isChart = true; break;
|
||||
case Asc.c_oAscSelectionType.RangeChartText:isTextChart = true; break;
|
||||
case Asc.c_oAscSelectionType.RangeShapeText: isTextShape = true; break;
|
||||
}
|
||||
|
||||
if (isImage || isShape || isChart) {
|
||||
isImage = isShape = isChart = false;
|
||||
let has_chartprops = false;
|
||||
let selectedObjects = Common.EditorApi.get().asc_getGraphicObjectProps();
|
||||
|
||||
for (let i = 0; i < selectedObjects.length; i++) {
|
||||
if (selectedObjects[i].asc_getObjectType() == Asc.c_oAscTypeSelectElement.Image) {
|
||||
const elValue = selectedObjects[i].asc_getObjectValue();
|
||||
isObjLocked = isObjLocked || elValue.asc_getLocked();
|
||||
const shapeProps = elValue.asc_getShapeProperties();
|
||||
|
||||
if (shapeProps) {
|
||||
if (shapeProps.asc_getFromChart()) {
|
||||
isChart = true;
|
||||
} else {
|
||||
isShape = true;
|
||||
|
||||
}
|
||||
} else if (elValue.asc_getChartProperties()) {
|
||||
isChart = true;
|
||||
has_chartprops = true;
|
||||
} else {
|
||||
isImage = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (isTextShape || isTextChart) {
|
||||
const selectedObjects = Common.EditorApi.get().asc_getGraphicObjectProps();
|
||||
let isEquation = false;
|
||||
|
||||
for (var i = 0; i < selectedObjects.length; i++) {
|
||||
const elType = selectedObjects[i].asc_getObjectType();
|
||||
if (elType == Asc.c_oAscTypeSelectElement.Image) {
|
||||
const value = selectedObjects[i].asc_getObjectValue();
|
||||
isObjLocked = isObjLocked || value.asc_getLocked();
|
||||
} else if (elType == Asc.c_oAscTypeSelectElement.Paragraph) {
|
||||
} else if (elType == Asc.c_oAscTypeSelectElement.Math) {
|
||||
isEquation = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isChart || isTextChart) {
|
||||
_selections.push('chart');
|
||||
|
||||
if (isTextChart) {
|
||||
_selections.push('text');
|
||||
}
|
||||
} else if ((isShape || isTextShape) && !isImage) {
|
||||
_selections.push('shape');
|
||||
|
||||
if (isTextShape) {
|
||||
_selections.push('text');
|
||||
}
|
||||
} else if (isImage) {
|
||||
_selections.push('image');
|
||||
|
||||
if (isShape) {
|
||||
_selections.push('shape');
|
||||
}
|
||||
} else {
|
||||
_selections.push('cell');
|
||||
|
||||
if (storeFocusObjects._cellInfo.asc_getHyperlink()) {
|
||||
_selections.push('hyperlink');
|
||||
}
|
||||
}
|
||||
return _selections;
|
||||
}
|
||||
|
||||
obj.getShapeObject = () => {
|
||||
const shapes = [];
|
||||
for (let object of storeFocusObjects._focusObjects) {
|
||||
if (object.get_ObjectType() === Asc.c_oAscTypeSelectElement.Image) {
|
||||
if (object.get_ObjectValue() && object.get_ObjectValue().get_ShapeProperties()) {
|
||||
shapes.push(object);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (shapes.length > 0) {
|
||||
const object = shapes[shapes.length - 1]; // get top
|
||||
return object.get_ObjectValue();
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
obj.getImageObject = () => {
|
||||
const images = [];
|
||||
for (let object of storeFocusObjects._focusObjects) {
|
||||
if (object.get_ObjectType() == Asc.c_oAscTypeSelectElement.Image) {
|
||||
images.push(object);
|
||||
}
|
||||
}
|
||||
if (images.length > 0) {
|
||||
const object = images[images.length - 1]; // get top
|
||||
return object.get_ObjectValue();
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
obj.getChartObject = () => {
|
||||
const charts = [];
|
||||
for (let object of storeFocusObjects._focusObjects) {
|
||||
if (object.get_ObjectType() === Asc.c_oAscTypeSelectElement.Image) {
|
||||
if (object.get_ObjectValue() && object.get_ObjectValue().get_ChartProperties()) {
|
||||
charts.push(object);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (charts.length > 0) {
|
||||
const object = charts[charts.length - 1]; // get top table
|
||||
return object.get_ObjectValue();
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
export default EditorUIController;
|
||||
|
|
@ -0,0 +1,670 @@
|
|||
import React, {Fragment} from 'react';
|
||||
import {Link} from 'framework7-react';
|
||||
import { Device } from '../../web-apps/apps/common/mobile/utils/device';
|
||||
import {
|
||||
AddCommentController,
|
||||
EditCommentController,
|
||||
} from "../../web-apps/apps/common/mobile/lib/controller/collaboration/Comments";
|
||||
|
||||
const EditorUIController = () => {
|
||||
return null
|
||||
};
|
||||
|
||||
EditorUIController.isSupportEditFeature = () => {
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
This is the file where the magic happens.
|
||||
Try to figure out a working version from the old commits
|
||||
and my hunches from hacking around in the old webapp editor
|
||||
*/
|
||||
|
||||
|
||||
// Code taken from
|
||||
// https://github.com/ONLYOFFICE/web-apps/commit/0277ac930611db0637100a2c5e6891ea495610a8#diff-755ea3df479f23211982e28466b363be9df22cb92f4a5cf9126ec9e227d6909bL66-L72
|
||||
EditorUIController.getToolbarOptions = (options) => {
|
||||
// console.log('EditorUIController.getToolbarOptions' ,options);
|
||||
return (
|
||||
<Fragment>
|
||||
<Link className={options.disabled && 'disabled'} id='btn-edit' icon='icon-edit-settings' href={false} onClick={() => options.onEditClick()}></Link>
|
||||
<Link className={options.disabled && 'disabled'} id='btn-add' icon='icon-plus' href={false} onClick={() => options.onAddClick()}></Link>
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
// Code taken from
|
||||
// https://github.com/ONLYOFFICE/web-apps/commit/0277ac930611db0637100a2c5e6891ea495610a8
|
||||
EditorUIController.getUndoRedo = (options) => {
|
||||
// console.log('EditorUIController.getUndoRedo', options);
|
||||
return (
|
||||
<Fragment>
|
||||
<Link icon='icon-undo' className={options.disabledUndo && 'disabled'} onClick={() => options.onUndoClick()}></Link>
|
||||
<Link icon='icon-redo' className={options.disabledRedo && 'disabled'} onClick={() => options.onRedoClick()}></Link>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
// Code taken from
|
||||
// https://github.com/ONLYOFFICE/web-apps/commit/45a9058da461a9da67ccb389faad08bce8cbda55#diff-1d89c904c6cd5147fb6942c09c4d12a2f3a3200a61b3e29b1a42a1263e57848bL307-L308
|
||||
EditorUIController.getEditCommentControllers = () => {
|
||||
// console.log('EditorUIController.getEditCommentControllers');
|
||||
return (
|
||||
<Fragment>
|
||||
<AddCommentController />
|
||||
<EditCommentController />
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
// Code taken from
|
||||
// https://github.com/ONLYOFFICE/web-apps/commit/fe1a9e16d3c18cb5e9c2cc1aa512649c348aa283#diff-1d89c904c6cd5147fb6942c09c4d12a2f3a3200a61b3e29b1a42a1263e57848bL233-L259
|
||||
EditorUIController.initFonts = (storeTextSettings) => {
|
||||
// console.log('EditorUIController.initFonts', storeTextSettings);
|
||||
const api = Common.EditorApi.get();
|
||||
api.asc_registerCallback('asc_onInitEditorFonts', (fonts, select) => {
|
||||
// console.log('asc_onInitEditorFonts', fonts, select);
|
||||
storeTextSettings.initEditorFonts(fonts, select);
|
||||
});
|
||||
api.asc_registerCallback('asc_onFontFamily', (font) => {
|
||||
// console.log('asc_onFontFamily', font);
|
||||
storeTextSettings.resetFontName(font);
|
||||
});
|
||||
api.asc_registerCallback('asc_onFontSize', (size) => {
|
||||
// console.log('asc_onFontSize', size);
|
||||
storeTextSettings.resetFontSize(size);
|
||||
});
|
||||
api.asc_registerCallback('asc_onBold', (isBold) => {
|
||||
// console.log('asc_onBold', isBold);
|
||||
storeTextSettings.resetIsBold(isBold);
|
||||
});
|
||||
api.asc_registerCallback('asc_onItalic', (isItalic) => {
|
||||
// console.log('asc_onItalic', isItalic);
|
||||
storeTextSettings.resetIsItalic(isItalic);
|
||||
});
|
||||
api.asc_registerCallback('asc_onUnderline', (isUnderline) => {
|
||||
// console.log('asc_onUnderline', isUnderline);
|
||||
storeTextSettings.resetIsUnderline(isUnderline);
|
||||
});
|
||||
api.asc_registerCallback('asc_onStrikeout', (isStrikeout) => {
|
||||
// console.log('asc_onStrikeout', isStrikeout);
|
||||
storeTextSettings.resetIsStrikeout(isStrikeout);
|
||||
});
|
||||
};
|
||||
|
||||
// Code taken from
|
||||
// https://github.com/ONLYOFFICE/web-apps/commit/fe1a9e16d3c18cb5e9c2cc1aa512649c348aa283#diff-1d89c904c6cd5147fb6942c09c4d12a2f3a3200a61b3e29b1a42a1263e57848bL210-L223
|
||||
EditorUIController.initEditorStyles = (storeSlideSettings) => {
|
||||
// console.log('EditorUIController.initEditorStyles', storeSlideSettings);
|
||||
const api = Common.EditorApi.get();
|
||||
api.asc_registerCallback('asc_onInitEditorStyles', themes => {
|
||||
// themes is an array of array with index 0 representing defaultThemes and 1 representing documentThemes
|
||||
// Inspired by what's done in /view/edit/EditSlide.jsx
|
||||
let defaultThemes = themes[0];
|
||||
let docThemes = themes[1];
|
||||
let arrayThemes = [];
|
||||
|
||||
defaultThemes.forEach(function(theme, index) {
|
||||
arrayThemes.push({
|
||||
themeId : theme.get_Index(),
|
||||
tip : theme.get_Name(),
|
||||
offsety : index * 40
|
||||
});
|
||||
});
|
||||
docThemes.forEach(function(theme) {
|
||||
arrayThemes.push({
|
||||
imageUrl: theme.get_Image(),
|
||||
themeId : theme.get_Index(),
|
||||
tip : theme.get_Name(),
|
||||
offsety : 0
|
||||
});
|
||||
});
|
||||
|
||||
storeSlideSettings.addArrayThemes(arrayThemes);
|
||||
});
|
||||
|
||||
api.asc_registerCallback('asc_onUpdateThemeIndex', themeId => {
|
||||
// console.log(themeId);
|
||||
storeSlideSettings.changeSlideThemeIndex(themeId);
|
||||
});
|
||||
|
||||
api.asc_registerCallback('asc_onUpdateLayout', layouts => {
|
||||
// console.log(layouts);
|
||||
storeSlideSettings.addArrayLayouts(layouts);
|
||||
});
|
||||
}
|
||||
|
||||
// Code taken from
|
||||
// https://github.com/ONLYOFFICE/web-apps/commit/fe1a9e16d3c18cb5e9c2cc1aa512649c348aa283#diff-1d89c904c6cd5147fb6942c09c4d12a2f3a3200a61b3e29b1a42a1263e57848bL202-L208
|
||||
EditorUIController.initFocusObjects = (storeFocusObjects) => {
|
||||
storeFocusObjects.intf = EditorUIController.Intf(storeFocusObjects);
|
||||
// console.log('EditorUIController.initFocusObjects', storeFocusObjects);
|
||||
const api = Common.EditorApi.get();
|
||||
api.asc_registerCallback('asc_onFocusObject', objects => {
|
||||
// console.log('asc_onFocusObject', objects);
|
||||
storeFocusObjects.resetFocusObjects(objects);
|
||||
});
|
||||
}
|
||||
|
||||
// Code taken from
|
||||
// https://github.com/ONLYOFFICE/web-apps/commit/fe1a9e16d3c18cb5e9c2cc1aa512649c348aa283#diff-1d89c904c6cd5147fb6942c09c4d12a2f3a3200a61b3e29b1a42a1263e57848bL318-L322
|
||||
EditorUIController.initTableTemplates = (storeTableSettings) => {
|
||||
// console.log('EditorUIController.initTableTemplates', storeTableSettings);
|
||||
const api = Common.EditorApi.get();
|
||||
api.asc_registerCallback('asc_onInitTableTemplates', (templates) => {
|
||||
// console.log('asc_onInitTableTemplates', templates);
|
||||
storeTableSettings.initTableTemplates(templates);
|
||||
});
|
||||
}
|
||||
|
||||
// Code taken from
|
||||
// https://github.com/ONLYOFFICE/web-apps/commit/fe1a9e16d3c18cb5e9c2cc1aa512649c348aa283#diff-1d89c904c6cd5147fb6942c09c4d12a2f3a3200a61b3e29b1a42a1263e57848bL225-L227
|
||||
EditorUIController.initThemeColors = () => {
|
||||
// console.log('EditorUIController.initThemeColors');
|
||||
const api = Common.EditorApi.get();
|
||||
api.asc_registerCallback('asc_onSendThemeColors', (colors, standart_colors) => {
|
||||
// console.log('asc_onSendThemeColors', colors, standart_colors);
|
||||
Common.Utils.ThemeColor.setColors(colors, standart_colors);
|
||||
});
|
||||
}
|
||||
|
||||
// Code taken from
|
||||
// https://github.com/ONLYOFFICE/web-apps/commit/45a9058da461a9da67ccb389faad08bce8cbda55#diff-1d89c904c6cd5147fb6942c09c4d12a2f3a3200a61b3e29b1a42a1263e57848bL264-L270
|
||||
EditorUIController.updateChartStyles = (storeChartSettings, storeFocusObjects) => {
|
||||
// console.log('EditorUIController.updateChartStyles', storeChartSettings, storeFocusObjects);
|
||||
const api = Common.EditorApi.get();
|
||||
api.asc_registerCallback('asc_onUpdateChartStyles', () => {
|
||||
// console.log('asc_onUpdateChartStyles', storeFocusObjects.chartObject);
|
||||
if (storeFocusObjects.chartObject && storeFocusObjects.chartObject.get_ChartProperties()) {
|
||||
// console.log('we in');
|
||||
storeChartSettings.updateChartStyles(api.asc_getChartPreviews(storeFocusObjects.chartObject.get_ChartProperties().getType()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Code taken from
|
||||
// https://github.com/ONLYOFFICE/web-apps/commit/fe1a9e16d3c18cb5e9c2cc1aa512649c348aa283#diff-f711cbc9449c97e0d6394cf70e9c04eeca1d9e520a1f2e7b390b1a5bc5acd82d
|
||||
EditorUIController.ContextMenu = {
|
||||
mapMenuItems: (contextMenu) => {
|
||||
// console.log('EditorUIController.ContextMenu.mapMenuItems', contextMenu);
|
||||
|
||||
if ( !Common.EditorApi ) return [];
|
||||
|
||||
const { t } = contextMenu.props;
|
||||
const _t = t("ContextMenu", { returnObjects: true });
|
||||
|
||||
const { isEdit, canViewComments, canReview, isDisconnected } = contextMenu.props;
|
||||
|
||||
const { isViewer, isProtected } = contextMenu.props;
|
||||
// This probably needs to be refired
|
||||
if(!isEdit || isViewer || isProtected)
|
||||
return EditorUIController.ContextMenu.mapMenuItemsReadOnly(contextMenu);
|
||||
|
||||
const api = Common.EditorApi.get();
|
||||
const stack = api.getSelectedElements();
|
||||
const canCopy = api.can_CopyCut();
|
||||
|
||||
let itemsIcon = [],
|
||||
itemsText = [];
|
||||
|
||||
if ( canCopy ) {
|
||||
itemsIcon.push({
|
||||
event: 'copy',
|
||||
icon: 'icon-copy'
|
||||
});
|
||||
}
|
||||
|
||||
if ( canViewComments && contextMenu.isComments && !isEdit ) {
|
||||
itemsText.push({
|
||||
caption: _t.menuViewComment,
|
||||
event: 'viewcomment'
|
||||
});
|
||||
}
|
||||
|
||||
let isText = false,
|
||||
isTable = false,
|
||||
isImage = false,
|
||||
isChart = false,
|
||||
isShape = false,
|
||||
isLink = false,
|
||||
lockedText = false,
|
||||
lockedTable = false,
|
||||
lockedImage = false,
|
||||
lockedHeader = false;
|
||||
|
||||
stack.forEach(item => {
|
||||
const objectType = item.get_ObjectType(),
|
||||
objectValue = item.get_ObjectValue();
|
||||
|
||||
if ( objectType == Asc.c_oAscTypeSelectElement.Header ) {
|
||||
lockedHeader = objectValue.get_Locked();
|
||||
} else
|
||||
if ( objectType == Asc.c_oAscTypeSelectElement.Paragraph ) {
|
||||
lockedText = objectValue.get_Locked();
|
||||
isText = true;
|
||||
} else
|
||||
if ( objectType == Asc.c_oAscTypeSelectElement.Image ) {
|
||||
lockedImage = objectValue.get_Locked();
|
||||
if ( objectValue && objectValue.get_ChartProperties() ) {
|
||||
isChart = true;
|
||||
} else
|
||||
if ( objectValue && objectValue.get_ShapeProperties() ) {
|
||||
isShape = true;
|
||||
} else {
|
||||
isImage = true;
|
||||
}
|
||||
} else
|
||||
if ( objectType == Asc.c_oAscTypeSelectElement.Table ) {
|
||||
lockedTable = objectValue.get_Locked();
|
||||
isTable = true;
|
||||
} else
|
||||
if ( objectType == Asc.c_oAscTypeSelectElement.Hyperlink ) {
|
||||
isLink = true;
|
||||
}
|
||||
});
|
||||
|
||||
if ( stack.length > 0 ) {
|
||||
const swapItems = function(items, indexBefore, indexAfter) {
|
||||
items[indexAfter] = items.splice(indexBefore, 1, items[indexAfter])[0];
|
||||
};
|
||||
|
||||
if ( isEdit && !isDisconnected ) {
|
||||
if ( !lockedText && !lockedTable && !lockedImage && !lockedHeader && canCopy ) {
|
||||
itemsIcon.push({
|
||||
event: 'cut',
|
||||
icon: 'icon-cut'
|
||||
});
|
||||
|
||||
// Swap 'Copy' and 'Cut'
|
||||
swapItems(itemsIcon, 0, 1);
|
||||
}
|
||||
|
||||
if ( !lockedText && !lockedTable && !lockedImage && !lockedHeader ) {
|
||||
itemsIcon.push({
|
||||
event: 'paste',
|
||||
icon: 'icon-paste'
|
||||
});
|
||||
}
|
||||
|
||||
if ( isTable && api.CheckBeforeMergeCells() && !lockedTable && !lockedHeader) {
|
||||
itemsText.push({
|
||||
caption: _t.menuMerge,
|
||||
event: 'merge'
|
||||
});
|
||||
}
|
||||
|
||||
if ( isTable && api.CheckBeforeSplitCells() && !lockedTable && !lockedHeader ) {
|
||||
itemsText.push({
|
||||
caption: _t.menuSplit,
|
||||
event: 'split'
|
||||
});
|
||||
}
|
||||
|
||||
if ( !lockedText && !lockedTable && !lockedImage && !lockedHeader ) {
|
||||
itemsText.push({
|
||||
caption: _t.menuDelete,
|
||||
event: 'delete'
|
||||
});
|
||||
}
|
||||
|
||||
if ( isTable && !lockedTable && !lockedText && !lockedHeader ) {
|
||||
itemsText.push({
|
||||
caption: _t.menuDeleteTable,
|
||||
event: 'deletetable'
|
||||
});
|
||||
}
|
||||
|
||||
if ( !lockedText && !lockedTable && !lockedImage && !lockedHeader ){
|
||||
itemsText.push({
|
||||
caption: _t.menuEdit,
|
||||
event: 'edit'
|
||||
});
|
||||
}
|
||||
|
||||
if ( !!api.can_AddHyperlink() && !lockedHeader) {
|
||||
itemsText.push({
|
||||
caption: _t.menuAddLink,
|
||||
event: 'addlink'
|
||||
});
|
||||
}
|
||||
|
||||
if(isLink && !lockedHeader) {
|
||||
itemsText.push({
|
||||
caption: _t.menuEditLink,
|
||||
event: 'editlink'
|
||||
});
|
||||
}
|
||||
|
||||
if ( canReview ) {
|
||||
if (contextMenu.inRevisionChange) {
|
||||
itemsText.push({
|
||||
caption: _t.menuReviewChange,
|
||||
event: 'reviewchange'
|
||||
});
|
||||
} else {
|
||||
itemsText.push({
|
||||
caption: _t.menuReview,
|
||||
event: 'review'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if ( contextMenu.isComments && canViewComments ) {
|
||||
itemsText.push({
|
||||
caption: _t.menuViewComment,
|
||||
event: 'viewcomment'
|
||||
});
|
||||
}
|
||||
|
||||
const isObject = isShape || isChart || isImage || isTable;
|
||||
const hideAddComment = !canViewComments || api.can_AddQuotedComment() === false || lockedText || lockedTable || lockedImage || lockedHeader || (!isText && isObject);
|
||||
if ( !hideAddComment ) {
|
||||
itemsText.push({
|
||||
caption: _t.menuAddComment,
|
||||
event: 'addcomment'
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( isLink ) {
|
||||
itemsText.push({
|
||||
caption: _t.menuOpenLink,
|
||||
event: 'openlink'
|
||||
});
|
||||
}
|
||||
|
||||
if ( Device.phone && itemsText.length > 2 ) {
|
||||
contextMenu.extraItems = itemsText.splice(2,itemsText.length, {
|
||||
caption: _t.menuMore,
|
||||
event: 'showActionSheet'
|
||||
});
|
||||
}
|
||||
|
||||
const menuItems = itemsIcon.concat(itemsText);
|
||||
// console.log('EditorUIController.ContextMenu.mapMenuItems', menuItems);
|
||||
return menuItems;
|
||||
} ,
|
||||
handleMenuItemClick: (contextMenu, action) => {
|
||||
// console.log('EditorUIController.ContextMenu.handleMenuItemClick', contextMenu, action);
|
||||
|
||||
const api = Common.EditorApi.get();
|
||||
switch (action) {
|
||||
case 'edit':
|
||||
setTimeout(() => {
|
||||
contextMenu.props.openOptions('edit');
|
||||
}, 0);
|
||||
return true;
|
||||
case 'addcomment':
|
||||
Common.Notifications.trigger('addcomment');
|
||||
return true;
|
||||
case 'merge':
|
||||
api.MergeCells();
|
||||
return true;
|
||||
case 'delete':
|
||||
api.asc_Remove();
|
||||
return true;
|
||||
case 'deletetable':
|
||||
api.remTable();
|
||||
return true;
|
||||
case 'editlink':
|
||||
setTimeout(() => {
|
||||
contextMenu.props.openOptions('edit', 'link');
|
||||
}, 400)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
// This method handles the menu items shown when the user is in edit mode but
|
||||
// can't edit the form i.e: in viewer mode or when the document is protected
|
||||
// This is mostly a copy of the else statement of ContextMenu.initMenuItems
|
||||
// with the bare minimum modifications so it can execute.
|
||||
// It is done that way on purpose even if some code ends up duplicated
|
||||
// This should make noticing and following Onlyoffice changes easier
|
||||
mapMenuItemsReadOnly: (contextMenu) => {
|
||||
const { t } = contextMenu.props;
|
||||
const _t = t("ContextMenu", { returnObjects: true });
|
||||
|
||||
const { isEdit, isDisconnected, isVersionHistoryMode } = contextMenu.props;
|
||||
const { isComments, canViewComments, canCoAuthoring, canComments } = contextMenu.props;
|
||||
|
||||
const api = Common.EditorApi.get();
|
||||
const stack = api.getSelectedElements();
|
||||
const canCopy = api.can_CopyCut();
|
||||
|
||||
let itemsIcon = [],
|
||||
itemsText = [];
|
||||
|
||||
let isText = false,
|
||||
isTable = false,
|
||||
isImage = false,
|
||||
isChart = false,
|
||||
isShape = false,
|
||||
isLink = false,
|
||||
isSlide = false,
|
||||
isObject,
|
||||
locked = false;
|
||||
|
||||
stack.forEach(item => {
|
||||
const objectType = item.get_ObjectType(),
|
||||
objectValue = item.get_ObjectValue();
|
||||
locked = typeof objectValue.get_Locked === 'function' ? objectValue.get_Locked() : false;
|
||||
|
||||
if (objectType == Asc.c_oAscTypeSelectElement.Paragraph) {
|
||||
isText = true;
|
||||
} else if (objectType == Asc.c_oAscTypeSelectElement.Image) {
|
||||
isImage = true;
|
||||
} else if (objectType == Asc.c_oAscTypeSelectElement.Chart) {
|
||||
isChart = true;
|
||||
} else if (objectType == Asc.c_oAscTypeSelectElement.Shape) {
|
||||
isShape = true;
|
||||
} else if (objectType == Asc.c_oAscTypeSelectElement.Table) {
|
||||
isTable = true;
|
||||
} else if (objectType == Asc.c_oAscTypeSelectElement.Hyperlink) {
|
||||
isLink = true;
|
||||
} else if (objectType == Asc.c_oAscTypeSelectElement.Slide) {
|
||||
isSlide = true;
|
||||
}
|
||||
});
|
||||
|
||||
isObject = isText || isImage || isChart || isShape || isTable;
|
||||
|
||||
if (canCopy && isObject) {
|
||||
itemsIcon.push({
|
||||
event: 'copy',
|
||||
icon: 'icon-copy'
|
||||
});
|
||||
}
|
||||
if(!isDisconnected && !isVersionHistoryMode) {
|
||||
if (canViewComments && isComments && !isEdit) {
|
||||
itemsText.push({
|
||||
caption: _t.menuViewComment,
|
||||
event: 'viewcomment'
|
||||
});
|
||||
}
|
||||
|
||||
if (!isChart && api.can_AddQuotedComment() !== false && canCoAuthoring && canComments && !locked) {
|
||||
itemsText.push({
|
||||
caption: _t.menuAddComment,
|
||||
event: 'addcomment'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (isLink) {
|
||||
itemsText.push({
|
||||
caption: _t.menuOpenLink,
|
||||
event: 'openlink'
|
||||
});
|
||||
}
|
||||
|
||||
return itemsIcon.concat(itemsText);
|
||||
}
|
||||
};
|
||||
|
||||
// This objects holds the mysterious functions in focusObjects.js inside the intf object
|
||||
// These for now are based on the latest valid implementation from the mobile editor
|
||||
// Code taken from
|
||||
// https://github.com/ONLYOFFICE/web-apps/commit/fe1a9e16d3c18cb5e9c2cc1aa512649c348aa283#diff-1a8252788e3c9baa4e6bcdd6a91d4718fcf3ac90f0f12b4e3263f9cccba53f8d
|
||||
EditorUIController.Intf = function (storeFocusObjects) {
|
||||
var obj = {};
|
||||
|
||||
obj.filterFocusObjects = () => {
|
||||
const _settings = [];
|
||||
let no_text = true;
|
||||
for (let object of storeFocusObjects._focusObjects) {
|
||||
const type = object.get_ObjectType(),
|
||||
objectValue = object.get_ObjectValue();
|
||||
if (Asc.c_oAscTypeSelectElement.Paragraph == type) {
|
||||
if ( !objectValue.get_Locked() )
|
||||
no_text = false;
|
||||
} else if (Asc.c_oAscTypeSelectElement.Table == type) {
|
||||
if ( !objectValue.get_Locked() ) {
|
||||
_settings.push('table');
|
||||
no_text = false;
|
||||
}
|
||||
} else if (Asc.c_oAscTypeSelectElement.Slide == type) {
|
||||
if ( !(objectValue.get_LockLayout() || objectValue.get_LockBackground() || objectValue.get_LockTransition() || objectValue.get_LockTiming() ))
|
||||
_settings.push('slide');
|
||||
} else if (Asc.c_oAscTypeSelectElement.Image == type) {
|
||||
if ( !objectValue.get_Locked() )
|
||||
_settings.push('image');
|
||||
} else if (Asc.c_oAscTypeSelectElement.Chart == type) {
|
||||
if ( !objectValue.get_Locked() )
|
||||
_settings.push('chart');
|
||||
} else if (Asc.c_oAscTypeSelectElement.Shape == type && !objectValue.get_FromChart()) {
|
||||
if ( !objectValue.get_Locked() ) {
|
||||
_settings.push('shape');
|
||||
no_text = false;
|
||||
}
|
||||
} else if (Asc.c_oAscTypeSelectElement.Hyperlink == type) {
|
||||
_settings.push('hyperlink');
|
||||
}
|
||||
}
|
||||
if (!no_text && _settings.indexOf('image') < 0)
|
||||
_settings.unshift('text');
|
||||
const resultArr = _settings.filter((value, index, self) => self.indexOf(value) === index); //get uniq array
|
||||
// Exclude hyperlink if text is locked
|
||||
if (resultArr.indexOf('hyperlink') > -1 && resultArr.indexOf('text') < 0) {
|
||||
resultArr.splice(resultArr.indexOf('hyperlink'), 1);
|
||||
}
|
||||
// Exclude shapes if chart exist
|
||||
if (resultArr.indexOf('chart') > -1 && resultArr.indexOf('shape') > -1) {
|
||||
resultArr.splice(resultArr.indexOf('shape'), 1);
|
||||
}
|
||||
return resultArr;
|
||||
}
|
||||
|
||||
obj.getSlideObject = () => {
|
||||
const slides = [];
|
||||
for (let object of storeFocusObjects._focusObjects) {
|
||||
if (object.get_ObjectType() === Asc.c_oAscTypeSelectElement.Slide) {
|
||||
slides.push(object);
|
||||
}
|
||||
}
|
||||
if (slides.length > 0) {
|
||||
const object = slides[slides.length - 1]; // get top
|
||||
return object.get_ObjectValue();
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
obj.getParagraphObject = () => {
|
||||
const paragraphs = [];
|
||||
for (let object of storeFocusObjects._focusObjects) {
|
||||
if (object.get_ObjectType() === Asc.c_oAscTypeSelectElement.Paragraph) {
|
||||
paragraphs.push(object);
|
||||
}
|
||||
}
|
||||
if (paragraphs.length > 0) {
|
||||
const object = paragraphs[paragraphs.length - 1]; // get top
|
||||
return object.get_ObjectValue();
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
obj.getShapeObject = () => {
|
||||
const shapes = [];
|
||||
for (let object of storeFocusObjects._focusObjects) {
|
||||
if (object.get_ObjectType() === Asc.c_oAscTypeSelectElement.Shape) {
|
||||
shapes.push(object);
|
||||
}
|
||||
}
|
||||
if (shapes.length > 0) {
|
||||
const object = shapes[shapes.length - 1]; // get top
|
||||
return object.get_ObjectValue();
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
obj.getImageObject = () => {
|
||||
const images = [];
|
||||
for (let object of storeFocusObjects._focusObjects) {
|
||||
if (object.get_ObjectType() == Asc.c_oAscTypeSelectElement.Image && object.get_ObjectValue()) {
|
||||
images.push(object);
|
||||
}
|
||||
}
|
||||
if (images.length > 0) {
|
||||
const object = images[images.length - 1]; // get top
|
||||
return object.get_ObjectValue();
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
obj.getTableObject = () => {
|
||||
const tables = [];
|
||||
for (let object of storeFocusObjects._focusObjects) {
|
||||
if (object.get_ObjectType() == Asc.c_oAscTypeSelectElement.Table) {
|
||||
tables.push(object);
|
||||
}
|
||||
}
|
||||
if (tables.length > 0) {
|
||||
const object = tables[tables.length - 1]; // get top table
|
||||
return object.get_ObjectValue();
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
obj.getChartObject = () => {
|
||||
const charts = [];
|
||||
|
||||
for (let object of storeFocusObjects._focusObjects) {
|
||||
if (object.get_ObjectType() == Asc.c_oAscTypeSelectElement.Chart) {
|
||||
charts.push(object);
|
||||
}
|
||||
}
|
||||
|
||||
if (charts.length > 0) {
|
||||
const object = charts[charts.length - 1]; // get top
|
||||
return object.get_ObjectValue();
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
obj.getLinkObject = () => {
|
||||
const links = [];
|
||||
for (let object of storeFocusObjects._focusObjects) {
|
||||
if (object.get_ObjectType() == Asc.c_oAscTypeSelectElement.Hyperlink) {
|
||||
links.push(object);
|
||||
}
|
||||
}
|
||||
if (links.length > 0) {
|
||||
const object = links[links.length - 1]; // get top
|
||||
return object.get_ObjectValue();
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
export default EditorUIController;
|
||||
|
|
@ -0,0 +1,640 @@
|
|||
import React, {Fragment} from 'react';
|
||||
import {Link} from 'framework7-react';
|
||||
import { Device } from '../../web-apps/apps/common/mobile/utils/device';
|
||||
import {
|
||||
AddCommentController,
|
||||
EditCommentController,
|
||||
} from "../../web-apps/apps/common/mobile/lib/controller/collaboration/Comments";
|
||||
|
||||
const EditorUIController = () => {
|
||||
return null
|
||||
};
|
||||
|
||||
EditorUIController.isSupportEditFeature = () => {
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
This is the file where the magic happens.
|
||||
Try to figure out a working version from a both the old commits
|
||||
and my hunches from hacking around in the old webapp editor
|
||||
|
||||
https://github.com/ONLYOFFICE/web-apps/commit/45a9058da461a9da67ccb389faad08bce8cbda55
|
||||
*/
|
||||
|
||||
EditorUIController.getToolbarOptions = (options) => {
|
||||
// console.log('EditorUIController.getToolbarOptions' ,options);
|
||||
return (
|
||||
<Fragment>
|
||||
<Link className={options.disabled && 'disabled'} id='btn-edit' icon='icon-edit-settings' href={false} onClick={() => options.onEditClick()}></Link>
|
||||
<Link className={options.disabled && 'disabled'} id='btn-add' icon='icon-plus' href={false} onClick={() => options.onAddClick()}></Link>
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
EditorUIController.getUndoRedo = (options) => {
|
||||
// console.log('EditorUIController.getUndoRedo', options);
|
||||
return (
|
||||
<Fragment>
|
||||
<Link icon='icon-undo' className={options.disabledUndo && 'disabled'} onClick={() => options.onUndoClick()}></Link>
|
||||
<Link icon='icon-redo' className={options.disabledRedo && 'disabled'} onClick={() => options.onRedoClick()}></Link>
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
EditorUIController.getEditCommentControllers = () => {
|
||||
// console.log('EditorUIController.getEditCommentControllers');
|
||||
return (
|
||||
<Fragment>
|
||||
<AddCommentController />
|
||||
<EditCommentController />
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
// https://github.com/ONLYOFFICE/web-apps/commit/ee15cf025dd64fe0f48eba015c7bdcea0446a38b
|
||||
EditorUIController.initFonts = (storeTextSettings) => {
|
||||
// console.log('EditorUIController.initFonts', storeTextSettings);
|
||||
const api = Common.EditorApi.get();
|
||||
api.asc_registerCallback('asc_onInitEditorFonts', (fonts, select) => {
|
||||
// console.log('asc_onInitEditorFonts', fonts, select);
|
||||
storeTextSettings.initEditorFonts(fonts, select);
|
||||
});
|
||||
api.asc_registerCallback('asc_onFontFamily', (font) => {
|
||||
// console.log('asc_onFontFamily', font);
|
||||
storeTextSettings.resetFontName(font);
|
||||
});
|
||||
api.asc_registerCallback('asc_onFontSize', (size) => {
|
||||
// console.log('asc_onFontSize', size);
|
||||
storeTextSettings.resetFontSize(size);
|
||||
});
|
||||
api.asc_registerCallback('asc_onBold', (isBold) => {
|
||||
// console.log('asc_onBold', isBold);
|
||||
storeTextSettings.resetIsBold(isBold);
|
||||
});
|
||||
api.asc_registerCallback('asc_onItalic', (isItalic) => {
|
||||
// console.log('asc_onItalic', isItalic);
|
||||
storeTextSettings.resetIsItalic(isItalic);
|
||||
});
|
||||
api.asc_registerCallback('asc_onUnderline', (isUnderline) => {
|
||||
// console.log('asc_onUnderline', isUnderline);
|
||||
storeTextSettings.resetIsUnderline(isUnderline);
|
||||
});
|
||||
api.asc_registerCallback('asc_onStrikeout', (isStrikeout) => {
|
||||
// console.log('asc_onStrikeout', isStrikeout);
|
||||
storeTextSettings.resetIsStrikeout(isStrikeout);
|
||||
});
|
||||
};
|
||||
EditorUIController.initEditorStyles = (storeParagraphSettings) => {
|
||||
// console.log('EditorUIController.initEditorStyles', storeParagraphSettings);
|
||||
const api = Common.EditorApi.get();
|
||||
api.asc_registerCallback('asc_onInitEditorStyles', (styles) => {
|
||||
// console.log('asc_onInitEditorStyles', styles);
|
||||
storeParagraphSettings.initEditorStyles(styles);
|
||||
});
|
||||
api.asc_registerCallback('asc_onParaStyleName', (name) => {
|
||||
// console.log('asc_onParaStyleName', name);
|
||||
storeParagraphSettings.changeParaStyleName(name);
|
||||
});
|
||||
}
|
||||
EditorUIController.initFocusObjects = (storeFocusObjects) => {
|
||||
storeFocusObjects.intf = EditorUIController.Intf(storeFocusObjects);
|
||||
// console.log('EditorUIController.initFocusObjects', storeFocusObjects);
|
||||
const api = Common.EditorApi.get();
|
||||
api.asc_registerCallback('asc_onFocusObject', objects => {
|
||||
// console.log('asc_onFocusObject', objects);
|
||||
storeFocusObjects.resetFocusObjects(objects);
|
||||
});
|
||||
}
|
||||
EditorUIController.initTableTemplates = (storeTableSettings) => {
|
||||
// console.log('EditorUIController.initTableTemplates', storeTableSettings);
|
||||
const api = Common.EditorApi.get();
|
||||
api.asc_registerCallback('asc_onInitTableTemplates', (templates) => {
|
||||
// console.log('asc_onInitTableTemplates', templates);
|
||||
storeTableSettings.initTableTemplates(templates);
|
||||
});
|
||||
}
|
||||
|
||||
EditorUIController.initThemeColors = () => {
|
||||
// console.log('EditorUIController.initThemeColors');
|
||||
const api = Common.EditorApi.get();
|
||||
api.asc_registerCallback('asc_onSendThemeColors', (colors, standart_colors) => {
|
||||
// console.log('asc_onSendThemeColors', colors, standart_colors);
|
||||
Common.Utils.ThemeColor.setColors(colors, standart_colors);
|
||||
});
|
||||
}
|
||||
|
||||
EditorUIController.updateChartStyles = (storeChartSettings, storeFocusObjects) => {
|
||||
// console.log('EditorUIController.updateChartStyles', storeChartSettings, storeFocusObjects);
|
||||
const api = Common.EditorApi.get();
|
||||
api.asc_registerCallback('asc_onUpdateChartStyles', () => {
|
||||
// console.log('asc_onUpdateChartStyles', storeFocusObjects.chartObject);
|
||||
if (storeFocusObjects.chartObject && storeFocusObjects.chartObject.get_ChartProperties()) {
|
||||
storeChartSettings.updateChartStyles(api.asc_getChartPreviews(storeFocusObjects.chartObject.get_ChartProperties().getType()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
EditorUIController.ContextMenu = {
|
||||
// Both those methods are taken from this commit:
|
||||
// https://github.com/ONLYOFFICE/web-apps/commit/b0c9a1c5d28371d78ae54854f74f9bdaa8ee9efa
|
||||
// 'edit' in handleMenuItemClick is from
|
||||
// https://github.com/ONLYOFFICE/web-apps/commit/cb62ade641dbdc2c7a2779d408b6d82bbf738500
|
||||
mapMenuItems: (contextMenu) => {
|
||||
// console.log('EditorUIController.ContextMenu.mapMenuItems', contextMenu);
|
||||
|
||||
if ( !Common.EditorApi ) return [];
|
||||
|
||||
const { t } = contextMenu.props;
|
||||
const _t = t("ContextMenu", { returnObjects: true });
|
||||
|
||||
const { isEdit, canViewComments, canReview, isDisconnected } = contextMenu.props;
|
||||
const { isViewer, isProtected } = contextMenu.props;
|
||||
|
||||
// This probably needs to be refired
|
||||
if(!isEdit || isViewer || isProtected)
|
||||
return EditorUIController.ContextMenu.mapMenuItemsReadOnly(contextMenu);
|
||||
|
||||
const api = Common.EditorApi.get();
|
||||
const stack = api.getSelectedElements();
|
||||
const canCopy = api.can_CopyCut();
|
||||
|
||||
let itemsIcon = [],
|
||||
itemsText = [];
|
||||
|
||||
if ( canCopy ) {
|
||||
itemsIcon.push({
|
||||
event: 'copy',
|
||||
icon: 'icon-copy'
|
||||
});
|
||||
}
|
||||
|
||||
if ( canViewComments && contextMenu.isComments && !isEdit ) {
|
||||
itemsText.push({
|
||||
caption: _t.menuViewComment,
|
||||
event: 'viewcomment'
|
||||
});
|
||||
}
|
||||
|
||||
let isText = false,
|
||||
isTable = false,
|
||||
isImage = false,
|
||||
isChart = false,
|
||||
isShape = false,
|
||||
isLink = false,
|
||||
lockedText = false,
|
||||
lockedTable = false,
|
||||
lockedImage = false,
|
||||
lockedHeader = false;
|
||||
|
||||
stack.forEach(item => {
|
||||
const objectType = item.get_ObjectType(),
|
||||
objectValue = item.get_ObjectValue();
|
||||
|
||||
if ( objectType == Asc.c_oAscTypeSelectElement.Header ) {
|
||||
lockedHeader = objectValue.get_Locked();
|
||||
} else
|
||||
if ( objectType == Asc.c_oAscTypeSelectElement.Paragraph ) {
|
||||
lockedText = objectValue.get_Locked();
|
||||
isText = true;
|
||||
} else
|
||||
if ( objectType == Asc.c_oAscTypeSelectElement.Image ) {
|
||||
lockedImage = objectValue.get_Locked();
|
||||
if ( objectValue && objectValue.get_ChartProperties() ) {
|
||||
isChart = true;
|
||||
} else
|
||||
if ( objectValue && objectValue.get_ShapeProperties() ) {
|
||||
isShape = true;
|
||||
} else {
|
||||
isImage = true;
|
||||
}
|
||||
} else
|
||||
if ( objectType == Asc.c_oAscTypeSelectElement.Table ) {
|
||||
lockedTable = objectValue.get_Locked();
|
||||
isTable = true;
|
||||
} else
|
||||
if ( objectType == Asc.c_oAscTypeSelectElement.Hyperlink ) {
|
||||
isLink = true;
|
||||
}
|
||||
});
|
||||
|
||||
if ( stack.length > 0 ) {
|
||||
const swapItems = function(items, indexBefore, indexAfter) {
|
||||
items[indexAfter] = items.splice(indexBefore, 1, items[indexAfter])[0];
|
||||
};
|
||||
|
||||
if ( isEdit && !isDisconnected ) {
|
||||
if ( !lockedText && !lockedTable && !lockedImage && !lockedHeader && canCopy ) {
|
||||
itemsIcon.push({
|
||||
event: 'cut',
|
||||
icon: 'icon-cut'
|
||||
});
|
||||
|
||||
// Swap 'Copy' and 'Cut'
|
||||
swapItems(itemsIcon, 0, 1);
|
||||
}
|
||||
|
||||
if ( !lockedText && !lockedTable && !lockedImage && !lockedHeader ) {
|
||||
itemsIcon.push({
|
||||
event: 'paste',
|
||||
icon: 'icon-paste'
|
||||
});
|
||||
}
|
||||
|
||||
if ( isTable && api.CheckBeforeMergeCells() && !lockedTable && !lockedHeader) {
|
||||
itemsText.push({
|
||||
caption: _t.menuMerge,
|
||||
event: 'merge'
|
||||
});
|
||||
}
|
||||
|
||||
if ( isTable && api.CheckBeforeSplitCells() && !lockedTable && !lockedHeader ) {
|
||||
itemsText.push({
|
||||
caption: _t.menuSplit,
|
||||
event: 'split'
|
||||
});
|
||||
}
|
||||
|
||||
if ( !lockedText && !lockedTable && !lockedImage && !lockedHeader ) {
|
||||
itemsText.push({
|
||||
caption: _t.menuDelete,
|
||||
event: 'delete'
|
||||
});
|
||||
}
|
||||
|
||||
if ( isTable && !lockedTable && !lockedText && !lockedHeader ) {
|
||||
itemsText.push({
|
||||
caption: _t.menuDeleteTable,
|
||||
event: 'deletetable'
|
||||
});
|
||||
}
|
||||
|
||||
if ( !lockedText && !lockedTable && !lockedImage && !lockedHeader ){
|
||||
itemsText.push({
|
||||
caption: _t.menuEdit,
|
||||
event: 'edit'
|
||||
});
|
||||
}
|
||||
|
||||
if ( !!api.can_AddHyperlink() && !lockedHeader) {
|
||||
itemsText.push({
|
||||
caption: _t.menuAddLink,
|
||||
event: 'addlink'
|
||||
});
|
||||
}
|
||||
|
||||
if ( canReview ) {
|
||||
if (contextMenu.inRevisionChange) {
|
||||
itemsText.push({
|
||||
caption: _t.menuReviewChange,
|
||||
event: 'reviewchange'
|
||||
});
|
||||
} else {
|
||||
itemsText.push({
|
||||
caption: _t.menuReview,
|
||||
event: 'review'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if ( contextMenu.isComments && canViewComments ) {
|
||||
itemsText.push({
|
||||
caption: _t.menuViewComment,
|
||||
event: 'viewcomment'
|
||||
});
|
||||
}
|
||||
|
||||
const isObject = isShape || isChart || isImage || isTable;
|
||||
const hideAddComment = !canViewComments || api.can_AddQuotedComment() === false || lockedText || lockedTable || lockedImage || lockedHeader || (!isText && isObject);
|
||||
if ( !hideAddComment ) {
|
||||
itemsText.push({
|
||||
caption: _t.menuAddComment,
|
||||
event: 'addcomment'
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( isLink ) {
|
||||
itemsText.push({
|
||||
caption: _t.menuOpenLink,
|
||||
event: 'openlink'
|
||||
});
|
||||
itemsText.push({
|
||||
caption: _t.menuEditLink,
|
||||
event: 'editlink'
|
||||
});
|
||||
}
|
||||
|
||||
if ( Device.phone && itemsText.length > 2 ) {
|
||||
contextMenu.extraItems = itemsText.splice(2,itemsText.length, {
|
||||
caption: _t.menuMore,
|
||||
event: 'showActionSheet'
|
||||
});
|
||||
}
|
||||
|
||||
const menuItems = itemsIcon.concat(itemsText);
|
||||
// console.log('EditorUIController.ContextMenu.mapMenuItems', menuItems);
|
||||
return menuItems;
|
||||
} ,
|
||||
handleMenuItemClick: (contextMenu, action) => {
|
||||
// console.log('EditorUIController.ContextMenu.handleMenuItemClick', contextMenu, action);
|
||||
|
||||
const api = Common.EditorApi.get();
|
||||
switch (action) {
|
||||
case 'edit':
|
||||
setTimeout(() => {
|
||||
contextMenu.props.openOptions('edit');
|
||||
}, 400);
|
||||
return true;
|
||||
case 'addcomment':
|
||||
Common.Notifications.trigger('addcomment');
|
||||
return true;
|
||||
case 'merge':
|
||||
api.MergeCells();
|
||||
return true;
|
||||
case 'delete':
|
||||
api.asc_Remove();
|
||||
return true;
|
||||
case 'deletetable':
|
||||
api.remTable();
|
||||
return true;
|
||||
case 'editlink':
|
||||
setTimeout(() => {
|
||||
contextMenu.props.openOptions('edit', 'link');
|
||||
}, 400)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
// This method handles the menu items shown when the user is in edit mode but
|
||||
// can't edit the form i.e: in viewer mode or when the document is protected
|
||||
// This is mostly a copy of the else statement of ContextMenu.initMenuItems
|
||||
// with the bare minimum modifications so it can execute.
|
||||
// It is done that way on purpose even if some code ends up duplicated
|
||||
// This should make noticing and following Onlyoffice changes easier
|
||||
mapMenuItemsReadOnly: (contextMenu) => {
|
||||
const { t } = contextMenu.props;
|
||||
const _t = t("ContextMenu", {returnObjects: true});
|
||||
|
||||
const { isEdit, canFillForms, isDisconnected, isViewer, canEditComments, isProtected, typeProtection } = contextMenu.props;
|
||||
const { isComments, canViewComments, canCoAuthoring, canComments, dataDoc } = contextMenu.props;
|
||||
|
||||
const api = Common.EditorApi.get();
|
||||
const inToc = api.asc_GetTableOfContentsPr(true);
|
||||
const stack = api.getSelectedElements();
|
||||
const canCopy = api.can_CopyCut();
|
||||
const docExt = dataDoc ? dataDoc.fileType : '';
|
||||
const isAllowedEditing = !isProtected || typeProtection === Asc.c_oAscEDocProtect.TrackedChanges;
|
||||
const isAllowedCommenting = typeProtection === Asc.c_oAscEDocProtect.Comments;
|
||||
|
||||
let isText = false,
|
||||
isObject = false,
|
||||
isLink = false,
|
||||
locked = false;
|
||||
|
||||
stack.forEach(item => {
|
||||
const objectType = item.get_ObjectType(),
|
||||
objectValue = item.get_ObjectValue();
|
||||
if ( objectType == Asc.c_oAscTypeSelectElement.Header ) {
|
||||
locked = objectValue.get_Locked();
|
||||
} else
|
||||
if ( objectType == Asc.c_oAscTypeSelectElement.Paragraph ) {
|
||||
locked = objectValue.get_Locked();
|
||||
isText = true;
|
||||
} else
|
||||
if ( objectType == Asc.c_oAscTypeSelectElement.Image || objectType == Asc.c_oAscTypeSelectElement.Table) {
|
||||
locked = objectValue.get_Locked();
|
||||
isObject = true;
|
||||
} else if ( objectType == Asc.c_oAscTypeSelectElement.Hyperlink ) {
|
||||
isLink = true;
|
||||
}
|
||||
});
|
||||
|
||||
let itemsIcon = [],
|
||||
itemsText = [];
|
||||
|
||||
if (canCopy) {
|
||||
itemsIcon.push({
|
||||
event: 'copy',
|
||||
icon: 'icon-copy'
|
||||
});
|
||||
}
|
||||
|
||||
if (!isDisconnected) {
|
||||
if (canFillForms && canCopy && !locked && (!isViewer || docExt === 'oform') && isAllowedEditing) {
|
||||
itemsIcon.push({
|
||||
event: 'cut',
|
||||
icon: 'icon-cut'
|
||||
});
|
||||
}
|
||||
|
||||
if (canFillForms && canCopy && !locked && (!isViewer || docExt === 'oform') && isAllowedEditing) {
|
||||
itemsIcon.push({
|
||||
event: 'paste',
|
||||
icon: 'icon-paste'
|
||||
});
|
||||
}
|
||||
|
||||
if (canViewComments && isComments) {
|
||||
itemsText.push({
|
||||
caption: _t.menuViewComment,
|
||||
event: 'viewcomment'
|
||||
});
|
||||
}
|
||||
|
||||
if (api.can_AddQuotedComment() !== false && canCoAuthoring && canComments && !locked && !(!isText && isObject) && (!isViewer || canEditComments) && (isAllowedEditing || isAllowedCommenting)) {
|
||||
itemsText.push({
|
||||
caption: _t.menuAddComment,
|
||||
event: 'addcomment'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (isLink) {
|
||||
itemsText.push({
|
||||
caption: _t.menuOpenLink,
|
||||
event: 'openlink'
|
||||
});
|
||||
|
||||
if(isAllowedEditing && !isViewer) {
|
||||
itemsText.push({
|
||||
caption: t('ContextMenu.menuEditLink'),
|
||||
event: 'editlink'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if(inToc && isEdit && !isViewer && isAllowedEditing) {
|
||||
itemsText.push({
|
||||
caption: t('ContextMenu.textRefreshEntireTable'),
|
||||
event: 'refreshEntireTable'
|
||||
});
|
||||
itemsText.push({
|
||||
caption: t('ContextMenu.textRefreshPageNumbersOnly'),
|
||||
event: 'refreshPageNumbers'
|
||||
});
|
||||
}
|
||||
|
||||
return itemsIcon.concat(itemsText);
|
||||
}
|
||||
};
|
||||
|
||||
// This objects holds the mysterious functions in focusObjects.js inside the intf object
|
||||
// These for now are based on the latest valid implementation from the mobile editor
|
||||
// The easiest way to fix it was to restores those in focusObjects.js: A way to improve would be to do that here.
|
||||
// https://github.com/ONLYOFFICE/web-apps/commit/b0c9a1c5d28371d78ae54854f74f9bdaa8ee9efa
|
||||
// https://github.com/ONLYOFFICE/web-apps/blame/bc7713368a787e01a0ce93a2d7956c77c762e1c5/apps/documenteditor/mobile/src/store/focusObjects.js (for settings or filterFocusObjects)
|
||||
|
||||
EditorUIController.Intf = function (storeFocusObjects) {
|
||||
var obj = {};
|
||||
|
||||
// console.log(window.Asc.c_oAscTypeSelectElement);
|
||||
|
||||
obj.filterFocusObjects = () => {
|
||||
const _settings = [];
|
||||
for (let object of storeFocusObjects._focusObjects) {
|
||||
let type = object.get_ObjectType();
|
||||
if (Asc.c_oAscTypeSelectElement.Paragraph === type) {
|
||||
_settings.push('text', 'paragraph');
|
||||
} else if (Asc.c_oAscTypeSelectElement.Table === type) {
|
||||
_settings.push('table');
|
||||
} else if (Asc.c_oAscTypeSelectElement.Image === type) {
|
||||
if (object.get_ObjectValue().get_ChartProperties()) {
|
||||
// Exclude shapes if chart exist
|
||||
let si = _settings.indexOf('shape');
|
||||
si < 0 ? _settings.push('chart') : _settings.splice(si,1,'chart');
|
||||
} else if (object.get_ObjectValue().get_ShapeProperties() && !_settings.includes('chart')) {
|
||||
_settings.push('shape');
|
||||
} else {
|
||||
_settings.push('image');
|
||||
}
|
||||
} else if (Asc.c_oAscTypeSelectElement.Hyperlink === type) {
|
||||
_settings.push('hyperlink');
|
||||
} else if (Asc.c_oAscTypeSelectElement.Header === type) {
|
||||
_settings.push('header');
|
||||
}
|
||||
}
|
||||
return _settings.filter((value, index, self) => self.indexOf(value) === index);
|
||||
}
|
||||
|
||||
obj.getHeaderObject = () => {
|
||||
const headers = [];
|
||||
for (let object of storeFocusObjects._focusObjects) {
|
||||
if (object.get_ObjectType() == Asc.c_oAscTypeSelectElement.Header) {
|
||||
headers.push(object);
|
||||
}
|
||||
}
|
||||
if (headers.length > 0) {
|
||||
const object = headers[headers.length - 1]; // get top
|
||||
return object.get_ObjectValue();
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
obj.getParagraphObject = () => {
|
||||
const paragraphs = [];
|
||||
for (let object of storeFocusObjects._focusObjects) {
|
||||
if (object.get_ObjectType() === Asc.c_oAscTypeSelectElement.Paragraph) {
|
||||
paragraphs.push(object);
|
||||
}
|
||||
}
|
||||
if (paragraphs.length > 0) {
|
||||
const object = paragraphs[paragraphs.length - 1]; // get top
|
||||
return object.get_ObjectValue();
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
obj.getShapeObject = () => {
|
||||
const shapes = [];
|
||||
for (let object of storeFocusObjects._focusObjects) {
|
||||
if (object.get_ObjectType() === Asc.c_oAscTypeSelectElement.Image) {
|
||||
if (object.get_ObjectValue()
|
||||
&& typeof object.get_ObjectValue().get_ShapeProperties === "function"
|
||||
&& object.get_ObjectValue().get_ShapeProperties()) {
|
||||
shapes.push(object);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (shapes.length > 0) {
|
||||
const object = shapes[shapes.length - 1]; // get top
|
||||
return object.get_ObjectValue();
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
obj.getImageObject = () => {
|
||||
const images = [];
|
||||
for (let object of storeFocusObjects._focusObjects) {
|
||||
if (object.get_ObjectType() == Asc.c_oAscTypeSelectElement.Image) {
|
||||
const imageObject = object.get_ObjectValue();
|
||||
if (imageObject && imageObject.get_ShapeProperties() === null && imageObject.get_ChartProperties() === null) {
|
||||
images.push(object);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (images.length > 0) {
|
||||
const object = images[images.length - 1]; // get top
|
||||
return object.get_ObjectValue();
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
obj.getTableObject = () => {
|
||||
const tables = [];
|
||||
for (let object of storeFocusObjects._focusObjects) {
|
||||
if (object.get_ObjectType() == Asc.c_oAscTypeSelectElement.Table) {
|
||||
tables.push(object);
|
||||
}
|
||||
}
|
||||
if (tables.length > 0) {
|
||||
const object = tables[tables.length - 1]; // get top table
|
||||
return object.get_ObjectValue();
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
obj.getChartObject = () => {
|
||||
const charts = [];
|
||||
for (let object of storeFocusObjects._focusObjects) {
|
||||
if (object.get_ObjectValue()
|
||||
&& typeof object.get_ObjectValue().get_ChartProperties === 'function'
|
||||
&& object.get_ObjectValue().get_ChartProperties() ) {
|
||||
charts.push(object);
|
||||
}
|
||||
}
|
||||
if (charts.length > 0) {
|
||||
const object = charts[charts.length - 1]; // get top table
|
||||
return object.get_ObjectValue();
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
obj.getLinkObject = () => {
|
||||
const links = [];
|
||||
for (let object of storeFocusObjects._focusObjects) {
|
||||
if (object.get_ObjectType() == Asc.c_oAscTypeSelectElement.Hyperlink) {
|
||||
links.push(object);
|
||||
}
|
||||
}
|
||||
if (links.length > 0) {
|
||||
const object = links[links.length - 1]; // get top
|
||||
return object.get_ObjectValue();
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
export default EditorUIController;
|
||||
|
|
@ -1,3 +1,14 @@
|
|||
From de497cfe4ac6a6cdb522bb7463624c91d282b721 Mon Sep 17 00:00:00 2001
|
||||
From: Fabrice <fabrice.roublot@workstreams.ch>
|
||||
Date: Mon, 14 Oct 2024 16:57:25 +0200
|
||||
Subject: [PATCH] add mobile
|
||||
|
||||
---
|
||||
apps/documenteditor/mobile/src/lib/patch.jsx | 2 +-
|
||||
apps/presentationeditor/mobile/src/lib/patch.jsx | 2 +-
|
||||
apps/spreadsheeteditor/mobile/src/lib/patch.jsx | 2 +-
|
||||
3 files changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/apps/documenteditor/mobile/src/lib/patch.jsx b/apps/documenteditor/mobile/src/lib/patch.jsx
|
||||
index 963aca451c..1ee48e8568 100644
|
||||
--- a/apps/documenteditor/mobile/src/lib/patch.jsx
|
||||
|
|
@ -35,3 +46,6 @@ index ec7b37a2ce..bfd8795839 100644
|
|||
+EditorUIController.isSupportEditFeature = () => true;
|
||||
|
||||
export default EditorUIController;
|
||||
--
|
||||
2.30.2
|
||||
|
||||
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 8.9 KiB After Width: | Height: | Size: 8.9 KiB |
Loading…
Reference in New Issue