diff --git a/cell/apiBuilder.js b/cell/apiBuilder.js index fc5365066b..38b50e7a34 100644 --- a/cell/apiBuilder.js +++ b/cell/apiBuilder.js @@ -11848,7 +11848,7 @@ if (ws.AutoFilter) { _range = ws.AutoFilter.Ref; } else { - let filterProps = ws.autoFilters.getAddFormatTableOptions(selectionRange); + let filterProps = ws.autoFilters.getAddFormatTableOptions(this.range.bbox); _range = filterProps && filterProps.range && AscCommonExcel.g_oRangeCache.getAscRange(filterProps.range); } @@ -12035,8 +12035,22 @@ if (VisibleDropDown === false) { autoFilterOptions.asc_setVisibleDropDown(VisibleDropDown); } - ws.autoFilters.applyAutoFilter(autoFilterOptions, ws.selectionRange.getLast().clone()); - //api.asc_applyAutoFilter(autoFilterOptions); + let applyFilterProps = ws.autoFilters.applyAutoFilter(autoFilterOptions, ws.selectionRange.getLast().clone()); + let minChangeRow = applyFilterProps && applyFilterProps.minChangeRow; + if (null !== minChangeRow) { + let oWorksheet = Asc['editor'] && Asc['editor'].wb && Asc['editor'].wb.getWorksheet(); + if (oWorksheet && oWorksheet.objectRender) { + let rangeOldFilter = applyFilterProps && applyFilterProps.rangeOldFilter; + if (rangeOldFilter) { + oWorksheet.objectRender.bUpdateMetrics = false; + oWorksheet._onUpdateFormatTable(rangeOldFilter, true); + oWorksheet.objectRender.bUpdateMetrics = true; + } + if (oWorksheet.objectRender.controller) { + oWorksheet.objectRender.updateSizeDrawingObjects({target: AscCommonExcel.c_oTargetType.RowResize, row: minChangeRow}); + } + } + } } } }; @@ -12140,6 +12154,29 @@ } }); + /** + * Returns a range that represents the expanded range around the current range. + * @memberof ApiRange + * @typeofeditors ["CSE"] + * @returns {ApiRange | null} - Returns the expanded range or null if the range cannot be expanded. + */ + ApiRange.prototype.Expand = function () { + if (!this.range) { + return null; + } + + let bbox = this.range.bbox; + let ws = this.range.worksheet; + let expandRange = ws && ws.autoFilters && ws.autoFilters.expandRange(bbox); + + if (!expandRange) { + return null; + } + + let res = ws.getRange3(expandRange.r1, expandRange.c1, expandRange.r2, expandRange.c2); + return new ApiRange(res); + }; + //------------------------------------------------------------------------------------------------------------------ // // ApiDrawing @@ -18369,6 +18406,7 @@ ApiRange.prototype["SetAutoFilter"] = ApiRange.prototype.SetAutoFilter; ApiRange.prototype["SetFormulaArray"] = ApiRange.prototype.SetFormulaArray; ApiRange.prototype["GetFormulaArray"] = ApiRange.prototype.GetFormulaArray; + ApiRange.prototype["Expand"] = ApiRange.prototype.Expand; diff --git a/cell/model/Workbook.js b/cell/model/Workbook.js index 1c0f2a14ef..b319672bc6 100644 --- a/cell/model/Workbook.js +++ b/cell/model/Workbook.js @@ -16927,11 +16927,13 @@ if(bChange) { var backupObj = this.getValueData(); - for (var i = 0, length = this.multiText.length; i < length; ++i) { - var elem = this.multiText[i]; + let newMultiText = this._cloneMultiText(); + for (var i = 0, length = newMultiText.length; i < length; ++i) { + var elem = newMultiText[i]; if (null != elem.format) fAction(elem.format) } + this.setValueMultiTextInternal(newMultiText); //пробуем преобразовать в простую строку if(this._minimizeMultiText(false)) { @@ -18207,7 +18209,7 @@ } AscCommon.History.EndTransaction(); - this.worksheet.workbook.oApi.onWorksheetChange(this.bbox); + this.worksheet.workbook && this.worksheet.workbook.oApi && this.worksheet.workbook.oApi.onWorksheetChange(this.bbox); }; Range.prototype.setValue2=function(array, pushOnlyFirstMergedCell){ AscCommon.History.Create_NewPoint(); @@ -18230,7 +18232,7 @@ // cell.Remove(); }); AscCommon.History.EndTransaction(); - this.worksheet.workbook.oApi.onWorksheetChange(this.bbox); + this.worksheet.workbook && this.worksheet.workbook.oApi && this.worksheet.workbook.oApi.onWorksheetChange(this.bbox); }; Range.prototype.setValueData = function(val){ AscCommon.History.Create_NewPoint(); diff --git a/cell/model/clipboard.js b/cell/model/clipboard.js index cc4ae45ca1..c35a3efd4c 100644 --- a/cell/model/clipboard.js +++ b/cell/model/clipboard.js @@ -537,13 +537,80 @@ Clipboard.prototype.drawSelectedArea = function (ws, opt_get_bytes) { let activeRange = ws.model.selectionRange.getLast(); - let base64; - //ws.workbook._executeWithoutZoom(function () { - let ctx = ws.workbook.printForCopyPaste(ws, activeRange); - if (ctx && ctx.canvas) { - base64 = ctx.canvas.toDataURL("image/png"); + // Canvas limitations for different browsers: + // Chrome/Edge: 32767px x 32767px + // Firefox: 32767px x 32767px + // Safari: 4096px x 4096px (most restrictive) + // IE9+: 8192px x 8192px + // IE8: 4096px x 4096px + + let maxCanvasHeight, maxCanvasWidth, maxCanvasArea; + + if (AscCommon.AscBrowser.isIE) { + maxCanvasHeight = 8192; + maxCanvasWidth = 8192; + maxCanvasArea = 8192 * 8192; + } else if (AscCommon.AscBrowser.isSafariMacOs) { + // Safari (not Chrome) + maxCanvasHeight = 4096; + maxCanvasWidth = 4096; + maxCanvasArea = 4096 * 4096; + } else { + // Chrome, Firefox, Edge and other modern browsers + maxCanvasHeight = 32767; + maxCanvasWidth = 32767; + maxCanvasArea = 268435456; + } + + let estimatedHeight = ws._getRowTop(activeRange.r2 + 1) - ws._getRowTop(activeRange.r1); + let estimatedWidth = ws._getColLeft(activeRange.c2 + 1) - ws._getColLeft(activeRange.c1); + + // Check height limitations + if (estimatedHeight > maxCanvasHeight) { + let currentHeight = 0; + let maxRow = activeRange.r1; + + for (let row = activeRange.r1; row <= activeRange.r2; row++) { + let rowHeight = ws._getRowHeight(row); + if (currentHeight + rowHeight > maxCanvasHeight) { + break; + } + currentHeight += rowHeight; + maxRow = row; } - //}) + + activeRange = new Asc.Range(activeRange.c1, activeRange.r1, activeRange.c2, maxRow); + estimatedHeight = ws._getRowTop(activeRange.r2 + 1) - ws._getRowTop(activeRange.r1); + } + + // Check width limitations + if (estimatedWidth > maxCanvasWidth) { + let currentWidth = 0; + let maxCol = activeRange.c1; + + for (let col = activeRange.c1; col <= activeRange.c2; col++) { + let colWidth = ws._getColLeft(col + 1) - ws._getColLeft(col); + if (currentWidth + colWidth > maxCanvasWidth) { + break; + } + currentWidth += colWidth; + maxCol = col; + } + + activeRange = new Asc.Range(activeRange.c1, activeRange.r1, maxCol, activeRange.r2); + estimatedWidth = ws._getColLeft(activeRange.c2 + 1) - ws._getColLeft(activeRange.c1); + } + + //TODO cut by max size + if (estimatedHeight * estimatedWidth >= maxCanvasArea) { + return; + } + + let base64; + let ctx = ws.workbook.printForCopyPaste(ws, activeRange, true); + if (ctx && ctx.canvas) { + base64 = ctx.canvas.toDataURL("image/png"); + } if (opt_get_bytes && base64) { // Get base64 data without header diff --git a/cell/view/WorkbookView.js b/cell/view/WorkbookView.js index c63fe2f500..37ca31fbbb 100644 --- a/cell/view/WorkbookView.js +++ b/cell/view/WorkbookView.js @@ -4022,16 +4022,26 @@ return page; }; - WorkbookView.prototype.printForCopyPaste = function (ws, oRange) { + WorkbookView.prototype.printForCopyPaste = function (ws, oRange, ignoreScaling) { var sizes = ws.getRangePosition(oRange); + let scaleFactor = ignoreScaling ? AscBrowser.retinaPixelRatio /** ws.getZoom()*/ : 1; if (sizes) { - sizes.width += 1; - sizes.height += 1; + sizes.width += 1*scaleFactor; + sizes.height += 1*scaleFactor; } + var page = this.getSimulatePageForCopyPaste(sizes, oRange); - var previewOleObjectContext = AscCommonExcel.getContext(sizes.width, sizes.height, this); + var previewOleObjectContext = AscCommonExcel.getContext(sizes.width/scaleFactor, sizes.height/scaleFactor, this); previewOleObjectContext.DocumentRenderer = AscCommonExcel.getGraphics(previewOleObjectContext); previewOleObjectContext.isNotDrawBackground = !this.Api.isFromSheetEditor; + + if (scaleFactor !== 1) { + previewOleObjectContext.ppiX = previewOleObjectContext.ppiX/scaleFactor; + previewOleObjectContext.ppiY = previewOleObjectContext.ppiY/scaleFactor; + previewOleObjectContext.setTransform(1/scaleFactor, 0, 0, 1/scaleFactor, 0, 0); + previewOleObjectContext.updateTransforms && previewOleObjectContext.updateTransforms(); + } + let renderingSettings = ws.getRenderingSettings(); if (!renderingSettings) { renderingSettings = ws.initRenderingSettings(); diff --git a/cell/view/WorksheetView.js b/cell/view/WorksheetView.js index 02d5ac072d..ed1bc470d0 100644 --- a/cell/view/WorksheetView.js +++ b/cell/view/WorksheetView.js @@ -27691,6 +27691,67 @@ function isAllowPasteLink(pastedWb) { oController.removeAllInks(arrInks); } }; + WorksheetView.prototype.getSelectionCoords = function () { + let range = this._getSelection(); + range = range && range.getLast(); + if (!range) { + return null; + } + var visibleRange = this.getVisibleRange(); + var intersectionVisibleRange = visibleRange.intersection(range); + if (!intersectionVisibleRange && this.topLeftFrozenCell) { + var cFrozen = this.topLeftFrozenCell.getCol0(); + var rFrozen = this.topLeftFrozenCell.getRow0(); + cFrozen -= 1; + rFrozen -= 1; + + var frozenRange; + if (0 <= cFrozen && 0 <= rFrozen) { + frozenRange = new asc_Range(0, 0, cFrozen, rFrozen); + intersectionVisibleRange = frozenRange.intersection(range); + } + if (!intersectionVisibleRange && 0 <= cFrozen) { + frozenRange = new asc_Range(0, this.visibleRange.r1, cFrozen, this.visibleRange.r2); + intersectionVisibleRange = frozenRange.intersection(range); + + } + if (!intersectionVisibleRange && 0 <= rFrozen) { + frozenRange = new asc_Range(this.visibleRange.c1, 0, this.visibleRange.c2, rFrozen); + intersectionVisibleRange = frozenRange.intersection(range); + } + } + + let res = null; + if (!intersectionVisibleRange) { + range = visibleRange; + intersectionVisibleRange = visibleRange; + } + + if (range && intersectionVisibleRange) { + let _elem = this.workbook.Api && this.workbook.Api.HtmlElement + let offs = _elem && AscCommon.UI && AscCommon.UI.getBoundingClientRect && AscCommon.UI.getBoundingClientRect(_elem); + if (offs) { + res = []; + + res[0] = this.getCellCoord(range.c1, range.r1); + res[1] = this.getCellCoord(intersectionVisibleRange.c2, intersectionVisibleRange.r2); + + if (this.getRightToLeft()) { + res[0]._x += res[0]._width; + res[1]._x += res[1]._width; + } + + res[0]._x += offs.left; + res[1]._x += offs.left; + res[0]._y += offs.top; + res[1]._y += offs.top; + } + } + + return res; + }; + + diff --git a/common/Drawings/GraphicsBase.js b/common/Drawings/GraphicsBase.js index f92ec0f26d..851ece2d73 100644 --- a/common/Drawings/GraphicsBase.js +++ b/common/Drawings/GraphicsBase.js @@ -451,6 +451,10 @@ CGraphicsBase.prototype.drawFlowAnchor = function(x, y) { }; + + CGraphicsBase.prototype.drawPermissionMark = function(x, y, h, isStart, isActive) + { + }; CGraphicsBase.prototype.DrawFootnoteRect = function(x, y, w, h) { diff --git a/common/HistoryCommon.js b/common/HistoryCommon.js index c636fc764b..d4ebd8036f 100644 --- a/common/HistoryCommon.js +++ b/common/HistoryCommon.js @@ -4672,7 +4672,10 @@ window['AscDFH'].historydescription_Pdf_ChangeField = 0x2b6; // reserved - window['AscDFH'].historydescription_GroupPoints = 0xFF01; + window['AscDFH'].historydescription_GroupPoints = 0xFF01; + window['AscDFH'].historydescription_GroupPointsOpen = 0xFF02; + + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/common/apiBase.js b/common/apiBase.js index b2745a77c2..8e98493f5c 100644 --- a/common/apiBase.js +++ b/common/apiBase.js @@ -4030,14 +4030,21 @@ ret.W = Math.max(document.documentElement.clientWidth, window.innerWidth || 0); ret.H = Math.max(document.documentElement.clientHeight, window.innerHeight || 0); + ret.editorX = 0; + ret.editorY = 0; + switch (this.editorId) { case c_oEditorId.Word: { - ret.X += this.WordControl.X; - ret.Y += this.WordControl.Y; - ret.X += (this.WordControl.m_oMainView.AbsolutePosition.L * AscCommon.g_dKoef_mm_to_pix); - ret.Y += (this.WordControl.m_oMainView.AbsolutePosition.T * AscCommon.g_dKoef_mm_to_pix); + ret.editorX += this.WordControl.X; + ret.editorX += (this.WordControl.m_oMainView.AbsolutePosition.L * AscCommon.g_dKoef_mm_to_pix); + ret.editorY += this.WordControl.Y; + ret.editorY += (this.WordControl.m_oMainView.AbsolutePosition.T * AscCommon.g_dKoef_mm_to_pix); + + ret.X += ret.editorX; + ret.Y += ret.editorY; + ret.X += (this.WordControl.m_oDrawingDocument.TargetHtmlElementLeft); ret.Y += (this.WordControl.m_oDrawingDocument.TargetHtmlElementTop); @@ -4049,20 +4056,23 @@ } case c_oEditorId.Presentation: { - ret.X += this.WordControl.X; - ret.Y += this.WordControl.Y; + ret.editorX += this.WordControl.X; + ret.editorX += (this.WordControl.m_oMainParent.AbsolutePosition.L * AscCommon.g_dKoef_mm_to_pix); - ret.X += (this.WordControl.m_oMainParent.AbsolutePosition.L * AscCommon.g_dKoef_mm_to_pix); + ret.X += ret.editorX; + ret.editorY += this.WordControl.Y; if (!this.WordControl.m_oLogicDocument.IsFocusOnNotes()) { - ret.Y += (this.WordControl.m_oMainView.AbsolutePosition.T * AscCommon.g_dKoef_mm_to_pix); + ret.editorY += (this.WordControl.m_oMainView.AbsolutePosition.T * AscCommon.g_dKoef_mm_to_pix); } else { - ret.Y += (this.WordControl.m_oNotesContainer.AbsolutePosition.T * AscCommon.g_dKoef_mm_to_pix); + ret.editorY += (this.WordControl.m_oNotesContainer.AbsolutePosition.T * AscCommon.g_dKoef_mm_to_pix); } + ret.Y += ret.editorY; + ret.X += (this.WordControl.m_oDrawingDocument.TargetHtmlElementLeft); ret.Y += (this.WordControl.m_oDrawingDocument.TargetHtmlElementTop); @@ -4093,6 +4103,16 @@ ret.Y = drDoc.TargetHtmlElementTop; ret.TargetH = drDoc.m_dTargetSize * this.asc_getZoom() * AscCommon.g_dKoef_mm_to_pix; off = this.HtmlElement; + } else if (Asc.c_oAscSelectionType.RangeCells === selectionType || + Asc.c_oAscSelectionType.RangeRow === selectionType || + Asc.c_oAscSelectionType.RangeCol === selectionType) + { + let ws = this.wb.getWorksheet(); + let activeCellCoord = ws.getSelectionCoords(); + if (activeCellCoord) { + ret.X = activeCellCoord[0]._x /*+ activeCellCoord[0]._width*/; + ret.Y = activeCellCoord[0]._y /*+ activeCellCoord[0]._height*/; + } } if (off) { @@ -5712,6 +5732,33 @@ plugins.callMethod(plugins.internalGuid, name, params); }; + baseEditorsApi.prototype["native_callCommand"] = function(funcText, params) + { + if (!this.canRunBuilderScript()) + return; + + let jsonParam = (typeof params === "string") ? params : JSON.stringify(params); + this._beforeEvalCommand(); + let script = "(function(){let Asc={};Asc.scope=" + jsonParam + ";return (" + funcText + ")(Asc.scope);})();"; + let commandReturnValue = AscCommon.safePluginEval(script); + this._afterEvalCommand(undefined); + this.onEndBuilderScript(); + + if (!Asc.checkReturnCommand(commandReturnValue)) + commandReturnValue = undefined; + return commandReturnValue; + }; + + baseEditorsApi.prototype["native_callMethod"] = function(name, params) + { + let returnValue = undefined; + + this.callMethod(name, params, function(retValue) { + returnValue = retValue; + }); + + return returnValue; + }; baseEditorsApi.prototype.asc_mergeSelectedShapes = function(operation) { if(AscCommon['PathBoolean']) { @@ -5822,10 +5869,11 @@ { ++this.groupActionsCounter; + AscCommon.History.startGroupPoints(); + if (this.groupActionsCounter > 1) return; - AscCommon.History.startGroupPoints(); AscCommon.CollaborativeEditing.Set_GlobalLock(true); AscCommon.CollaborativeEditing.Set_GlobalLockSelection(true); }; @@ -5861,9 +5909,14 @@ if (!this.isGroupActions()) return; + --this.groupActionsCounter; + AscCommon.History.cancelGroupPoints(); + + if (this.groupActionsCounter > 0) + return; + AscCommon.CollaborativeEditing.Set_GlobalLock(false); AscCommon.CollaborativeEditing.Set_GlobalLockSelection(false); - AscCommon.History.cancelGroupPoints(); }; baseEditorsApi.prototype.endGroupActions = function() { @@ -5871,12 +5924,13 @@ return; --this.groupActionsCounter; + AscCommon.History.endGroupPoints(); + if (this.groupActionsCounter > 0) return; AscCommon.CollaborativeEditing.Set_GlobalLock(false); AscCommon.CollaborativeEditing.Set_GlobalLockSelection(false); - AscCommon.History.endGroupPoints(); }; baseEditorsApi.prototype.isGroupActions = function() { diff --git a/common/apiBase_plugins.js b/common/apiBase_plugins.js index 97d995743d..ad26bea4a2 100644 --- a/common/apiBase_plugins.js +++ b/common/apiBase_plugins.js @@ -2090,6 +2090,13 @@ h += (offsets.H - b); } + if (y > offsets.H) + y = offsets.H - h; + if (y < offsets.editorY) + y = offsets.editorY; + if (x < offsets.editorX) + x = offsets.editorX; + variation["size"] = [w, h]; variation["positionX"] = x; variation["positionY"] = y; diff --git a/common/editorscommon.js b/common/editorscommon.js index fd558ea80c..b433683f97 100644 --- a/common/editorscommon.js +++ b/common/editorscommon.js @@ -11117,6 +11117,13 @@ return true === isDark ? res.Dark : res.Light; } + function setUserColorById(userId, light, dark) + { + g_oUserColorById[userId] = { + Light : new CColor(light.r, light.g, light.b, 255), + Dark : new CColor(dark.r, dark.g, dark.b, 255), + }; + } function getUserColorById(userId, userName, isDark, isNumericValue) { let color = _getUserColorById(userId, userName, isDark); @@ -15470,6 +15477,7 @@ window["AscCommon"].getUrlType = getUrlType; window["AscCommon"].prepareUrl = prepareUrl; window["AscCommon"].getUserColorById = getUserColorById; + window["AscCommon"].setUserColorById = setUserColorById; window["AscCommon"].isNullOrEmptyString = isNullOrEmptyString; window["AscCommon"].unleakString = unleakString; window["AscCommon"].readValAttr = readValAttr; diff --git a/common/plugins/plugin_base.js b/common/plugins/plugin_base.js index eef4932ae7..8514b1efb3 100644 --- a/common/plugins/plugin_base.js +++ b/common/plugins/plugin_base.js @@ -823,8 +823,10 @@ { if (window.Asc.plugin.onCallCommandCallback) { - window.Asc.plugin.onCallCommandCallback(pluginData.commandReturnData); + var methodCallback = window.Asc.plugin.onCallCommandCallback; window.Asc.plugin.onCallCommandCallback = null; + methodCallback(pluginData.commandReturnData); + methodCallback = null; } else if (window.Asc.plugin.onCommandCallback) window.Asc.plugin.onCommandCallback(pluginData.commandReturnData); diff --git a/common/wordcopypaste.js b/common/wordcopypaste.js index 3aaade54b9..093bfc618f 100644 --- a/common/wordcopypaste.js +++ b/common/wordcopypaste.js @@ -3850,7 +3850,7 @@ PasteProcessor.prototype = } window['AscCommon'].g_specialPasteHelper.Paste_Process_End(); - this.pasteCallback && this.pasteCallback(oPaste.insert); + return oPaste.insert; }, _setSpecialPasteShowOptionsPresentation: function(props){ @@ -7222,6 +7222,9 @@ PasteProcessor.prototype = var fPasteTextPresentationCallback = function () { var executePastePresentation = function () { oThis.InsertInPlacePresentation(oThis.aContent, true); + if (oThis.pasteCallback) { + oThis.pasteCallback(true); + } }; var presentation = editor.WordControl.m_oLogicDocument; diff --git a/pdf/api.js b/pdf/api.js index f95525fe22..a879d71e9d 100644 --- a/pdf/api.js +++ b/pdf/api.js @@ -1550,13 +1550,13 @@ let aActionsFormat = [{ "S": AscPDF.ACTIONS_TYPES.JavaScript, - "JS": 'AFDate_Format("' + sFormat + '");' + "JS": 'AFDate_FormatEx("' + sFormat + '");' }] oField.SetActions(AscPDF.FORMS_TRIGGERS_TYPES.Format, aActionsFormat); let aActionsKeystroke = [{ "S": AscPDF.ACTIONS_TYPES.JavaScript, - "JS": 'AFDate_Keystroke("' + sFormat + '");' + "JS": 'AFDate_KeystrokeEx("' + sFormat + '");' }]; oField.SetActions(AscPDF.FORMS_TRIGGERS_TYPES.Keystroke, aActionsKeystroke); if (oField.IsCanCommit()) { @@ -1593,13 +1593,13 @@ let aActionsFormat = [{ "S": AscPDF.ACTIONS_TYPES.JavaScript, - "JS": 'AFTime_Format(' + nFormat + ');' + "JS": 'AFTime_FormatEx(' + nFormat + ');' }] oField.SetActions(AscPDF.FORMS_TRIGGERS_TYPES.Format, aActionsFormat); let aActionsKeystroke = [{ "S": AscPDF.ACTIONS_TYPES.JavaScript, - "JS": 'AFTime_Keystroke(' + nFormat + ');' + "JS": 'AFTime_KeystrokeEx(' + nFormat + ');' }]; oField.SetActions(AscPDF.FORMS_TRIGGERS_TYPES.Keystroke, aActionsKeystroke); if (oField.IsCanCommit()) { diff --git a/pdf/src/document.js b/pdf/src/document.js index bff5731f7c..027a6452c0 100644 --- a/pdf/src/document.js +++ b/pdf/src/document.js @@ -3535,7 +3535,7 @@ var CPresentation = CPresentation || function(){}; let bUseContentsAsComment = oAnnot.IsUseContentAsComment(); if (oAnnot.IsUseInDocument()) { - if ((bUseContentsAsComment && oAnnot.GetContents()) || (bUseContentsAsComment == false && oAnnot.GetReply(0) instanceof AscPDF.CAnnotationText)) { + if ((bUseContentsAsComment && oAnnot.GetContents() != null) || (bUseContentsAsComment == false && oAnnot.GetReply(0) instanceof AscPDF.CAnnotationText)) { editor.sendEvent("asc_onAddComment", oAnnot.GetId(), oAnnot.GetAscCommentData()); } } @@ -6125,7 +6125,6 @@ var CPresentation = CPresentation || function(){}; author: sAuthor, modDate: nCurTime, creationDate: nCurTime, - contents: '', hidden: false } diff --git a/slide/Drawing/Transitions.js b/slide/Drawing/Transitions.js index 0a10935f38..82601e608a 100644 --- a/slide/Drawing/Transitions.js +++ b/slide/Drawing/Transitions.js @@ -4011,6 +4011,9 @@ function CDemonstrationManager(htmlpage) this.onMouseDown = function(e) { + oThis.startPageX = e.pageX; + oThis.startPageY = e.pageY; + AscCommon.global_mouseEvent.LockMouse() var documentMI = oThis.documentMouseInfo(e); if (documentMI) @@ -4131,12 +4134,34 @@ function CDemonstrationManager(htmlpage) AscCommon.global_mouseEvent.UnLockMouse(); - const isMouseDown = oThis.isMouseDown || isFromMainToReporterMouseDown; - oThis.isMouseDown = false; + const isMouseDown = oThis.isMouseDown || isFromMainToReporterMouseDown; + oThis.isMouseDown = false; if (isFromMainToReporter && oThis.PointerDiv && oThis.HtmlPage.m_oApi.isReporterMode) oThis.PointerRemove(); - if (oThis.PointerDiv && oThis.HtmlPage.m_oApi.isReporterMode) + let handleSwipe = false; + if (e.pointerType === "touch") + { + let iN = AscFormat.isRealNumber; + if (iN(oThis.startPageX) && iN(oThis.startPageY) && iN(e.pageX) && iN(e.pageY) ) + { + if (e.pageX - oThis.startPageX > 20) + { + oThis.OnPrevSlide(); + handleSwipe = true; + } + else if (oThis.startPageX - e.pageX > 20 || + (Math.abs(e.pageX - oThis.startPageX) < 1 && + Math.abs(e.pageY- oThis.startPageY) < 1)) + { + oThis.OnNextSlide(); + handleSwipe = true; + } + } + } + this.startPageX = null; + this.startPageY = null; + if (handleSwipe || oThis.PointerDiv && oThis.HtmlPage.m_oApi.isReporterMode) { AscCommon.stopEvent(e); return false; diff --git a/slide/api.js b/slide/api.js index d939463e75..f611cba2e4 100644 --- a/slide/api.js +++ b/slide/api.js @@ -7043,8 +7043,8 @@ background-repeat: no-repeat;\ return oPresentation.GetSelectedText(true); } - const value = AscCommon.isRealObject(aSelectedArray[0].nvSpPr.cNvPr.hlinkClick); - return value ? false : null; + const cNvProps = aSelectedArray[0].getCNvProps(); + return cNvProps && AscCommon.isRealObject(cNvProps.hlinkClick) ? false : null; }; // HyperProps - объект CHyperlinkProperty diff --git a/slide/apiBuilder.js b/slide/apiBuilder.js index 962740a867..6634152a94 100644 --- a/slide/apiBuilder.js +++ b/slide/apiBuilder.js @@ -364,6 +364,10 @@ * @typedef {("body" | "chart" | "clipArt" | "ctrTitle" | "diagram" | "date" | "footer" | "header" | "media" | "object" | "picture" | "sldImage" | "sldNumber" | "subTitle" | "table" | "title")} PlaceholderType - Available placeholder types. */ + /** + * @typedef {("blank" | "chart" | "chartAndTx" | "clipArtAndTx" | "clipArtAndVertTx" | "cust" | "dgm" | "fourObj" | "mediaAndTx" | "obj" | "objAndTwoObj" | "objAndTx" | "objOnly" | "objOverTx" | "objTx" | "picTx" | "secHead" | "tbl" | "title" | "titleOnly" | "twoColTx" | "twoObj" | "twoObjAndObj" | "twoObjAndTx" | "twoObjOverTx" | "twoTxTwoObj" | "tx" | "txAndChart" | "txAndClipArt" | "txAndMedia" | "txAndObj" | "txAndTwoObj" | "txOverObj" | "vertTitleAndTx" | "vertTitleAndTxOverChart" | "vertTx")} LayoutType - Available layout types. + */ + /** * Any valid drawing element. * @typedef {(ApiShape | ApiImage | ApiGroup | ApiOleObject | ApiTable | ApiChart )} Drawing @@ -725,7 +729,7 @@ * @returns {ApiShape} * @see office-js-api/Examples/{Editor}/Api/Methods/CreateShape.js */ - Api.prototype.CreateShape = function(sType, nWidth, nHeight, oFill, oStroke){ + Api.prototype.CreateShape = function(sType, nWidth, nHeight, oFill, oStroke){ var oCurrentSlide = private_GetCurrentSlide(); sType = sType || "rect"; nWidth = nWidth || 914400; @@ -1170,12 +1174,17 @@ * @typeofeditors ["CPE"] * @memberof ApiPresentation * @param {ApiSlide} oSlide - The slide created using the {@link Api#CreateSlide} method. + * @param {?number} nIndex - Index of the slide to be added. If not specified, the slide will be added to the end of the presentation. * @see office-js-api/Examples/{Editor}/ApiPresentation/Methods/AddSlide.js */ - ApiPresentation.prototype.AddSlide = function(oSlide) { + ApiPresentation.prototype.AddSlide = function(oSlide, nIndex) { if(this.Presentation){ oSlide.Slide.setSlideNum(this.Presentation.Slides.length); - this.Presentation.insertSlide(this.Presentation.Slides.length, oSlide.Slide); + let index = this.Presentation.Slides.length; + if(AscFormat.isRealNumber(nIndex) && nIndex >= 0 && nIndex < this.Presentation.Slides.length) { + index = nIndex; + } + this.Presentation.insertSlide(index, oSlide.Slide); } }; @@ -1829,6 +1838,21 @@ return new ApiLayout(this.Master.sldLayoutLst[nPos]) }; + /** + * Returns a layout of the specified slide master by its position. + * @typeofeditors ["CPE"] + * @param {LayoutType} sType - Layout position. + * @returns {ApiLayout | null} - returns null if position is invalid. + * @see office-js-api/Examples/{Editor}/ApiMaster/Methods/GetLayoutByType.js + */ + ApiMaster.prototype.GetLayoutByType = function(sType) + { + let type = AscCommonSlide.LAYOUT_TYPE_MAP[sType]; + let layout = this.Master.getMatchingLayout(type) + if(!layout) return null; + return new ApiLayout(layout) + }; + /** * Adds a layout to the specified slide master. * @typeofeditors ["CPE"] @@ -2266,6 +2290,17 @@ return true; }; + /** + * Returns a type if the current layout. + * @typeofeditors ["CPE"] + * @returns {boolean} + * @see office-js-api/Examples/{Editor}/ApiLayout/Methods/GetLayoutType.js + */ + ApiLayout.prototype.GetLayoutType = function() + { + this.Layout.getType(); + }; + /** * Returns a name of the current layout. * @typeofeditors ["CPE"] @@ -5407,6 +5442,7 @@ ApiMaster.prototype["GetClassType"] = ApiMaster.prototype.GetClassType; ApiMaster.prototype["GetAllLayouts"] = ApiMaster.prototype.GetAllLayouts; ApiMaster.prototype["GetLayout"] = ApiMaster.prototype.GetLayout; + ApiMaster.prototype["GetLayoutByType"] = ApiMaster.prototype.GetLayoutByType; ApiMaster.prototype["AddLayout"] = ApiMaster.prototype.AddLayout; ApiMaster.prototype["RemoveLayout"] = ApiMaster.prototype.RemoveLayout; ApiMaster.prototype["GetLayoutsCount"] = ApiMaster.prototype.GetLayoutsCount; @@ -5432,6 +5468,8 @@ ApiLayout.prototype["GetClassType"] = ApiLayout.prototype.GetClassType; ApiLayout.prototype["SetName"] = ApiLayout.prototype.SetName; + ApiLayout.prototype["GetLayoutType"] = ApiLayout.prototype.GetLayoutType; + ApiLayout.prototype["GetName"] = ApiLayout.prototype.GetName; ApiLayout.prototype["AddObject"] = ApiLayout.prototype.AddObject; ApiLayout.prototype["RemoveObject"] = ApiLayout.prototype.RemoveObject; ApiLayout.prototype["SetBackground"] = ApiLayout.prototype.SetBackground; diff --git a/tests/word/builder/api/replace-text-smart.js b/tests/word/builder/api/replace-text-smart.js index bbffde0076..434b18c0bc 100644 --- a/tests/word/builder/api/replace-text-smart.js +++ b/tests/word/builder/api/replace-text-smart.js @@ -238,7 +238,7 @@ $(function () ]); AscTest.SelectParagraph(p); - AscTest.Editor.ReplaceTextSmart(["text added in review and another interted text"]); + AscTest.Editor.ReplaceTextSmart(["text added in review and another inserted text"]); assert.deepEqual( GetParagraphRunsInfo(p), @@ -250,12 +250,16 @@ $(function () ["o", {Italic: true}, reviewtype_Common], ["mmo", {Italic: true}, reviewtype_Remove], ["ther i", {Italic: true}, reviewtype_Add], - ["nterted text", {Italic: true}, reviewtype_Common] + ["n", {Italic: true}, reviewtype_Common], + ["serted", {Italic: true}, reviewtype_Add], + [" text", {Italic: true}, reviewtype_Common] ], "ReplaceTextSmart - replace reviewed changes with track revisions" ); ///////////////// 3 ////////////// + // TODO: Этот тест неправильно работает, если отключить рецензирование + // TODO: С включенным рецензированием разница отдается странно, возможно проблема с набивкой текста p = fillDocument([ {text: "text removed by first user and ", pr: {Bold: true}, reviewType: reviewtype_Remove}, {text: "common text and ", pr: {Italic: true}}, @@ -272,7 +276,8 @@ $(function () GetParagraphRunsInfo(p), [ ["text removed by first user and ", {Bold: true}, reviewtype_Remove], - ["edited commo", {Italic: true}, reviewtype_Common], + ["edited ", {Italic: true}, reviewtype_Add], + ["commo", {Italic: true}, reviewtype_Common], ["n text a", {Italic: true}, reviewtype_Remove], ["n", {Italic: true}, reviewtype_Common], ["d", {Italic: true}, reviewtype_Remove], diff --git a/word/Drawing/Graphics.js b/word/Drawing/Graphics.js index 3fb3fce7b6..cf80fed98a 100644 --- a/word/Drawing/Graphics.js +++ b/word/Drawing/Graphics.js @@ -2579,6 +2579,51 @@ this.m_oFullTransform.sy,this.m_oFullTransform.tx,this.m_oFullTransform.ty); } }; + + CGraphics.prototype.drawPermissionMark = function(x, y, h, isStart, isActive) + { + if (isActive) + this.p_color(164, 160, 0, 255); + else + this.p_color(127, 127, 127, 255); + + if (!global_MatrixTransformer.IsIdentity2(this.m_oTransform)) + { + let coeff = this.m_oCoordTransform.sx; + + this.p_width(2 / coeff * 1000); + let shift = isStart ? 3 / coeff : -3 / coeff; + this._s(); + this._m(x + shift, y); + this._l(x, y); + this._l(x, y + h); + this._l(x + shift, y + h); + this.ds(); + this._s(); + } + else + { + let pen_w = 2; + + let ctx = this.m_oContext; + ctx.setTransform(1, 0, 0, 1, 0, 0); + ctx.lineWidth = 2; + + let _y = (this.m_oFullTransform.TransformPointY(x, y) >> 0) + 0.5 - 0.5; + let _b = (this.m_oFullTransform.TransformPointY(x, y + h) >> 0) + 0.5 - 0.5; + + let _x0 = (this.m_oFullTransform.TransformPointX(x, y) >> 0) + 0.5 - 0.5 - pen_w / 2; + let _x1 = _x0 + (isStart ? pen_w / 2 + 3 : -pen_w / 2 - 3); + + ctx.beginPath(); + ctx.moveTo(_x1, _y); + ctx.lineTo(_x0, _y); + ctx.lineTo(_x0, _b); + ctx.lineTo(_x1, _b); + ctx.stroke(); + ctx.beginPath(); + } + }; CGraphics.prototype.StartClipPath = function() { diff --git a/word/Editor/Document.js b/word/Editor/Document.js index 0894bc1e8c..7d29d55f05 100644 --- a/word/Editor/Document.js +++ b/word/Editor/Document.js @@ -2924,6 +2924,8 @@ CDocument.prototype.FinalizeAction = function(checkEmptyAction) var oCurrentParagraph = this.GetCurrentParagraph(false, false) if (oCurrentParagraph && oCurrentParagraph.IsInFixedForm()) oCurrentParagraph.GetParent().CheckFormViewWindow(); + + this.private_CheckCursorPosInFillingFormMode(); this.Action.Start = false; this.Action.Depth = 0; @@ -10636,7 +10638,7 @@ CDocument.prototype.canEnterText = function() return false; if (this.Api.isRestrictionComments() || this.Api.isRestrictionView()) - return this._checkPermRangeForCurrentSelection(); + return this._checkPermRangeForCurrentSelection(AscCommon.changestype_Paragraph_AddText); else if (this.IsFillingFormMode()) return this.IsInFormField(false, true); @@ -12249,6 +12251,22 @@ CDocument.prototype.GetSelectedParagraphs = function() { return this.GetCurrentParagraph(false, true); }; +/** + * возвращаем первый параграф в выделении (а не тот, с которого начали выделение) + * @returns {?AscWord.Paragraph} + */ +CDocument.prototype.GetFirstParagraphInSelection = function() +{ + return this.GetCurrentParagraph(false, false, {FirstInSelection : true}); +}; +/** + * возвращаем последний параграф в выделении (а не тот, на котором закончили выделение) + * @returns {?AscWord.Paragraph} + */ +CDocument.prototype.GetLastParagraphInSelection = function() +{ + return this.GetCurrentParagraph(false, false, {LastInSelection : true}); +}; /** * Получаем текущую таблицу * @returns {?CTable} @@ -13779,7 +13797,7 @@ CDocument.prototype.IsPermRangeEditing = function(changesType, additionalData, a else if (AscCommon.changestype_Paragraph_Properties === changesType) { let selectedParagraphs = this.GetSelectedParagraphs(); - if (!this._checkPermRangeForCurrentSelection()) + if (!this._checkPermRangeForCurrentSelection(changesType)) return false; if (0 !== selectedParagraphs.length && !this._checkPermRangeForElement(selectedParagraphs[0])) @@ -13793,7 +13811,7 @@ CDocument.prototype.IsPermRangeEditing = function(changesType, additionalData, a if (!this._checkChangesTypeForPermRangeForSelection(changesType)) return false; - if (!this._checkPermRangeForCurrentSelection()) + if (!this._checkPermRangeForCurrentSelection(changesType)) return false; } } @@ -13843,7 +13861,7 @@ CDocument.prototype.IsPermRangeEditing = function(changesType, additionalData, a } else if (AscCommon.changestype_2_AdditionalTypes === additionalData.Type) { - if (!t._checkPermRangeForCurrentSelection()) + if (!t._checkPermRangeForCurrentSelection(AscCommon.changestype_None)) return false; for (let i = 0, count = additionalData.Types.length; i < count; ++i) @@ -13925,7 +13943,7 @@ CDocument.prototype._checkChangesTypeForPermRangeForSelection = function(changes || AscCommon.changestype_Delete === changesType || AscCommon.changestype_Text_Props === changesType); }; -CDocument.prototype._checkPermRangeForCurrentSelection = function() +CDocument.prototype._checkPermRangeForCurrentSelection = function(changesType) { let docPosType = this.GetDocPosType(); @@ -13948,10 +13966,16 @@ CDocument.prototype._checkPermRangeForCurrentSelection = function() { let hdrftr = this.HdrFtr.CurHdrFtr; if (!hdrftr) - return null; + return false; docContent = hdrftr.GetContent(); } + else if (docPosType === docpostype_DrawingObjects) + { + docContent = this.DrawingObjects.getTargetDocContent(); + if (!docContent) + docContent = this; + } // TODO: Пока запрещаем любые действия, связанные с выделением автофигур if (this.IsTextSelectionUse() && this.Selection.Use) @@ -13967,7 +13991,30 @@ CDocument.prototype._checkPermRangeForCurrentSelection = function() else if (!this.IsSelectionUse()) { let currentPos = docContent.GetContentPosition(); - return this.GetPermRangesByContentPos(currentPos, docContent).length > 0; + if (this.GetPermRangesByContentPos(currentPos, docContent).length <= 0) + return false; + + // TODO: Надо проверить, если мы находимся в начале параграфа, то проверяем можно ли менять прилегание и отступ первой строки + if (changesType === AscCommon.changestype_Remove) + { + let state = this.SaveDocumentState(false); + this.MoveCursorLeft(false, false); + let result = (this.GetPermRangesByContentPos(docContent.GetContentPosition(), docContent).length > 0); + this.LoadDocumentState(state); + this.UpdateInterface(); + return result; + } + else if (changesType === AscCommon.changestype_Delete) + { + let state = this.SaveDocumentState(false); + this.MoveCursorRight(false, false); + let result = (this.GetPermRangesByContentPos(docContent.GetContentPosition(), docContent).length > 0); + this.LoadDocumentState(state); + this.UpdateInterface(); + return result; + } + + return true; } return false; @@ -23423,7 +23470,7 @@ CDocument.prototype.IsEditSignaturesMode = function() }; CDocument.prototype.IsViewModeInEditor = function() { - return this.Api.isRestrictionView(); + return this.Api.isRestrictionView() && !this.Api.isRestrictionSignatures(); }; CDocument.prototype.CanEdit = function() { @@ -23438,6 +23485,12 @@ CDocument.prototype.private_CheckCursorPosInFillingFormMode = function() this.UpdateSelection(); this.UpdateInterface(); } + else if (this.IsEditCommentsMode() || this.IsViewModeInEditor()) + { + this.CorrectCursorToPermRanges(); + this.UpdateSelection(); + this.UpdateInterface(); + } }; CDocument.prototype.OnEndLoadScript = function() { @@ -24336,13 +24389,57 @@ CDocument.prototype.GetPermRangesByContentPos = function(docPos, docContent) docContent.SetContentPosition(docPos, 0, 0); let result = []; - let currentParagraph = this.GetCurrentParagraph(true, null); + let currentParagraph = docContent.GetCurrentParagraph(true, null); if (currentParagraph) result = currentParagraph.GetCurrentPermRanges(); this.LoadDocumentState(state, false); return result; }; +CDocument.prototype.CorrectCursorToPermRanges = function() +{ + if (this.IsSelectionUse()) + { + if (!this.IsTextSelectionUse()) + return; + + let firstPara = this.GetFirstParagraphInSelection(); + let lastPara = this.GetLastParagraphInSelection(); + if (!firstPara || !lastPara) + return; + + if (this.GetSelectDirection() >= 0) + { + let startPos = firstPara.Get_ParaContentPos(true, true, false); + startPos = firstPara.CorrectPosToPermRanges(startPos); + firstPara.SetSelectionStartContentPos(startPos); + + let endPos = lastPara.Get_ParaContentPos(true, false, false); + endPos = lastPara.CorrectPosToPermRanges(endPos); + lastPara.SetSelectionEndContentPos(endPos); + } + else + { + let endPos = firstPara.Get_ParaContentPos(true, false, false); + endPos = firstPara.CorrectPosToPermRanges(endPos); + firstPara.SetSelectionEndContentPos(endPos); + + let startPos = lastPara.Get_ParaContentPos(true, true, false); + startPos = lastPara.CorrectPosToPermRanges(startPos); + lastPara.SetSelectionStartContentPos(startPos); + } + } + else + { + let paragraph = this.GetCurrentParagraph(); + if (!paragraph) + return; + + let paraPos = paragraph.Get_ParaContentPos(false, false, false); + paraPos = paragraph.CorrectPosToPermRanges(paraPos); + paragraph.Set_ParaContentPos(paraPos, false, -1, -1, false); + } +}; /** * Получаем ссылку на класс, управляющий закладками * @returns {CBookmarksManager} @@ -25401,6 +25498,16 @@ CDocument.prototype.AddBlankPage = function() this.CurPos.ContentPos = this.CurPos.ContentPos + 2; } + else if (0 === this.CurPos.ContentPos && oElement.IsCursorAtBegin()) + { + let breakParagraph = oElement.Split(); + this.AddToContent(1, breakParagraph); + let splitParagraph = breakParagraph.Split(); + this.AddToContent(2, splitParagraph); + breakParagraph.AddToParagraph(new AscWord.CRunBreak(AscWord.break_Page)); + + this.CurPos.ContentPos = 0; + } else { var oNext = oElement.Split(); diff --git a/word/Editor/History.js b/word/Editor/History.js index 13d110ef86..7a5e20f1d6 100644 --- a/word/Editor/History.js +++ b/word/Editor/History.js @@ -1799,7 +1799,7 @@ CHistory.prototype.private_PostProcessingRecalcData = function() }; CHistory.prototype.startGroupPoints = function() { - this.Create_NewPoint(AscDFH.historydescription_LongAction); + this.Create_NewPoint(AscDFH.historydescription_GroupPointsOpen); }; CHistory.prototype.cancelGroupPoints = function() { @@ -1812,7 +1812,7 @@ CHistory.prototype.private_PostProcessingRecalcData = function() this.UndoRedoInProgress = true; let point; - for (let i = this.Points.length - 1; i >= startIndex; --i) + for (let i = this.Index; i >= startIndex; --i) { point = this.Points[i]; this.private_UndoPoint(point, changes); @@ -1824,6 +1824,9 @@ CHistory.prototype.private_PostProcessingRecalcData = function() if (!window['AscCommon'].g_specialPasteHelper.specialPasteStart) window['AscCommon'].g_specialPasteHelper.SpecialPasteButton_Hide(true); + this.Index = startIndex - 1; + this.ClearRedo() + this.UndoRedoInProgress = false; return changes; }; @@ -1836,6 +1839,8 @@ CHistory.prototype.private_PostProcessingRecalcData = function() return; let point = this.Points[startIndex]; + point.Description = AscDFH.historydescription_GroupPoints; + for (let i = startIndex + 1; i < this.Points.length; ++i) { point.Items = point.Items.concat(this.Points[i].Items); @@ -1884,7 +1889,7 @@ CHistory.prototype.private_PostProcessingRecalcData = function() { for (let i = this.Index; i >= 0; --i) { - if (AscDFH.historydescription_LongAction === this.Points[i].Description) + if (AscDFH.historydescription_GroupPointsOpen === this.Points[i].Description) return i; } diff --git a/word/Editor/Paragraph.js b/word/Editor/Paragraph.js index 17ccf4a4a0..1ddddaf44d 100644 --- a/word/Editor/Paragraph.js +++ b/word/Editor/Paragraph.js @@ -3140,13 +3140,16 @@ Paragraph.prototype.drawRunContentLines = function(CurPage, pGraphics, drawState for (var CurLine = StartLine; CurLine <= EndLine; CurLine++) { - var Line = this.Lines[CurLine]; - var LineM = Line.Metrics; + var Line = this.Lines[CurLine]; + var lineMetrics = Line.Metrics; + + let lineY0 = (Page.Y + Line.Y - lineMetrics.TextAscent); + let lineY1 = (Page.Y + Line.Y + lineMetrics.TextDescent); var Baseline = Page.Y + Line.Y; - var UnderlineOffset = LineM.TextDescent * 0.4; + var UnderlineOffset = lineMetrics.TextDescent * 0.4; - PDSL.resetLine(CurLine, Baseline, UnderlineOffset); + PDSL.resetLine(CurLine, Baseline, UnderlineOffset, lineY0, lineY1); // Сначала проанализируем данную строку: в массивы aStrikeout, aDStrikeout, aUnderline // aSpelling сохраним позиции начала и конца продолжительных одинаковых настроек зачеркивания, @@ -3949,6 +3952,14 @@ Paragraph.prototype.Remove = function(nCount, isRemoveWholeElement, bRemoveOnlyS this.Selection.Use = false; this.Internal_Content_Remove(StartPos); + + // Fix the content after deletion + if (!bOnAddText + && !this.Content[StartPos].IsCursorPlaceable() + && (0 === StartPos || !this.Content[StartPos - 1].IsCursorPlaceable())) + { + this.AddToContent(StartPos, new AscWord.Run()); + } this.CurPos.ContentPos = StartPos; this.Content[StartPos].MoveCursorToStartPos(); @@ -4110,6 +4121,14 @@ Paragraph.prototype.Remove = function(nCount, isRemoveWholeElement, bRemoveOnlyS if (isStartDeleted && isEndDeleted) this.Selection.Use = false; + // Fix the content after deletion + if (!bOnAddText + && !this.Content[StartPos].IsCursorPlaceable() + && (0 === StartPos || !this.Content[StartPos - 1].IsCursorPlaceable())) + { + this.AddToContent(StartPos, new AscWord.Run()); + } + if (nCount > -1 && true !== bOnAddText) { this.Correct_ContentPos2(); @@ -4138,10 +4157,6 @@ Paragraph.prototype.Remove = function(nCount, isRemoveWholeElement, bRemoveOnlyS if (true !== this.Content[this.CurPos.ContentPos].IsSelectionUse()) { this.RemoveSelection(); - - // TODO: Переделать корректировку содержимого - // if (nCount > -1 && true !== bOnAddText) - // this.Correct_Content(); } else { @@ -4150,10 +4165,6 @@ Paragraph.prototype.Remove = function(nCount, isRemoveWholeElement, bRemoveOnlyS this.Selection.Flag = selectionflag_Common; this.Selection.StartPos = this.CurPos.ContentPos; this.Selection.EndPos = this.CurPos.ContentPos; - - // TODO: Переделать корректировку содержимого - // if (nCount > -1 && true !== bOnAddText) - // this.Correct_Content(); this.Document_SetThisElementCurrent(false); @@ -5723,6 +5734,24 @@ Paragraph.prototype.SetSelectionContentPos = function(oStartPos, oEndPos, isCorr { return this.Set_SelectionContentPos(oStartPos, oEndPos, isCorrectAnchor); }; +/** + * Устанавливаем стартовую позицию селекта внутри данного параграфа + * NB: Данная функция не стартует селект в параграфе, а лишь выставляет его стартовую границу + * @param startPos {AscWord.CParagraphContentPos} + */ +Paragraph.prototype.SetSelectionStartContentPos = function(startPos) +{ + return this.SetSelectionContentPos(startPos, this.Get_ParaContentPos(true, false, false), false); +}; +/** + * Устанавливаем конечную позицию селекта внутри данного параграфа + * NB: Данная функция не стартует селект в параграфе, а лишь выставляет его конечную границу + * @param endPos {AscWord.CParagraphContentPos} + */ +Paragraph.prototype.SetSelectionEndContentPos = function(endPos) +{ + return this.Set_SelectionContentPos(this.Get_ParaContentPos(true, true, false), endPos, true); +}; Paragraph.prototype.private_GetClosestPosInCombiningMark = function(oContentPos, nDiff) { if (undefined === nDiff) @@ -16878,6 +16907,47 @@ Paragraph.prototype.GetPermRangesByPos = function(paraPos) this.LoadSelectionState(state); return permRanges; }; +/** + * Корректируем заданную позицию, чтобы она попала в каку-либо разрешенную область, но приэтом так, чтобы физически + * позиция не изменилась. + * @param {AscWord.CParagraphContentPos} paraPos + */ +Paragraph.prototype.CorrectPosToPermRanges = function(paraPos) +{ + if (this.GetPermRangesByPos(paraPos).length) + return paraPos; + + let state = new AscWord.ParagraphPosToPermRangeState(); + state.setDirection(true); + let curPos = paraPos.Get(0); + for (let pos = curPos; pos < this.Content.length; ++pos) + { + state.setPos(pos, 0); + + if (this.Content[pos].CorrectPosToPermRanges(state, paraPos, 1, pos === curPos)) + break; + + if (state.isStopped()) + break; + } + + if (!state.isFound()) + { + state.setDirection(false); + for (let pos = curPos; pos >= 0; --pos) + { + state.setPos(pos, 0); + + if (this.Content[pos].CorrectPosToPermRanges(state, paraPos, 1, pos === curPos)) + break; + + if (state.isStopped()) + break; + } + } + + return state.isFound() ? state.getCorrectedPos() : paraPos; +}; Paragraph.prototype.IsCurrentPosInComplexFieldCode = function() { let cfStatePos = this.GetCurrentComplexFields(true); diff --git a/word/Editor/Paragraph/draw/line-draw-state.js b/word/Editor/Paragraph/draw/line-draw-state.js index ab488ea60c..9230393a75 100644 --- a/word/Editor/Paragraph/draw/line-draw-state.js +++ b/word/Editor/Paragraph/draw/line-draw-state.js @@ -54,7 +54,8 @@ this.VisitedHyperlink = false; this.Hyperlink = false; - this.ulTrailSpace = false; + this.ulTrailSpace = false; + this.activePermRanges = false; this.Strikeout = new CParaDrawingRangeHorizontalLines(); this.DStrikeout = new CParaDrawingRangeHorizontalLines(); @@ -73,6 +74,8 @@ this.BaseLine = 0; this.UnderlineOffset = 0; this.Spaces = 0; + this.LineY0 = 0; + this.LineY1 = 0; this.complexFields = new AscWord.ParagraphComplexFieldStack(); this.contentControls = []; @@ -106,6 +109,8 @@ this.collPrChangeColor = null; + this.annotationMarks = []; + this.bidiFlow = new AscWord.BidiFlow(this); } ParagraphLineDrawState.prototype.init = function() @@ -115,7 +120,10 @@ this.logicDocument = this.GetLogicDocument(); if (this.logicDocument && this.logicDocument.IsDocumentEditor()) - this.ulTrailSpace = this.logicDocument.IsUnderlineTrailSpace(); + { + this.ulTrailSpace = this.logicDocument.IsUnderlineTrailSpace(); + this.activePermRanges = this.logicDocument.IsEditCommentsMode() || this.logicDocument.IsViewModeInEditor(); + } }; ParagraphLineDrawState.prototype.resetPage = function(page) { @@ -129,12 +137,14 @@ this.complexFields.resetPage(this.Paragraph, page); }; - ParagraphLineDrawState.prototype.resetLine = function(Line, Baseline, UnderlineOffset) + ParagraphLineDrawState.prototype.resetLine = function(Line, Baseline, UnderlineOffset, lineY0, lineY1) { this.Line = Line; this.Baseline = Baseline; this.UnderlineOffset = UnderlineOffset; + this.LineY0 = lineY0; + this.LineY1 = lineY1; this.Strikeout.Clear(); this.DStrikeout.Clear(); @@ -175,14 +185,17 @@ if (para_Drawing === element.Type && !element.IsInline()) return; - this.bidiFlow.add([element, run, inRunPos, misspell], element.getBidiType()); + this.bidiFlow.add([element, run, inRunPos, misspell, this.annotationMarks], element.getBidiType()); + + this.annotationMarks = []; }; - ParagraphLineDrawState.prototype.handleBidiFlow = function(data) + ParagraphLineDrawState.prototype.handleBidiFlow = function(data, direction) { let element = data[0]; let run = data[1]; let inRunPos = data[2]; let misspell = data[3]; + let marks = data[4]; this.handleRun(run); @@ -258,8 +271,21 @@ if (this.collPrChangeColor) this.CollChange.Add(0, 0, startX, endX, 0, this.collPrChangeColor.r, this.collPrChangeColor.g, this.collPrChangeColor.b, {RunPr : this.textPr}); + if (marks) + { + let markX = direction === AscBidi.DIRECTION.L ? startX : endX; + for (let i = 0; i < marks.length; ++i) + { + marks[i].drawMark(markX, this.LineY0, this.LineY1 - this.LineY0, this.Graphics, direction === AscBidi.DIRECTION.R, this); + } + } + this.X = endX; }; + ParagraphLineDrawState.prototype.handleAnnotationMark = function(mark) + { + this.annotationMarks.push(mark); + }; /** * Получаем количество орфографических ошибок в данном месте * @returns {number} @@ -288,6 +314,10 @@ { return this.Paragraph.GetLogicDocument(); }; + ParagraphLineDrawState.prototype.isActivePermRanges = function() + { + return this.activePermRanges; + }; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Private area //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/word/Editor/ParagraphContentBase.js b/word/Editor/ParagraphContentBase.js index ecc445ef71..050b7cffa2 100644 --- a/word/Editor/ParagraphContentBase.js +++ b/word/Editor/ParagraphContentBase.js @@ -78,6 +78,9 @@ CParagraphContentBase.prototype.PreDelete = function() CParagraphContentBase.prototype.GetCurrentPermRanges = function(permRanges, isCurrent) { }; +CParagraphContentBase.prototype.CorrectPosToPermRanges = function(state, paraPos, depth, isCurrent) +{ +}; /** * Выствялем параграф, в котром лежит данный элемент * @param {Paragraph} oParagraph @@ -4616,6 +4619,33 @@ CParagraphContentWithParagraphLikeContent.prototype.GetCurrentPermRanges = funct this.Content[pos].GetCurrentPermRanges(permRanges, isCurrent && pos === endPos); } }; +CParagraphContentWithParagraphLikeContent.prototype.CorrectPosToPermRanges = function(state, paraPos, depth, isCurrent) +{ + if (state.isForward()) + { + let startPos = isCurrent ? paraPos.Get(depth) : 0; + for (let pos = startPos; pos < this.Content.length; ++pos) + { + state.setPos(pos, depth); + this.Content[pos].CorrectPosToPermRanges(state, paraPos, depth + 1, isCurrent && pos === startPos); + + if (state.isStopped()) + break; + } + } + else + { + let startPos = isCurrent ? paraPos.Get(depth) : this.Content.length - 1; + for (let pos = startPos; pos >= 0; --pos) + { + state.setPos(pos, depth); + this.Content[pos].CorrectPosToPermRanges(state, paraPos, depth + 1, isCurrent && pos === startPos); + + if (state.isStopped()) + break; + } + } +}; CParagraphContentWithParagraphLikeContent.prototype.GetCurrentComplexFields = function(arrComplexFields, isCurrent, isFieldPos) { var nEndPos = isCurrent ? this.State.ContentPos : this.Content.length - 1; diff --git a/word/Editor/Run.js b/word/Editor/Run.js index 2f2fbd9757..b4b4d9629b 100644 --- a/word/Editor/Run.js +++ b/word/Editor/Run.js @@ -11533,6 +11533,37 @@ ParaRun.prototype.PreDelete = function(isDeep) this.RemoveSelection(); }; +ParaRun.prototype.CorrectPosToPermRanges = function(state, paraPos, depth, isCurrent) +{ + if (!isCurrent && state.inPermRange()) + { + state.setPos(state.isForward() ? 0 : this.Content.length, depth); + state.stop(true); + return; + } + + let start, end; + if (state.isForward()) + { + start = isCurrent ? paraPos.Get(depth) : 0; + end = this.Content.length; + } + else + { + start = 0; + end = isCurrent ? Math.min(this.Content.length, paraPos.Get(depth)) : this.Content.length; + } + + + for (let i = start; i < end; ++i) + { + if (!this.Content[i].IsDrawing() || this.Content[i].IsInline()) + { + state.stop(false); + return; + } + } +}; ParaRun.prototype.GetCurrentComplexFields = function(arrComplexFields, isCurrent, isFieldPos) { var nEndPos = isCurrent ? this.State.ContentPos : this.Content.length; diff --git a/word/Editor/Serialize2.js b/word/Editor/Serialize2.js index 1d6133cdb1..5be54c7297 100644 --- a/word/Editor/Serialize2.js +++ b/word/Editor/Serialize2.js @@ -4479,6 +4479,16 @@ Binary_tblPrWriter.prototype = WriteTbl: function(table) { var oThis = this; + + // Обязательно пишем стиль самым первым (при сохранении в docx из бинарника эти данные напрямую в xml + // сохраняются), а MSWord плохо воспринимает некоторые параметры, если стиль идет после них (76106) + let styleId = table.GetTableStyle(); + if (styleId) + { + this.memory.WriteByte(c_oSerProp_tblPrType.Style); + this.memory.WriteString2(styleId); + } + this.WriteTblPr(table.Pr, table); //Look var oLook = table.Get_TableLook(); @@ -4499,13 +4509,6 @@ Binary_tblPrWriter.prototype = nLook |= 0x0400; this.bs.WriteItem(c_oSerProp_tblPrType.Look, function(){oThis.memory.WriteLong(nLook);}); } - //Style - var sStyle = table.Get_TableStyle(); - if(null != sStyle && "" != sStyle) - { - this.memory.WriteByte(c_oSerProp_tblPrType.Style); - this.memory.WriteString2(sStyle); - } }, WriteTblPr: function(tblPr, table) { diff --git a/word/Editor/Styles.js b/word/Editor/Styles.js index 89657b5fe4..8bd1838951 100644 --- a/word/Editor/Styles.js +++ b/word/Editor/Styles.js @@ -9706,6 +9706,10 @@ AscWord.CDocumentColor = CDocumentColor; { return this.ReadFromBinary(reader); }; + CDocumentColorA.prototype.IsEqual = function(color) + { + return this.isEqual(color); + }; //------------------------------------------------------------------------------------------------------------------ AscWord.CDocumentColorA = CDocumentColorA; })(); diff --git a/word/Editor/annotations/paragraph-perm.js b/word/Editor/annotations/paragraph-perm.js index 7e02585ab4..d44148ee87 100644 --- a/word/Editor/annotations/paragraph-perm.js +++ b/word/Editor/annotations/paragraph-perm.js @@ -54,6 +54,14 @@ { return this.Id; }; + ParagraphPermBase.prototype.isStart = function() + { + return false; + }; + ParagraphPermBase.prototype.isEnd = function() + { + return false; + }; ParagraphPermBase.prototype.GetId = function() { return this.Id; @@ -79,6 +87,14 @@ { marks.push(this); }; + ParagraphPermBase.prototype.IsAnnotationMark = function() + { + return true; + }; + ParagraphPermBase.prototype.GetAllAnnotationMarks = function(marks) + { + marks.push(this); + }; ParagraphPermBase.prototype.IsCursorPlaceable = function() { return false; @@ -87,6 +103,19 @@ { return false; }; + ParagraphPermBase.prototype.CorrectPosToPermRanges = function(state, paraPos, depth, isCurrent) + { + state.checkPermRange(this); + }; + ParagraphPermBase.prototype.Draw_Lines = function(lineDrawState) + { + lineDrawState.handleAnnotationMark(this); + }; + ParagraphPermBase.prototype.drawMark = function(x, y, h, graphics, isRTL, lineDrawState) + { + if (graphics && graphics.drawPermissionMark) + graphics.drawPermissionMark(x, y, h, isRTL ? !this.isStart() : this.isStart(), lineDrawState.isActivePermRanges()); + }; /** * Очень важно, что в режимах комментирования и просмотра, мы проход через данный элемент считаем как перемещение курсора, * т.к. на этом завязано выделение текущего слова и применение настроек к текущему слову (оно должно применяться @@ -336,8 +365,70 @@ this.rangeId = reader.GetString2(); }; + /** + * @constructor + */ + function ParagraphPosToPermRangeState() + { + this.forward = true; + this.curPos = new AscWord.CParagraphContentPos(); + this.stopped = false; + this.found = false; + this.permRanges = []; + } + ParagraphPosToPermRangeState.prototype.isFound = function() + { + return this.found; + }; + ParagraphPosToPermRangeState.prototype.setDirection = function(isForward) + { + this.forward = isForward; + this.stopped = false; + this.found = false; + this.permRanges = []; + }; + ParagraphPosToPermRangeState.prototype.isForward = function() + { + return this.forward; + }; + ParagraphPosToPermRangeState.prototype.isStopped = function() + { + return this.stopped; + }; + ParagraphPosToPermRangeState.prototype.inPermRange = function() + { + return (!!this.permRanges.length); + }; + ParagraphPosToPermRangeState.prototype.stop = function(isFound) + { + this.stopped = true; + this.found = isFound; + }; + ParagraphPosToPermRangeState.prototype.checkPermRange = function(mark) + { + if ((mark.isEnd() && this.forward) || (mark.isStart() && !this.forward)) + { + let rangeId = mark.getRangeId(); + let pos = this.permRanges.indexOf(rangeId); + if (-1 !== pos) + this.permRanges.splice(pos, 1); + } + else + { + this.permRanges.push(mark.getRangeId()); + } + }; + ParagraphPosToPermRangeState.prototype.setPos = function(pos, depth) + { + this.curPos.Update(pos, depth); + }; + ParagraphPosToPermRangeState.prototype.getCorrectedPos = function() + { + return this.curPos; + }; //--------------------------------------------------------export---------------------------------------------------- - AscWord.ParagraphPermStart = ParagraphPermStart; - AscWord.ParagraphPermEnd = ParagraphPermEnd; + AscWord.ParagraphPermStart = ParagraphPermStart; + AscWord.ParagraphPermEnd = ParagraphPermEnd; + AscWord.ParagraphPosToPermRangeState = ParagraphPosToPermRangeState; })(); diff --git a/word/apiBuilder.js b/word/apiBuilder.js index 638e0c06ce..ed6afc206f 100644 --- a/word/apiBuilder.js +++ b/word/apiBuilder.js @@ -4364,6 +4364,32 @@ { return new ApiDocument(this.WordControl.m_oLogicDocument); }; + /** + * Returns the object by it's internal ID. + * @memberof Api + * @typeofeditors ["CDE"] + * @param id {string} ID of the object. + * @returns {?object} + * @since 9.0.4 + * @see office-js-api/Examples/{Editor}/Api/Methods/GetByInternalId.js + */ + Api.prototype.GetByInternalId = function(id) + { + let obj = AscCommon.g_oTableId.Get_ById(id); + if (!obj) + return null; + + if (obj instanceof AscWord.CDocument) + return new ApiDocument(obj); + else if (obj instanceof AscWord.CDocumentContent) + return new ApiDocumentContent(obj); + else if (obj instanceof AscWord.CInlineLevelSdt) + return new ApiInlineLvlSdt(obj); + else if (obj instanceof AscWord.CBlockLevelSdt) + return new ApiBlockLvlSdt(obj); + + return null; + }; /** * Creates a new paragraph. * @memberof Api @@ -5578,6 +5604,18 @@ { return "documentContent"; }; + /** + * Returns an internal ID of the current document content. + * @memberof ApiDocumentContent + * @typeofeditors ["CDE", "CSE", "CPE"] + * @returns {string} + * @since 9.0.4 + * @see office-js-api/Examples/{Editor}/ApiDocumentContent/Methods/GetInternalId.js + */ + ApiDocumentContent.prototype.GetInternalId = function() + { + return this.Sdt.GetId(); + }; /** * Returns a number of elements in the current document. * @memberof ApiDocumentContent @@ -7425,6 +7463,47 @@ this.Document.SetGlobalTrackRevisions(isTrack); return true; }; + + var trackRevisionBuffer = { + name : "", + userId : "", + isTrack : false + }; + /** + * Special method for AI track revisions. + * @memberof ApiDocument + * @typeofeditors ["CDE"] + * @param isTrack {boolean} - Specifies if the change tracking mode is set or not. + * @param assistantName {string} - Specifies if the change tracking mode is set or not. + * @returns {boolean} + * @see office-js-api/Examples/{Editor}/ApiDocument/Methods/SetAssistantTrackRevisions.js + */ + ApiDocument.prototype.SetAssistantTrackRevisions = function(isTrack, assistantName) + { + if (isTrack) + { + trackRevisionBuffer.isTrack = this.Document.IsTrackRevisions(); + this.Document.SetGlobalTrackRevisions(true); + + let userInfo = Asc.editor.DocInfo.get_UserInfo(); + trackRevisionBuffer.userId = userInfo.get_Id(); + trackRevisionBuffer.userName = userInfo.get_FullName(); + + let userId = "uid-" + assistantName; + userInfo.put_Id(userId); + userInfo.put_FullName(assistantName); + + AscCommon.setUserColorById(userId, {r : 8, g: 145, b: 178}, {r : 8, g: 145, b: 178}); + } + else + { + this.Document.SetGlobalTrackRevisions(trackRevisionBuffer.isTrack); + let userInfo = Asc.editor.DocInfo.get_UserInfo(); + userInfo.put_Id(trackRevisionBuffer.userId); + userInfo.put_FullName(trackRevisionBuffer.userName); + } + return true; + }; /** * Checks if change tracking mode is enabled or not. * @memberof ApiDocument @@ -8088,6 +8167,34 @@ return comment ? new ApiComment(comment) : null; }; + + /** + * Show a comment by its ID. + * @memberof ApiDocument + * @typeofeditors ["CDE"] + * @param {string | Array.string} commentId - The comment ID. + * @returns {boolean} + * @since 9.0.4 + * @see office-js-api/Examples/{Editor}/ApiDocument/Methods/ShowComment.js + */ + ApiDocument.prototype.ShowComment = function(commentId) + { + let durableIds = Array.isArray(commentId) ? commentId : [commentId]; + let internalIds = []; + + let comments = this.Document.GetCommentsManager(); + for (let i = 0; i < durableIds.length; ++i) + { + let comment = comments.GetByDurableId(durableIds[i]); + if (comment) + internalIds.push(comment.GetId()); + } + + // Force recalculation to display the comment in the correct place + this.ForceRecalculate(); + this.Document.ShowComment(internalIds); + return true; + }; /** * Returns all numbered paragraphs from the current document. @@ -9155,7 +9262,47 @@ ApiDocument.prototype.GetCustomProperties = function () { return new ApiCustomProperties(this.Document.CustomProperties); }; - + + /** + * Insert blank page to the current location. + * @memberof ApiDocument + * @returns {boolean} + * @typeofeditors ["CDE"] + * @since 9.0.4 + * @see office-js-api/Examples/{Editor}/ApiDocument/Methods/InsertBlankPage.js + */ + ApiDocument.prototype.InsertBlankPage = function() + { + this.Document.AddBlankPage(); + return true; + }; + /** + * Moves cursor to the start of the document. + * @memberof ApiDocument + * @returns {boolean} + * @typeofeditors ["CDE"] + * @since 9.0.4 + * @see office-js-api/Examples/{Editor}/ApiDocument/Methods/MoveCursorToStart.js + */ + ApiDocument.prototype.MoveCursorToStart = function() + { + this.Document.MoveCursorToStartOfDocument(); + return true; + }; + /** + * Moves cursor to the end of the document. + * @memberof ApiDocument + * @returns {boolean} + * @typeofeditors ["CDE"] + * @since 9.0.4 + * @see office-js-api/Examples/{Editor}/ApiDocument/Methods/MoveCursorToEnd.js + */ + ApiDocument.prototype.MoveCursorToEnd = function() + { + this.Document.MoveCursorToStartOfDocument(); + this.Document.MoveCursorToEndPos(); + return true; + }; //------------------------------------------------------------------------------------------------------------------ // // ApiParagraph @@ -10365,50 +10512,17 @@ /** * Selects the current paragraph. * @memberof ApiParagraph - * @typeofeditors ["CDE"] + * @typeofeditors ["CDE", "CPE"] * @return {boolean} * @see office-js-api/Examples/{Editor}/ApiParagraph/Methods/Select.js */ ApiParagraph.prototype.Select = function() { - var Document = private_GetLogicDocument(); - - var StartRun = this.Paragraph.GetFirstRun(); - var StartPos = StartRun.GetDocumentPositionFromObject(); - var EndRun = this.Paragraph.Content[this.Paragraph.Content.length - 1]; - var EndPos = EndRun.GetDocumentPositionFromObject(); - - StartPos.push({Class: StartRun, Position: 0}); - EndPos.push({Class: EndRun, Position: 1}); - - if (StartPos[0].Position === - 1) - return false; - - StartPos[0].Class.SetSelectionByContentPositions(StartPos, EndPos); - - var controllerType; - - if (StartPos[0].Class.IsHdrFtr()) - { - controllerType = docpostype_HdrFtr; - } - else if (StartPos[0].Class.IsFootnote()) - { - controllerType = docpostype_Footnotes; - } - else if (StartPos[0].Class.Is_DrawingShape()) - { - controllerType = docpostype_DrawingObjects; - } - else - { - controllerType = docpostype_Content; - } - - Document.SetDocPosType(controllerType); - Document.UpdateSelection(); - - return true; + let logicDocument = private_GetLogicDocument(); + logicDocument.RemoveSelection(); + this.Paragraph.SelectAll(); + this.Paragraph.Document_SetThisElementCurrent(); + return true; }; /** * Searches for a scope of a paragraph object. The search results are a collection of ApiRange objects. @@ -12839,36 +12953,11 @@ */ ApiTable.prototype.Select = function() { - var Document = private_GetLogicDocument(); - - var aDocPos = this.Table.GetDocumentPositionFromObject(); - - if (aDocPos[0].Position === - 1) - return false; - - var controllerType; - - if (aDocPos[0].Class.IsHdrFtr()) - { - controllerType = docpostype_HdrFtr; - } - else if (aDocPos[0].Class.IsFootnote()) - { - controllerType = docpostype_Footnotes; - } - else if (aDocPos[0].Class.Is_DrawingShape()) - { - controllerType = docpostype_DrawingObjects; - } - else - { - controllerType = docpostype_Content; - } - aDocPos[0].Class.CurPos.ContentPos = aDocPos[0].Position; - Document.SetDocPosType(controllerType); - Document.SelectTable(3); - - return true; + let logicDocument = private_GetLogicDocument(); + logicDocument.RemoveSelection(); + this.Table.SelectAll(); + this.Table.Document_SetThisElementCurrent(); + return true; }; /** * Returns a Range object that represents the part of the document contained in the specified table. @@ -22045,19 +22134,6 @@ */ ApiFormBase.prototype.GetClassType = function() { - if (this instanceof ApiTextForm) - return "textForm"; - else if (this instanceof ApiComboBoxForm) - return "comboBoxForm"; - else if (this instanceof ApiDateForm) - return "dateForm"; - else if (this instanceof ApiCheckBoxForm) - return "checkBoxForm"; - else if (this instanceof ApiPictureForm) - return "pictureForm"; - else if (this instanceof ApiComplexForm) - return "complexForm"; - return "form"; }; /** @@ -22544,6 +22620,18 @@ // //------------------------------------------------------------------------------------------------------------------ + /** + * Returns a type of the ApiTextForm class. + * @memberof ApiTextForm + * @typeofeditors ["CDE", "CFE"] + * @since 9.0.4 + * @returns {"textForm"} + * @see office-js-api/Examples/{Editor}/ApiTextForm/Methods/GetClassType.js + */ + ApiTextForm.prototype.GetClassType = function() + { + return "textForm"; + }; /** * Checks if the text field content is autofit, i.e. whether the font size adjusts to the size of the fixed size form. * @memberof ApiTextForm @@ -22758,7 +22846,19 @@ // ApiPictureForm // //------------------------------------------------------------------------------------------------------------------ - + + /** + * Returns a type of the ApiPictureForm class. + * @memberof ApiPictureForm + * @typeofeditors ["CDE", "CFE"] + * @returns {"pictureForm"} + * @since 9.0.4 + * @see office-js-api/Examples/{Editor}/ApiPictureForm/Methods/GetClassType.js + */ + ApiPictureForm.prototype.GetClassType = function() + { + return "pictureForm"; + }; /** * Returns the current scaling condition of the picture form. * @memberof ApiPictureForm @@ -23022,7 +23122,19 @@ // ApiComboBoxForm // //------------------------------------------------------------------------------------------------------------------ - + + /** + * Returns a type of the ApiComboBoxForm class. + * @memberof ApiComboBoxForm + * @typeofeditors ["CDE", "CFE"] + * @returns {"comboBoxForm"} + * @since 9.0.4 + * @see office-js-api/Examples/{Editor}/ApiComboBoxForm/Methods/GetClassType.js + */ + ApiComboBoxForm.prototype.GetClassType = function() + { + return "comboBoxForm"; + }; /** * Returns the list values from the current combo box. * @memberof ApiComboBoxForm @@ -23150,7 +23262,19 @@ // ApiCheckBoxForm // //------------------------------------------------------------------------------------------------------------------ - + + /** + * Returns a type of the ApiCheckBoxForm class. + * @memberof ApiCheckBoxForm + * @typeofeditors ["CDE", "CFE"] + * @returns {"checkBoxForm"} + * @since 9.0.4 + * @see office-js-api/Examples/{Editor}/ApiCheckBoxForm/Methods/GetClassType.js + */ + ApiCheckBoxForm.prototype.GetClassType = function() + { + return "checkBoxForm"; + }; /** * Checks the current checkbox. * @memberof ApiCheckBoxForm @@ -23268,6 +23392,18 @@ // //------------------------------------------------------------------------------------------------------------------ + /** + * Returns a type of the ApiDateForm class. + * @memberof ApiDateForm + * @typeofeditors ["CDE", "CFE"] + * @returns {"dateForm"} + * @since 9.0.4 + * @see office-js-api/Examples/{Editor}/ApiDateForm/Methods/GetClassType.js + */ + ApiDateForm.prototype.GetClassType = function() + { + return "dateForm"; + }; /** * Gets the date format of the current form. * @memberof ApiDateForm @@ -23445,7 +23581,19 @@ // ApiComplexForm // //------------------------------------------------------------------------------------------------------------------ - + + /** + * Returns a type of the ApiComplexForm class. + * @memberof ApiComplexForm + * @typeofeditors ["CDE", "CFE"] + * @returns {"form"} + * @since 9.0.4 + * @see office-js-api/Examples/{Editor}/ApiComplexForm/Methods/GetClassType.js + */ + ApiComplexForm.prototype.GetClassType = function() + { + return "complexForm"; + }; /** * Appends the text content of the given form to the end of the current complex form. * @memberof ApiComplexForm @@ -23779,8 +23927,6 @@ let oRunInfo = Object.assign({}, allRunsInfo[nInfo]); let oDeleteReviewRun = null; - let oInsertReviewRun = null; - if (oChange.pos >= oRunInfo.GlobStartPos || oChange.pos + DelCount > oRunInfo.GlobStartPos) { let nPosToDel = Math.max(0, oChange.pos - oRunInfo.GlobStartPos + oRunInfo.StartPos); @@ -23852,8 +23998,8 @@ let oRunToAdd = oRunInfo.Run.Content.length === 0 && oRunInfoToAdd ? oRunInfoToAdd.Run : oRunInfo.Run; nPosToAdd = oRunInfo.Run.Content.length === 0 && oRunInfoToAdd ? oRunInfoToAdd.Pos : nPosToAdd; - // creting review add run - if (oDeleteReviewRun) { + if (oDeleteReviewRun) + { let oPara = oDeleteReviewRun.Paragraph; oRunToAdd = new ParaRun(oPara, false); oRunToAdd.Set_Pr(oDeleteReviewRun.Pr.Copy(true)); @@ -23861,6 +24007,17 @@ oPara.AddToContent(oPara.Content.indexOf(oDeleteReviewRun) + 1, oRunToAdd); nPosToAdd = 0; } + else if (isTrackRevisions && reviewtype_Add !== oRunToAdd.GetReviewType()) + { + let runParent = oRunToAdd.GetParent(); + let posInParent = oRunToAdd.GetPosInParent(); + if (0 !== nPosToAdd) + oRunToAdd = oRunToAdd.Split2(nPosToAdd, runParent, posInParent++); + + oRunToAdd.Split2(0, runParent, posInParent); + oRunToAdd.SetReviewType(reviewtype_Add); + nPosToAdd = 0; + } for (let nChar = 0; nChar < oChange.insert.length; nChar++) { @@ -25543,6 +25700,7 @@ // Export //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Api.prototype["GetDocument"] = Api.prototype.GetDocument; + Api.prototype["GetByInternalId"] = Api.prototype.GetByInternalId; Api.prototype["CreateParagraph"] = Api.prototype.CreateParagraph; Api.prototype["CreateTable"] = Api.prototype.CreateTable; Api.prototype["AddComment"] = Api.prototype.AddComment; @@ -25695,6 +25853,7 @@ ApiDocument.prototype["SetFormsData"] = ApiDocument.prototype.SetFormsData; ApiDocument.prototype["SetTrackRevisions"] = ApiDocument.prototype.SetTrackRevisions; ApiDocument.prototype["IsTrackRevisions"] = ApiDocument.prototype.IsTrackRevisions; + ApiDocument.prototype["SetAssistantTrackRevisions"] = ApiDocument.prototype.SetAssistantTrackRevisions; ApiDocument.prototype["GetRange"] = ApiDocument.prototype.GetRange; ApiDocument.prototype["GetRangeBySelect"] = ApiDocument.prototype.GetRangeBySelect; ApiDocument.prototype["Last"] = ApiDocument.prototype.Last; @@ -25720,6 +25879,7 @@ ApiDocument.prototype["SetControlsHighlight"] = ApiDocument.prototype.SetControlsHighlight; ApiDocument.prototype["GetAllComments"] = ApiDocument.prototype.GetAllComments; ApiDocument.prototype["GetCommentById"] = ApiDocument.prototype.GetCommentById; + ApiDocument.prototype["ShowComment"] = ApiDocument.prototype.ShowComment; ApiDocument.prototype["GetStatistics"] = ApiDocument.prototype.GetStatistics; ApiDocument.prototype["GetPageCount"] = ApiDocument.prototype.GetPageCount; ApiDocument.prototype["GetCurrentPage"] = ApiDocument.prototype.GetCurrentPage; @@ -25755,9 +25915,13 @@ ApiDocument.prototype["AddDropDownListContentControl"] = ApiDocument.prototype.AddDropDownListContentControl; ApiDocument.prototype["AddPictureContentControl"] = ApiDocument.prototype.AddPictureContentControl; ApiDocument.prototype["GetCustomXmlParts"] = ApiDocument.prototype.GetCustomXmlParts; - ApiDocument.prototype["GetCore"] = ApiDocument.prototype.GetCore; - ApiDocument.prototype["GetCustomProperties"] = ApiDocument.prototype.GetCustomProperties; - + ApiDocument.prototype["GetCore"] = ApiDocument.prototype.GetCore; + ApiDocument.prototype["GetCustomProperties"] = ApiDocument.prototype.GetCustomProperties; + ApiDocument.prototype["InsertBlankPage"] = ApiDocument.prototype.InsertBlankPage; + ApiDocument.prototype["MoveCursorToStart"] = ApiDocument.prototype.MoveCursorToStart; + ApiDocument.prototype["MoveCursorToEnd"] = ApiDocument.prototype.MoveCursorToEnd; + + ApiParagraph.prototype["GetClassType"] = ApiParagraph.prototype.GetClassType; ApiParagraph.prototype["AddText"] = ApiParagraph.prototype.AddText; ApiParagraph.prototype["AddPageBreak"] = ApiParagraph.prototype.AddPageBreak; @@ -26465,7 +26629,8 @@ ApiFormBase.prototype["SetTag"] = ApiFormBase.prototype.SetTag; ApiFormBase.prototype["GetRole"] = ApiFormBase.prototype.GetRole; ApiFormBase.prototype["SetRole"] = ApiFormBase.prototype.SetRole; - + + ApiTextForm.prototype["GetClassType"] = ApiTextForm.prototype.GetClassType; ApiTextForm.prototype["IsAutoFit"] = ApiTextForm.prototype.IsAutoFit; ApiTextForm.prototype["SetAutoFit"] = ApiTextForm.prototype.SetAutoFit; ApiTextForm.prototype["IsMultiline"] = ApiTextForm.prototype.IsMultiline; @@ -26478,6 +26643,7 @@ ApiTextForm.prototype["SetText"] = ApiTextForm.prototype.SetText; ApiTextForm.prototype["Copy"] = ApiTextForm.prototype.Copy; + ApiPictureForm.prototype["GetClassType"] = ApiPictureForm.prototype.GetClassType; ApiPictureForm.prototype["GetScaleFlag"] = ApiPictureForm.prototype.GetScaleFlag; ApiPictureForm.prototype["SetScaleFlag"] = ApiPictureForm.prototype.SetScaleFlag; ApiPictureForm.prototype["SetLockAspectRatio"] = ApiPictureForm.prototype.SetLockAspectRatio; @@ -26490,28 +26656,32 @@ ApiPictureForm.prototype["SetImage"] = ApiPictureForm.prototype.SetImage; ApiPictureForm.prototype["Copy"] = ApiPictureForm.prototype.Copy; - ApiDateForm.prototype["GetFormat"] = ApiDateForm.prototype.GetFormat; - ApiDateForm.prototype["SetFormat"] = ApiDateForm.prototype.SetFormat; - ApiDateForm.prototype["GetLanguage"] = ApiDateForm.prototype.GetLanguage; - ApiDateForm.prototype["SetLanguage"] = ApiDateForm.prototype.SetLanguage; - ApiDateForm.prototype["GetTime"] = ApiDateForm.prototype.GetTime; - ApiDateForm.prototype["SetTime"] = ApiDateForm.prototype.SetTime; - ApiDateForm.prototype["SetDate"] = ApiDateForm.prototype.SetDate; - ApiDateForm.prototype["GetDate"] = ApiDateForm.prototype.GetDate; - ApiDateForm.prototype["Copy"] = ApiDateForm.prototype.Copy; + ApiDateForm.prototype["GetClassType"] = ApiDateForm.prototype.GetClassType; + ApiDateForm.prototype["GetFormat"] = ApiDateForm.prototype.GetFormat; + ApiDateForm.prototype["SetFormat"] = ApiDateForm.prototype.SetFormat; + ApiDateForm.prototype["GetLanguage"] = ApiDateForm.prototype.GetLanguage; + ApiDateForm.prototype["SetLanguage"] = ApiDateForm.prototype.SetLanguage; + ApiDateForm.prototype["GetTime"] = ApiDateForm.prototype.GetTime; + ApiDateForm.prototype["SetTime"] = ApiDateForm.prototype.SetTime; + ApiDateForm.prototype["SetDate"] = ApiDateForm.prototype.SetDate; + ApiDateForm.prototype["GetDate"] = ApiDateForm.prototype.GetDate; + ApiDateForm.prototype["Copy"] = ApiDateForm.prototype.Copy; + ApiComplexForm.prototype["GetClassType"] = ApiComplexForm.prototype.GetClassType; ApiComplexForm.prototype["Add"] = ApiComplexForm.prototype.Add; ApiComplexForm.prototype["GetSubForms"] = ApiComplexForm.prototype.GetSubForms; ApiComplexForm.prototype["ClearContent"] = ApiComplexForm.prototype.ClearContent; ApiComplexForm.prototype["Copy"] = ApiComplexForm.prototype.Copy; - - ApiComboBoxForm.prototype["GetListValues"] = ApiComboBoxForm.prototype.GetListValues; - ApiComboBoxForm.prototype["SetListValues"] = ApiComboBoxForm.prototype.SetListValues; - ApiComboBoxForm.prototype["SelectListValue"] = ApiComboBoxForm.prototype.SelectListValue; - ApiComboBoxForm.prototype["SetText"] = ApiComboBoxForm.prototype.SetText; - ApiComboBoxForm.prototype["IsEditable"] = ApiComboBoxForm.prototype.IsEditable; - ApiComboBoxForm.prototype["Copy"] = ApiComboBoxForm.prototype.Copy; - + + ApiComboBoxForm.prototype["GetClassType"] = ApiComboBoxForm.prototype.GetClassType; + ApiComboBoxForm.prototype["GetListValues"] = ApiComboBoxForm.prototype.GetListValues; + ApiComboBoxForm.prototype["SetListValues"] = ApiComboBoxForm.prototype.SetListValues; + ApiComboBoxForm.prototype["SelectListValue"] = ApiComboBoxForm.prototype.SelectListValue; + ApiComboBoxForm.prototype["SetText"] = ApiComboBoxForm.prototype.SetText; + ApiComboBoxForm.prototype["IsEditable"] = ApiComboBoxForm.prototype.IsEditable; + ApiComboBoxForm.prototype["Copy"] = ApiComboBoxForm.prototype.Copy; + + ApiCheckBoxForm.prototype["GetClassType"] = ApiCheckBoxForm.prototype.GetClassType; ApiCheckBoxForm.prototype["SetChecked"] = ApiCheckBoxForm.prototype.SetChecked; ApiCheckBoxForm.prototype["IsChecked"] = ApiCheckBoxForm.prototype.IsChecked; ApiCheckBoxForm.prototype["IsRadioButton"] = ApiCheckBoxForm.prototype.IsRadioButton;