Files
DocumentServer-v-9.2.0/sdkjs/word/Editor/Paragraph/draw/highlight-draw-state.js
Yajbir Singh f1b860b25c
Some checks failed
check / markdownlint (push) Has been cancelled
check / spellchecker (push) Has been cancelled
updated
2025-12-11 19:03:17 +05:30

618 lines
18 KiB
JavaScript

/*
* (c) Copyright Ascensio System SIA 2010-2024
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
* street, Riga, Latvia, EU, LV-1050.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
"use strict";
(function(window)
{
const FLAG_HIGHLIGHT = 0x0001;
const FLAG_SEARCH = 0x0004;
const FLAG_COMMENT = 0x0008;
const FLAG_COMPLEX_FIELD = 0x0010;
const FLAG_COLLABORATION = 0x0020;
const FLAG_SHD = 0x0040;
const FLAG_PERM_RANGE = 0x0080;
/**
* Class for storing the current draw state of paragraph highlight (text/paragraph/field/etc. background)
* @param {AscWord.ParagraphDrawState} drawState
* @constructor
*/
function ParagraphHighlightDrawState(drawState)
{
this.drawState = drawState;
this.Page = 0;
this.Line = 0;
this.Range = 0;
this.CurPos = new AscWord.CParagraphContentPos();
this.DrawColl = false;
this.DrawMMFields = false;
this.High = new CParaDrawingRangeLines();
this.Coll = new CParaDrawingRangeLines();
this.Find = new CParaDrawingRangeLines();
this.Comm = new CParaDrawingRangeLines();
this.Shd = new CParaDrawingRangeLines();
this.MMFields = new CParaDrawingRangeLines();
this.CFields = new CParaDrawingRangeLines();
this.HyperCF = new CParaDrawingRangeLines();
this.Perm = new CParaDrawingRangeLines();
this.DrawComments = true;
this.DrawSolvedComments = true;
this.haveCurrentComment = false;
this.currentCommentId = null;
this.comments = []; // current list of comments
this.permRanges = {};
this.hyperlinks = [];
this.searchCounter = 0;
this.Paragraph = undefined;
this.Graphics = undefined;
this.X = 0;
this.Y0 = 0;
this.Y1 = 0;
this.spaces = 0;
this.InlineSdt = [];
this.CollectFixedForms = false;
this.complexFields = new AscWord.ParagraphComplexFieldStack();
this.bidiFlow = new AscWord.BidiFlow(this);
this.run = null;
this.highlight = highlight_None;
this.shdColor = null;
this.shd = null;
this.permColor = null;
}
ParagraphHighlightDrawState.prototype.init = function(paragraph, graphics)
{
this.Paragraph = paragraph;
this.Graphics = graphics;
let logicDocument = paragraph.GetLogicDocument();
let commentManager = logicDocument && logicDocument.IsDocumentEditor() ? logicDocument.GetCommentsManager() : null;
this.DrawColl = !graphics.isPdf();
this.DrawSearch = logicDocument && logicDocument.IsDocumentEditor() && logicDocument.SearchEngine.Selection;
this.DrawComments = commentManager && commentManager.isUse();
this.DrawSolvedComments = commentManager && commentManager.isUseSolved();
this.DrawMMFields = logicDocument && logicDocument.IsDocumentEditor() && logicDocument.isHighlightMailMergeFields();
this.currentCommentId = commentManager ? commentManager.getCurrentCommentId() : -1;
this.permColor = new AscWord.CDocumentColor(233, 233, 233, 255);
if (logicDocument && logicDocument.IsDocumentEditor())
{
let docApi = logicDocument.GetApi();
if (docApi.isRestrictionView() || docApi.isRestrictionComments())
this.permColor = new AscWord.CDocumentColor(255, 254, 213, 255);
}
};
ParagraphHighlightDrawState.prototype.resetPage = function(page)
{
this.Page = page;
this.CurPos = new AscWord.CParagraphContentPos();
this.searchCounter = 0;
this.comments = [];
this.haveCurrentComment = false;
this.permRanges = [];
let pageEndInfo = this.Paragraph.GetEndInfoByPage(page - 1);
if (pageEndInfo)
{
for (let index = 0, count = pageEndInfo.Comments.length; index < count; ++index)
{
this.addComment(pageEndInfo.Comments[index]);
}
for (let index = 0, count = pageEndInfo.PermRanges.length; index < count; ++index)
{
this.addPermRange(pageEndInfo.PermRanges[index]);
}
}
this.complexFields.resetPage(this.Paragraph, page);
};
ParagraphHighlightDrawState.prototype.resetLine = function(line, top, bottom)
{
this.Line = line;
this.Y0 = top;
this.Y1 = bottom;
};
ParagraphHighlightDrawState.prototype.beginRange = function(range, X, spaceCount)
{
this.High.Clear();
this.Coll.Clear();
this.Find.Clear();
this.Comm.Clear();
this.Shd.Clear();
this.MMFields.Clear();
this.CFields.Clear();
this.HyperCF.Clear();
this.Perm.Clear();
this.Range = range;
this.X = X;
if (!this.Paragraph.isRtlDirection())
this.checkNumbering(false);
this.spaces = spaceCount;
this.bidiFlow.begin(this.Paragraph.isRtlDirection());
this.InlineSdt = [];
this.run = null;
this.highlight = highlight_None;
this.shdColor = null;
this.shd = null;
};
ParagraphHighlightDrawState.prototype.endRange = function()
{
this.bidiFlow.end();
if (this.Paragraph.isRtlDirection())
this.checkNumbering(true);
};
ParagraphHighlightDrawState.prototype.AddInlineSdt = function(oSdt)
{
this.InlineSdt.push(oSdt);
};
ParagraphHighlightDrawState.prototype.addComment = function(commentId)
{
let comment = this.getComment(commentId);
if (!comment)
return;
if (commentId === this.currentCommentId)
this.haveCurrentComment = true;
this.comments.push(commentId);
};
ParagraphHighlightDrawState.prototype.removeComment = function(commentId)
{
let comment = this.getComment(commentId);
if (!comment)
return;
if (commentId === this.currentCommentId)
this.haveCurrentComment = false;
let index = this.comments.indexOf(commentId);
if (-1 !== index)
this.comments.splice(index, 1);
};
ParagraphHighlightDrawState.prototype.addPermRange = function(rangeId)
{
this.permRanges.push(rangeId);
};
ParagraphHighlightDrawState.prototype.removePermRange = function(rangeId)
{
if (!this.permRanges.length)
return;
if (this.permRanges[this.permRanges.length - 1] === rangeId)
{
--this.permRanges.length;
}
else
{
let pos = this.permRanges.indexOf(rangeId);
if (-1 !== pos)
this.permRanges.splice(pos, 1);
}
};
ParagraphHighlightDrawState.prototype.increaseSearchCounter = function()
{
++this.searchCounter;
};
ParagraphHighlightDrawState.prototype.decreaseSearchCounter = function()
{
--this.searchCounter;
};
ParagraphHighlightDrawState.prototype.IsCollectFixedForms = function()
{
return this.CollectFixedForms;
};
ParagraphHighlightDrawState.prototype.SetCollectFixedForms = function(isCollect)
{
this.CollectFixedForms = isCollect;
};
ParagraphHighlightDrawState.prototype.handleRunElement = function(element, run, collaborationColor)
{
if (!this.complexFields.checkRunElement(element))
return;
if (para_Drawing === element.Type && !element.IsInline())
return;
let flags = this.getFlags(element, !!collaborationColor);
let hyperlink = this.getHyperlinkObject();
this.bidiFlow.add([element, run, flags, hyperlink, collaborationColor, this.comments.slice(), this.haveCurrentComment], element.getBidiType());
};
ParagraphHighlightDrawState.prototype.handleBidiFlow = function(data)
{
let element = data[0];
let run = data[1];
let flags = data[2];
let hyperlink = data[3];
let collColor = data[4];
let comments = data[5];
let curComment = data[6];
let highlightAdditional;
let w = element.GetWidthVisible();
this.handleRun(run);
if (this.Graphics.m_bIsTextDrawer) {
highlightAdditional = {TextDrawer: {TextElement: element, SplitType: this.Graphics.m_nCurrentSplitOptions}};
}
this.addHighlight(this.X, this.X + w, flags, hyperlink, collColor, comments, curComment, highlightAdditional);
this.X += w;
};
ParagraphHighlightDrawState.prototype.handleParaMath = function(math)
{
if (!math || math.Root.IsEmptyRange(this.Line, this.Range))
return;
this.bidiFlow.end();
let y0 = this.Y0;
let y1 = this.Y1;
let coll = this.Coll;
let comm = this.Comm;
this.Coll = new CParaDrawingRangeLines();
this.Comm = new CParaDrawingRangeLines();
math.Root.Draw_HighLights(this);
let mathComments = this.Comm.getNext();
if (mathComments)
{
let bounds = math.Root.Get_LineBound(this.Line, this.Range);
comm.Add(bounds.Y, bounds.Y + bounds.H, bounds.X, bounds.X + bounds.W, 0, 0, 0, 0, mathComments.Additional);
}
let mathColl = this.Coll.getNext();
if (mathColl)
{
let bounds = math.Root.Get_LineBound(this.Line, this.Range);
coll.Add(bounds.Y, bounds.Y + bounds.H, bounds.X, bounds.X + bounds.W, 0, mathColl.r, mathColl.g, mathColl.b);
}
this.Coll = coll;
this.Comm = comm;
this.Y0 = y0;
this.Y1 = y1;
};
ParagraphHighlightDrawState.prototype.handleMathBase = function(element)
{
this.bidiFlow.end();
let textPr = element.Get_CompiledCtrPrp();
let shdColor = (textPr.Shd && !textPr.Shd.IsNil() ? textPr.Shd.GetSimpleColor(this.drawState.getTheme(), this.drawState.getColorMap()) : null);
let w = element.Get_LineBound(this.Line, this.Range).W;
let x = this.X;
let y0 = this.Y0;
let y1 = this.Y1;
let startPos = 0;
let endPos = element.Content.length - 1;
if (!element.bOneLine)
{
let rangeInfo = element.getRangePos(this.Line, this.Range);
startPos = rangeInfo[0];
endPos = rangeInfo[1];
}
for (let pos = startPos; pos <= endPos; ++pos)
{
element.Content[pos].Draw_HighLights(this);
}
// Add after because we are rendering in reverse direction
if (shdColor)
this.Shd.Add(y0, y1, x, x + w, 0, shdColor.r, shdColor.g, shdColor.b);
if (highlight_None !== textPr.HighLight)
this.High.Add(y0, y1, x, x + w, 0, textPr.HighLight.r, textPr.HighLight.g, textPr.HighLight.b);
this.X = x + w;
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Private area
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
ParagraphHighlightDrawState.prototype.checkNumbering = function(isRtl)
{
let paraNumbering = this.Paragraph.Numbering;
if (!paraNumbering.checkRange(this.Range, this.Line))
return;
let x = this.X;
let w = paraNumbering.WidthNum + paraNumbering.WidthSuff;
this.X += paraNumbering.WidthVisible;
let numPr = this.drawState.getParagraphCompiledPr().ParaPr.NumPr;
let paraParent = this.Paragraph.GetParent();
if (para_Numbering !== paraNumbering.Type
|| !numPr
|| !numPr.IsValid()
|| !paraParent
|| paraParent.IsEmptyParagraphAfterTableInTableCell(this.Paragraph.GetIndex()))
return;
let numManager = paraParent.GetNumbering();
let numLvl = numManager.GetNum(numPr.NumId).GetLvl(numPr.Lvl);
let numJc = numLvl.GetJc();
let numTextPr = this.Paragraph.GetNumberingTextPr();
if (!isRtl)
{
if (AscCommon.align_Right === numJc)
x -= paraNumbering.WidthNum;
else if (AscCommon.align_Center === numJc)
x -= paraNumbering.WidthNum / 2;
}
if (highlight_None !== numTextPr.HighLight)
this.High.Add(this.Y0, this.Y1, x, x + w, 0, numTextPr.HighLight.r, numTextPr.HighLight.g, numTextPr.HighLight.b, undefined, numTextPr);
let shdColor = (numTextPr.Shd && !numTextPr.Shd.IsNil() ? numTextPr.Shd.GetSimpleColor(this.drawState.getTheme(), this.drawState.getColorMap()) : null);
if (shdColor)
this.Shd.Add(this.Y0, this.Y1, x, x + w, 0, shdColor.r, shdColor.g, shdColor.b);
};
/**
* @param {string} commentId
* @returns {CComment}
*/
ParagraphHighlightDrawState.prototype.getComment = function(commentId)
{
if (!this.DrawComments)
return null;
let comment = AscCommon.g_oTableId.GetById(commentId);
if (comment
&& (this.DrawSolvedComments || !comment.IsSolved())
&& AscCommon.UserInfoParser.canViewComment(comment.GetUserName()))
return comment;
return null;
};
/**
* @param {AscWord.CRun} run
*/
ParagraphHighlightDrawState.prototype.handleRun = function(run)
{
if (this.run === run)
return;
this.run = run;
let textPr = run.getCompiledPr();
let shd = textPr.Shd;
this.shd = textPr.Shd;
this.shdColor = shd && !shd.IsNil() ? shd.GetSimpleColor(this.drawState.getTheme(), this.drawState.getColorMap()) : null;
if (!this.shdColor || this.shdColor.IsAuto() || (run.IsMathRun() && run.IsPlaceholder()))
this.shdColor = null;
this.highlight = textPr.HighLight;
if (textPr.HighlightColor)
{
textPr.HighlightColor.check(this.drawState.getTheme(), this.drawState.getColorMap());
let RGBA = textPr.HighlightColor.RGBA;
this.highlight = new CDocumentColor(RGBA.R, RGBA.G, RGBA.B, RGBA.A);
}
};
/**
*
*/
ParagraphHighlightDrawState.prototype.addHighlight = function(startX, endX, flags, hyperlink, collColor, comments, curComment, highlightAdditional)
{
let startY = this.Y0;
let endY = this.Y1;
if ((flags & FLAG_SHD) && this.shdColor)
this.Shd.Add(startY, endY, startX, endX, 0, this.shdColor.r, this.shdColor.g, this.shdColor.b, undefined, this.shd);
if (hyperlink)
this.HyperCF.Add(startY, endY, startX, endX, 0, 0, 0, 0, {HyperlinkCF : hyperlink});
if (flags & FLAG_COMPLEX_FIELD)
this.CFields.Add(startY, endY, startX, endX, 0, 0, 0, 0);
if (flags & FLAG_COMMENT && comments.length)
this.Comm.Add(startY, endY, startX, endX, 0, 0, 0, 0, {Active : curComment, CommentId : comments});
if ((flags & FLAG_HIGHLIGHT) && (this.highlight && highlight_None !== this.highlight))
this.High.Add(startY, endY, startX, endX, 0, this.highlight.r, this.highlight.g, this.highlight.b, highlightAdditional, this.highlight);
if (flags & FLAG_SEARCH)
this.Find.Add(startY, endY, startX, endX, 0, 0, 0, 0);
if ((flags & FLAG_COLLABORATION) && collColor)
this.Coll.Add(startY, endY, startX, endX, 0, collColor.r, collColor.g, collColor.b);
if (flags & FLAG_PERM_RANGE && this.permColor)
this.Perm.Add(startY, endY, startX, endX, 0, this.permColor.r, this.permColor.g, this.permColor.b);
};
ParagraphHighlightDrawState.prototype.pushHyperlink = function(hyperlink)
{
this.hyperlinks.push(hyperlink)
};
ParagraphHighlightDrawState.prototype.popHyperlink = function()
{
if (!this.hyperlinks.length)
return;
--this.hyperlinks.length;
};
ParagraphHighlightDrawState.prototype.getHyperlinkObject = function()
{
if (this.hyperlinks.length)
return this.hyperlinks[this.hyperlinks.length - 1];
let complexField = null;
if (this.complexFields.isComplexField() && (complexField = this.complexFields.getReferenceToHyperlink()))
return complexField.GetInstruction();
return null;
};
ParagraphHighlightDrawState.prototype.isComplexFieldHighlight = function()
{
return (this.complexFields.isComplexField()
&& !this.complexFields.isHiddenComplexFieldPart()
&& this.complexFields.isCurrentComplexField()
&& !this.complexFields.isHyperlinkField());
};
ParagraphHighlightDrawState.prototype.getFlags = function(element, isCollaboration)
{
let flags = 0;
if (this.DrawSearch && this.searchCounter > 0)
flags |= FLAG_SEARCH;
if (this.isComplexFieldHighlight())
flags |= FLAG_COMPLEX_FIELD;
if (this.permRanges.length > 0)
flags |= FLAG_PERM_RANGE;
if (element.Type !== para_End)
flags |= FLAG_SHD;
switch (element.Type)
{
case para_PageNum:
case para_PageCount:
case para_Drawing:
case para_Tab:
case para_Text:
case para_Math_Text:
case para_Math_Placeholder:
case para_Math_BreakOperator:
case para_Math_Ampersand:
case para_Sym:
case para_FootnoteReference:
case para_FootnoteRef:
case para_Separator:
case para_ContinuationSeparator:
case para_EndnoteReference:
case para_EndnoteRef:
{
if (this.DrawComments && this.comments.length > 0)
flags |= FLAG_COMMENT;
else
flags |= FLAG_HIGHLIGHT;
if (this.DrawSearch && this.searchCounter > 0)
flags |= FLAG_SEARCH;
else if (this.DrawColl && isCollaboration)
flags |= FLAG_COLLABORATION;
break;
}
case para_Space:
{
if (this.spaces > 0)
{
if (this.DrawComments && this.comments.length > 0)
flags |= FLAG_COMMENT;
else
flags |= FLAG_HIGHLIGHT;
--this.spaces;
}
if (this.DrawSearch && this.searchCounter > 0)
flags |= FLAG_SEARCH;
else if (this.DrawColl && isCollaboration)
flags |= FLAG_COLLABORATION;
break;
}
case para_End:
{
if (this.DrawColl && isCollaboration)
flags |= FLAG_COLLABORATION;
break;
}
case para_FieldChar:
{
if (element.IsVisual())
{
if (this.DrawComments && this.comments.length > 0)
flags |= FLAG_COMMENT;
else
flags |= FLAG_HIGHLIGHT;
if (this.DrawSearch && this.searchCounter > 0)
flags |= FLAG_SEARCH;
else if (this.DrawColl && isCollaboration)
flags |= FLAG_COLLABORATION;
if (element.IsFormField())
flags |= FLAG_COMPLEX_FIELD;
}
break;
}
}
return flags;
};
//--------------------------------------------------------export----------------------------------------------------
AscWord.ParagraphHighlightDrawState = ParagraphHighlightDrawState;
})(window);