12907 lines
406 KiB
JavaScript
12907 lines
406 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";
|
||
|
||
// Import
|
||
var g_oTableId = AscCommon.g_oTableId;
|
||
var g_oTextMeasurer = AscCommon.g_oTextMeasurer;
|
||
|
||
var c_oAscShdNil = Asc.c_oAscShdNil;
|
||
|
||
var c_oAscRevisionsChangeType = Asc.c_oAscRevisionsChangeType;
|
||
|
||
var reviewtype_Common = 0x00;
|
||
var reviewtype_Remove = 0x01;
|
||
var reviewtype_Add = 0x02;
|
||
|
||
function CSpellCheckerMarks()
|
||
{
|
||
this.len = 0;
|
||
this.data = null;
|
||
|
||
this.Check = function(len)
|
||
{
|
||
if (len <= this.len)
|
||
{
|
||
for (var i = 0; i < len; i++)
|
||
this.data[i] = 0;
|
||
return this.data;
|
||
}
|
||
|
||
this.len = len;
|
||
this.data = typeof(Int8Array) !== undefined ? new Int8Array(this.len) : new Array(this.len);
|
||
return this.data;
|
||
};
|
||
}
|
||
var g_oSpellCheckerMarks = new CSpellCheckerMarks();
|
||
|
||
/**
|
||
*
|
||
* @param Paragraph
|
||
* @param bMathRun
|
||
* @constructor
|
||
* @extends {CParagraphContentWithContentBase}
|
||
*/
|
||
function ParaRun(Paragraph, bMathRun)
|
||
{
|
||
CParagraphContentWithContentBase.call(this);
|
||
|
||
this.Id = AscCommon.g_oIdCounter.Get_NewId(); // Id данного элемента
|
||
this.Type = para_Run; // тип данного элемента
|
||
this.Paragraph = Paragraph; // Ссылка на параграф
|
||
this.Pr = new CTextPr(); // Текстовые настройки данного run
|
||
this.Content = []; // Содержимое данного run
|
||
|
||
this.State = new CParaRunState(); // Положение курсора и селекта в данного run
|
||
this.Selection = this.State.Selection;
|
||
this.CompiledPr = AscWord.g_textPrCache.add(new AscWord.CTextPr()); // Скомпилированные настройки
|
||
this.RecalcInfo = new CParaRunRecalcInfo(); // Флаги для пересчета (там же флаг пересчета стиля)
|
||
|
||
this.CollPrChangeMine = false;
|
||
this.CollPrChangeColor = null; // Если задан, значит это цвет того, кто менял
|
||
this.CollaborativeMarks = new CRunCollaborativeMarks();
|
||
this.m_oContentChanges = new AscCommon.CContentChanges(); // список изменений(добавление/удаление элементов)
|
||
|
||
this.NearPosArray = [];
|
||
this.SearchMarks = [];
|
||
this.SpellingMarks = [];
|
||
|
||
this.ReviewInfo = undefined;
|
||
|
||
if (editor
|
||
&& !editor.isPresentationEditor
|
||
&& editor.WordControl
|
||
&& editor.WordControl.m_oLogicDocument
|
||
&& true === editor.WordControl.m_oLogicDocument.IsTrackRevisions()
|
||
&& !editor.WordControl.m_oLogicDocument.RecalcTableHeader
|
||
&& !editor.WordControl.m_oLogicDocument.MoveDrawing
|
||
&& !(this.Paragraph && !this.Paragraph.bFromDocument))
|
||
{
|
||
this.ReviewInfo = AscWord.ReviewInfo.createAdd();
|
||
this.ReviewInfo.Update();
|
||
}
|
||
|
||
if (bMathRun)
|
||
{
|
||
this.Type = para_Math_Run;
|
||
|
||
// запомним позицию для recalculateCursorPosition, когда Run пустой
|
||
this.pos = new CMathPosition();
|
||
this.ParaMath = null;
|
||
this.Parent = null;
|
||
this.ArgSize = 0;
|
||
this.size = new CMathSize();
|
||
this.MathPrp = new CMPrp();
|
||
this.bEqArray = false;
|
||
}
|
||
|
||
this.CompositeInput = null;
|
||
|
||
// Добавляем данный класс в таблицу Id (обязательно в конце конструктора)
|
||
AscCommon.g_oTableId.Add(this, this.Id);
|
||
if (this.Paragraph && !this.Paragraph.bFromDocument &&AscCommon.History.CanAddChanges())
|
||
{
|
||
this.Save_StartState();
|
||
}
|
||
}
|
||
|
||
ParaRun.prototype = Object.create(CParagraphContentWithContentBase.prototype);
|
||
ParaRun.prototype.constructor = ParaRun;
|
||
|
||
ParaRun.prototype.Get_Type = function()
|
||
{
|
||
return this.Type;
|
||
};
|
||
//-----------------------------------------------------------------------------------
|
||
// Функции для работы с Id
|
||
//-----------------------------------------------------------------------------------
|
||
ParaRun.prototype.Get_Id = function()
|
||
{
|
||
return this.Id;
|
||
};
|
||
ParaRun.prototype.GetId = function()
|
||
{
|
||
return this.Id;
|
||
};
|
||
ParaRun.prototype.IsRun = function()
|
||
{
|
||
return true;
|
||
};
|
||
ParaRun.prototype.Set_ParaMath = function(ParaMath, Parent)
|
||
{
|
||
this.ParaMath = ParaMath;
|
||
this.Parent = Parent;
|
||
|
||
for(var i = 0; i < this.Content.length; i++)
|
||
{
|
||
this.Content[i].relate(this);
|
||
}
|
||
};
|
||
ParaRun.prototype.Save_StartState = function()
|
||
{
|
||
this.StartState = new CParaRunStartState(this);
|
||
};
|
||
ParaRun.prototype.SetParagraph = function(oParagraph)
|
||
{
|
||
this.Paragraph = oParagraph;
|
||
for (let nPos = 0, nCount = this.Content.length; nPos < nCount; ++nPos)
|
||
{
|
||
let oItem = this.Content[nPos];
|
||
if (oItem.IsDrawing())
|
||
oItem.SetParent(oParagraph);
|
||
}
|
||
};
|
||
//-----------------------------------------------------------------------------------
|
||
// Функции для работы с содержимым данного рана
|
||
//-----------------------------------------------------------------------------------
|
||
ParaRun.prototype.Copy = function(Selected, oPr)
|
||
{
|
||
if (!oPr)
|
||
oPr = {};
|
||
|
||
var isCopyReviewPr = oPr.CopyReviewPr;
|
||
|
||
let isMathRun = this.IsMathRun();
|
||
let NewRun = new AscWord.Run(undefined, isMathRun);
|
||
|
||
NewRun.Set_Pr(this.Pr.Copy(isCopyReviewPr, oPr));
|
||
|
||
var oLogicDocument = this.GetLogicDocument();
|
||
if(oPr && oPr.Comparison)
|
||
{
|
||
oPr.Comparison.checkCopyParaRun(NewRun, this);
|
||
}
|
||
else if (true === isCopyReviewPr || (oLogicDocument && (oLogicDocument.RecalcTableHeader || oLogicDocument.MoveDrawing)))
|
||
{
|
||
let reviewType = this.GetReviewType();
|
||
let reviewInfo = this.GetReviewInfo();
|
||
if (reviewInfo && !(oLogicDocument && (oLogicDocument.RecalcTableHeader || oLogicDocument.MoveDrawing)))
|
||
reviewInfo.SetMove(Asc.c_oAscRevisionsMove.NoMove);
|
||
|
||
NewRun.SetReviewTypeWithInfo(reviewType, reviewInfo ? reviewInfo.Copy() : undefined);
|
||
}
|
||
else if (oLogicDocument && true === oLogicDocument.IsTrackRevisions())
|
||
{
|
||
NewRun.SetReviewType(reviewtype_Add);
|
||
}
|
||
|
||
if (isMathRun)
|
||
NewRun.Set_MathPr(this.MathPrp.Copy());
|
||
|
||
|
||
|
||
|
||
|
||
var StartPos = 0;
|
||
var EndPos = this.Content.length;
|
||
|
||
if (true === Selected && true === this.State.Selection.Use)
|
||
{
|
||
StartPos = this.State.Selection.StartPos;
|
||
EndPos = this.State.Selection.EndPos;
|
||
|
||
if (StartPos > EndPos)
|
||
{
|
||
StartPos = this.State.Selection.EndPos;
|
||
EndPos = this.State.Selection.StartPos;
|
||
}
|
||
}
|
||
else if (true === Selected && true !== this.State.Selection.Use)
|
||
{
|
||
EndPos = -1;
|
||
}
|
||
|
||
var CurPos, AddedPos, Item;
|
||
|
||
if(oPr && oPr.Comparison)
|
||
{
|
||
var aCopyContent = [];
|
||
for (CurPos = StartPos; CurPos < EndPos; CurPos++)
|
||
{
|
||
Item = this.Content[CurPos];
|
||
|
||
if (para_NewLine === Item.Type
|
||
&& oPr
|
||
&& ((oPr.SkipLineBreak && Item.IsLineBreak())
|
||
|| (oPr.SkipPageBreak && Item.IsPageBreak())
|
||
|| (oPr.SkipColumnBreak && Item.IsColumnBreak())))
|
||
{
|
||
if (oPr.Paragraph && true !== oPr.Paragraph.IsEmpty())
|
||
{
|
||
aCopyContent.push( new AscWord.CRunSpace());
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// TODO: Как только перенесем para_End в сам параграф (как и нумерацию) убрать здесь
|
||
if (para_End !== Item.Type
|
||
&& para_RevisionMove !== Item.Type
|
||
&& (para_Drawing !== Item.Type || Item.Is_Inline() || true !== oPr.SkipAnchors)
|
||
&& ((para_FootnoteReference !== Item.Type && para_EndnoteReference !== Item.Type) || true !== oPr.SkipFootnoteReference)
|
||
&& ((para_FieldChar !== Item.Type && para_InstrText !== Item.Type) || true !== oPr.SkipComplexFields))
|
||
{
|
||
aCopyContent.push(Item.Copy(oPr));
|
||
}
|
||
}
|
||
}
|
||
NewRun.ConcatToContent(aCopyContent);
|
||
}
|
||
else
|
||
{
|
||
for (CurPos = StartPos, AddedPos = 0; CurPos < EndPos; CurPos++)
|
||
{
|
||
Item = this.Content[CurPos];
|
||
|
||
if (para_NewLine === Item.Type
|
||
&& oPr
|
||
&& ((oPr.SkipLineBreak && Item.IsLineBreak())
|
||
|| (oPr.SkipPageBreak && Item.IsPageBreak())
|
||
|| (oPr.SkipColumnBreak && Item.IsColumnBreak())))
|
||
{
|
||
if (oPr.Paragraph && true !== oPr.Paragraph.IsEmpty())
|
||
{
|
||
NewRun.Add_ToContent(AddedPos, new AscWord.CRunSpace(), false);
|
||
AddedPos++;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// TODO: Как только перенесем para_End в сам параграф (как и нумерацию) убрать здесь
|
||
if (para_End !== Item.Type
|
||
&& para_RevisionMove !== Item.Type
|
||
&& (para_Drawing !== Item.Type || Item.Is_Inline() || true !== oPr.SkipAnchors)
|
||
&& ((para_FootnoteReference !== Item.Type && para_EndnoteReference !== Item.Type) || true !== oPr.SkipFootnoteReference)
|
||
&& ((para_FieldChar !== Item.Type && para_InstrText !== Item.Type) || true !== oPr.SkipComplexFields))
|
||
{
|
||
NewRun.Add_ToContent(AddedPos, Item.Copy(oPr), false);
|
||
AddedPos++;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return NewRun;
|
||
};
|
||
|
||
ParaRun.prototype.Copy2 = function(oPr)
|
||
{
|
||
var NewRun = new ParaRun(this.Paragraph);
|
||
|
||
NewRun.Set_Pr( this.Pr.Copy(undefined, oPr) );
|
||
if(oPr && oPr.Comparison)
|
||
{
|
||
oPr.Comparison.checkCopyParaRun(NewRun, this);
|
||
}
|
||
var StartPos = 0;
|
||
var EndPos = this.Content.length;
|
||
var CurPos;
|
||
if(oPr && oPr.Comparison)
|
||
{
|
||
var aContentToInsert = [];
|
||
for (CurPos = StartPos; CurPos < EndPos; CurPos++ )
|
||
{
|
||
aContentToInsert.push(this.Content[CurPos].Copy(oPr));
|
||
}
|
||
NewRun.ConcatToContent(aContentToInsert);
|
||
}
|
||
else
|
||
{
|
||
for (CurPos = StartPos; CurPos < EndPos; CurPos++ )
|
||
{
|
||
var Item = this.Content[CurPos];
|
||
NewRun.Add_ToContent( CurPos - StartPos, Item.Copy(oPr), false );
|
||
}
|
||
}
|
||
return NewRun;
|
||
};
|
||
|
||
ParaRun.prototype.createDuplicateForSmartArt = function(oPr)
|
||
{
|
||
var NewRun = new ParaRun(this.Paragraph);
|
||
NewRun.Set_Pr(this.Pr.createDuplicateForSmartArt(oPr));
|
||
var StartPos = 0;
|
||
var EndPos = this.Content.length;
|
||
var CurPos;
|
||
for (CurPos = StartPos; CurPos < EndPos; CurPos++ )
|
||
{
|
||
var Item = this.Content[CurPos];
|
||
NewRun.Add_ToContent( CurPos - StartPos, Item.Copy(oPr), false );
|
||
}
|
||
return NewRun;
|
||
};
|
||
|
||
ParaRun.prototype.CopyContent = function(Selected)
|
||
{
|
||
return [this.Copy(Selected, {CopyReviewPr : true})];
|
||
};
|
||
ParaRun.prototype.GetSelectedContent = function(oSelectedContent)
|
||
{
|
||
if (oSelectedContent.IsTrackRevisions())
|
||
{
|
||
var nReviewType = this.GetReviewType();
|
||
var oReviewInfo = this.GetReviewInfo();
|
||
|
||
if (reviewtype_Add === nReviewType || reviewtype_Common === nReviewType)
|
||
{
|
||
var oRun = this.Copy(true, {CopyReviewPr : false});
|
||
|
||
if (reviewtype_Common !== nReviewType && (oReviewInfo.IsMovedTo() || oReviewInfo.IsMovedFrom()))
|
||
oSelectedContent.SetMovedParts(true);
|
||
|
||
if (oSelectedContent.IsMoveTrack())
|
||
oSelectedContent.AddRunForMoveTrack(oRun);
|
||
|
||
|
||
for (var nPos = 0, nCount = oRun.Content.length; nPos < nCount; ++nPos)
|
||
{
|
||
if (oRun.Content[nPos].Type === para_RevisionMove)
|
||
{
|
||
oRun.RemoveFromContent(nPos, 1);
|
||
nPos--;
|
||
nCount--;
|
||
|
||
oSelectedContent.SetMovedParts(true);
|
||
}
|
||
}
|
||
|
||
return oRun;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return this.Copy(true, {CopyReviewPr : true});
|
||
}
|
||
|
||
return null;
|
||
};
|
||
|
||
ParaRun.prototype.GetAllDrawingObjects = function(arrDrawingObjects)
|
||
{
|
||
if (!arrDrawingObjects)
|
||
arrDrawingObjects = [];
|
||
|
||
for (var nPos = 0, nCount = this.Content.length; nPos < nCount; ++nPos)
|
||
{
|
||
var oItem = this.Content[nPos];
|
||
if (para_Drawing === oItem.Type)
|
||
{
|
||
arrDrawingObjects.push(oItem);
|
||
oItem.GetAllDrawingObjects(arrDrawingObjects);
|
||
}
|
||
}
|
||
|
||
return arrDrawingObjects;
|
||
};
|
||
|
||
ParaRun.prototype.Clear_ContentChanges = function()
|
||
{
|
||
this.m_oContentChanges.Clear();
|
||
};
|
||
|
||
ParaRun.prototype.Add_ContentChanges = function(Changes)
|
||
{
|
||
this.m_oContentChanges.Add( Changes );
|
||
};
|
||
|
||
ParaRun.prototype.Refresh_ContentChanges = function()
|
||
{
|
||
this.m_oContentChanges.Refresh();
|
||
};
|
||
|
||
ParaRun.prototype.Get_Text = function(Text)
|
||
{
|
||
if (null === Text.Text)
|
||
return;
|
||
|
||
var ContentLen = this.Content.length;
|
||
|
||
for (var CurPos = 0; CurPos < ContentLen; CurPos++)
|
||
{
|
||
var Item = this.Content[CurPos];
|
||
var ItemType = Item.Type;
|
||
|
||
var bBreak = false;
|
||
|
||
switch (ItemType)
|
||
{
|
||
case para_Drawing:
|
||
case para_PageNum:
|
||
case para_PageCount:
|
||
{
|
||
if (true === Text.BreakOnNonText)
|
||
{
|
||
Text.Text = null;
|
||
bBreak = true;
|
||
}
|
||
|
||
break;
|
||
}
|
||
case para_End:
|
||
{
|
||
if (true === Text.BreakOnNonText)
|
||
{
|
||
Text.Text = null;
|
||
bBreak = true;
|
||
break;
|
||
}
|
||
|
||
let oParagraph = this.GetParagraph();
|
||
if (oParagraph && null === oParagraph.Get_DocumentNext() && oParagraph.IsTableCellContent())
|
||
{
|
||
if (!oParagraph.Parent.IsLastTableCellInRow(false))
|
||
Text.Text += undefined !== Text.TableCellSeparator ? Text.TableCellSeparator : '\t';
|
||
else
|
||
Text.Text += undefined !== Text.TableRowSeparator ? Text.TableRowSeparator : '\r\n';
|
||
}
|
||
else
|
||
{
|
||
Text.Text += undefined !== Text.ParaSeparator ? Text.ParaSeparator : '\r\n';
|
||
}
|
||
|
||
break;
|
||
}
|
||
|
||
case para_Text :
|
||
{
|
||
Text.Text += String.fromCharCode(Item.Value);
|
||
break;
|
||
}
|
||
case para_NewLine:
|
||
{
|
||
Text.Text += undefined !== Text.NewLineSeparator ? Text.NewLineSeparator : "\r";
|
||
break;
|
||
}
|
||
case para_Tab:
|
||
{
|
||
Text.Text += undefined !== Text.TabSymbol ? Text.TabSymbol : " ";
|
||
break;
|
||
}
|
||
case para_Space:
|
||
{
|
||
Text.Text += " ";
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (true === bBreak)
|
||
break;
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Получем текст из данного рана
|
||
* @param oText
|
||
* @returns {string}
|
||
*/
|
||
ParaRun.prototype.GetText = function(oText)
|
||
{
|
||
if (!oText)
|
||
{
|
||
oText = {
|
||
Text : ""
|
||
};
|
||
}
|
||
|
||
this.Get_Text(oText);
|
||
return oText.Text;
|
||
};
|
||
/**
|
||
*
|
||
* @param {MathTextAndStyles | boolean} oMathText
|
||
* @param {boolean} isSelectedText
|
||
* @constructor
|
||
*/
|
||
ParaRun.prototype.GetTextOfElement = function(oMathText, isSelectedText)
|
||
{
|
||
oMathText = new AscMath.MathTextAndStyles(oMathText);
|
||
let isLatex = oMathText.IsLaTeX();
|
||
let nStartPos = (isSelectedText == true ? Math.min(this.Selection.StartPos, this.Selection.EndPos) : 0);
|
||
let nEndPos = (isSelectedText == true ? Math.max(this.Selection.StartPos, this.Selection.EndPos) : this.Content.length);
|
||
let isStrFont = false;
|
||
|
||
if (oMathText.IsLaTeX() && this.math_autocorrection)
|
||
{
|
||
if (this.math_autocorrection.getIsMathRm() || this.math_autocorrection.getIsText())
|
||
{
|
||
let str = '';
|
||
for (let i = nStartPos; i < nEndPos; i++)
|
||
{
|
||
let oCurrentElement = this.Content[i];
|
||
str += oCurrentElement.GetTextOfElement().GetText();
|
||
}
|
||
|
||
if (this.math_autocorrection.getIsMathRm())
|
||
oMathText.AddText(new AscMath.MathText('\\mathrm{' + str + '}', this));
|
||
else if (this.math_autocorrection.getIsText())
|
||
oMathText.AddText(new AscMath.MathText('\\text{' + str + '}', this));
|
||
|
||
return oMathText;
|
||
}
|
||
}
|
||
// [Unicode] Investigate the mechanism for converting an escaped backslash. Information about separating it
|
||
// into a separate Run is not enough.
|
||
|
||
for (let i = nStartPos; i < nEndPos; i++)
|
||
{
|
||
let oCurrentElement = this.Content[i];
|
||
let strCurrentElement = oCurrentElement.GetTextOfElement().GetText();
|
||
|
||
if (this.Content.length === 1 && oCurrentElement.value === 11034)
|
||
return oMathText;
|
||
|
||
let oLast = oMathText.GetLastContent();
|
||
let strLast = ""
|
||
if (oLast)
|
||
strLast = oLast.text[oLast.text.length - 1];
|
||
|
||
// for LaTeX space processing while convert to professional mode
|
||
if (oMathText.IsDefaultText)
|
||
{
|
||
oMathText.AddText(new AscMath.MathText(strCurrentElement, this));
|
||
continue;
|
||
}
|
||
|
||
let arrFontContent = oMathText.IsLaTeX()
|
||
? AscMath.GetLaTeXFont[strCurrentElement]
|
||
: undefined;
|
||
let strMathFontName = arrFontContent
|
||
? AscMath.oStandardFont[arrFontContent[0]]
|
||
: undefined;
|
||
|
||
if (!strMathFontName && isLatex)
|
||
{
|
||
let strTemp = AscMath.SymbolsToLaTeX[strCurrentElement];
|
||
if (strTemp)
|
||
strCurrentElement = strTemp;
|
||
}
|
||
|
||
if (strMathFontName)
|
||
{
|
||
if (!isStrFont)
|
||
oMathText.AddText(new AscMath.MathText(strMathFontName + "{", this));
|
||
|
||
isStrFont = true;
|
||
oMathText.AddText(new AscMath.MathText(arrFontContent[1], this));
|
||
}
|
||
else if (isStrFont && !arrFontContent)
|
||
{
|
||
isStrFont = false;
|
||
oMathText.AddText(new AscMath.MathText('}', this));
|
||
}
|
||
else
|
||
{
|
||
if (oMathText.IsLaTeX())
|
||
{
|
||
if (strCurrentElement === " " && strLast !== "\\") //normal space
|
||
oMathText.AddText(new AscMath.MathText('\\ ', this))
|
||
else if (strCurrentElement === " ")
|
||
oMathText.AddText(new AscMath.MathText("\\quad", this));
|
||
// else if (strCurrentElement === " ")
|
||
// oMathText.AddText(new AscMath.MathText("\\:", this));
|
||
// else if (strCurrentElement === " ")
|
||
// oMathText.AddText(new AscMath.MathText("\\;", this));
|
||
else
|
||
{
|
||
oMathText.AddText(new AscMath.MathText(strCurrentElement, this));
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// in Word if slash in separate ParaRun -> slash interpreted as an escaped slash
|
||
// if (strCurrentElement === "/" && this.Content.length === 1 && strLast !== "\\")
|
||
// {
|
||
// let oEscSlash = new AscMath.MathText("\\/", this);
|
||
// let oAddData = oEscSlash.GetAdditionalData();
|
||
// let oMathMetaData = oAddData.GetMathMetaData();
|
||
// oMathMetaData.setIsEscapedSlash();
|
||
// oMathText.AddText(oEscSlash, this);
|
||
// }
|
||
// else
|
||
// {
|
||
let mathText = new AscMath.MathText(strCurrentElement, this);
|
||
let additionalData = mathText.GetAdditionalData();
|
||
|
||
if (this.math_autocorrection)
|
||
additionalData.metaData = this.math_autocorrection.Copy();
|
||
|
||
oMathText.AddText(mathText);
|
||
//}
|
||
}
|
||
}
|
||
}
|
||
|
||
if (isStrFont)
|
||
oMathText.AddText(new AscMath.MathText('}', this));
|
||
|
||
return oMathText;
|
||
};
|
||
ParaRun.prototype.MathAutocorrection_GetBracketsOperatorsInfo = function (isLaTeX)
|
||
{
|
||
const arrBracketsInfo = [];
|
||
let isOpen = false;
|
||
let isClose = false;
|
||
|
||
for (let intCounter = 0; intCounter < this.Content.length; intCounter++)
|
||
{
|
||
let strContent = String.fromCharCode(this.Content[intCounter].value);
|
||
let intCount = null;
|
||
|
||
if ((strContent === "{" || strContent === "}") && isLaTeX)
|
||
continue;
|
||
|
||
if (strContent === "├")
|
||
{
|
||
isOpen = true;
|
||
continue;
|
||
}
|
||
else if (strContent === "┤")
|
||
{
|
||
if (intCounter === this.Content.length - 1)
|
||
{
|
||
arrBracketsInfo.push([intCounter - 1, 1]);
|
||
}
|
||
else
|
||
{
|
||
isClose = true;
|
||
continue;
|
||
}
|
||
}
|
||
|
||
if (AscMath.MathLiterals.lBrackets.SearchU(strContent))
|
||
intCount = -1;
|
||
else if (AscMath.MathLiterals.rBrackets.SearchU(strContent))
|
||
intCount = 1;
|
||
else if (AscMath.MathLiterals.lrBrackets.SearchU(strContent))
|
||
intCount = 0;
|
||
else if (AscMath.MathLiterals.operator.SearchU(strContent))
|
||
intCount = 2;
|
||
|
||
if (intCount === null && isOpen)
|
||
{
|
||
arrBracketsInfo.push([intCounter - 1, -1]);
|
||
isOpen = false;
|
||
}
|
||
else if (intCount === null && isClose)
|
||
{
|
||
arrBracketsInfo.push([intCounter - 1, 1]);
|
||
isClose = false;
|
||
}
|
||
|
||
if (intCount !== null)
|
||
arrBracketsInfo.push([intCounter, intCount]);
|
||
}
|
||
|
||
return arrBracketsInfo;
|
||
}
|
||
ParaRun.prototype.MathAutocorrection_GetOperatorInfo = function ()
|
||
{
|
||
const arrOperatorContent = [];
|
||
|
||
for (let intCounter = 0; intCounter < this.Content.length; intCounter++)
|
||
{
|
||
let strContent = String.fromCharCode(this.Content[intCounter].value);
|
||
|
||
if (AscMath.MathLiterals.operator.SearchU(strContent))
|
||
arrOperatorContent.push(intCounter);
|
||
}
|
||
|
||
return arrOperatorContent;
|
||
}
|
||
|
||
ParaRun.prototype.MathAutocorrection_GetSlashesInfo = function ()
|
||
{
|
||
const arrOperatorContent = [];
|
||
|
||
for (let intCounter = 0; intCounter < this.Content.length; intCounter++)
|
||
{
|
||
let strContent = String.fromCharCode(this.Content[intCounter].value);
|
||
|
||
if (strContent === "\\")
|
||
arrOperatorContent.push(intCounter);
|
||
}
|
||
|
||
return arrOperatorContent;
|
||
}
|
||
|
||
ParaRun.prototype.MathAutocorrection_IsLastElement = function(type)
|
||
{
|
||
if (this.Content.length === 0)
|
||
return false;
|
||
|
||
let oLastElement = this.Content[this.Content.length - 1];
|
||
let strLastElement = String.fromCharCode(oLastElement.value);
|
||
return type.SearchU(strLastElement);
|
||
}
|
||
|
||
ParaRun.prototype.MathAutoCorrection_DeleteLastSpace = function()
|
||
{
|
||
if (this.Content.length === 0)
|
||
return false;
|
||
|
||
let oLastElement = this.Content[this.Content.length - 1];
|
||
if (oLastElement.value === 32)
|
||
{
|
||
this.Remove_FromContent(this.Content.length - 1, 1);
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
|
||
// Проверяем пустой ли ран
|
||
ParaRun.prototype.Is_Empty = function(oProps)
|
||
{
|
||
var SkipAnchor = (undefined !== oProps ? oProps.SkipAnchor : false);
|
||
let SkipDrawing = (undefined !== oProps ? oProps.SkipDrawing : false);
|
||
var SkipEnd = (undefined !== oProps ? oProps.SkipEnd : false);
|
||
var SkipPlcHldr = (undefined !== oProps ? oProps.SkipPlcHldr : false);
|
||
var SkipNewLine = (undefined !== oProps ? oProps.SkipNewLine : false);
|
||
var SkipCF = (undefined !== oProps ? oProps.SkipComplexFields : false);
|
||
var SkipSpace = (undefined !== oProps ? oProps.SkipSpace : false);
|
||
var SkipTab = (undefined !== oProps ? oProps.SkipTab : false);
|
||
|
||
var nCount = this.Content.length;
|
||
|
||
if (true !== SkipAnchor
|
||
&& true !== SkipEnd
|
||
&& true !== SkipPlcHldr
|
||
&& true !== SkipNewLine
|
||
&& true !== SkipCF
|
||
&& true !== SkipSpace)
|
||
{
|
||
if (nCount > 0)
|
||
return false;
|
||
else
|
||
return true;
|
||
}
|
||
else
|
||
{
|
||
for (var nCurPos = 0; nCurPos < nCount; ++nCurPos)
|
||
{
|
||
var oItem = this.Content[nCurPos];
|
||
var nType = oItem.Type;
|
||
|
||
if ((true !== SkipAnchor || para_Drawing !== nType || false !== oItem.Is_Inline())
|
||
&& (true !== SkipDrawing || para_Drawing !== nType)
|
||
&& (true !== SkipEnd || para_End !== nType)
|
||
&& (true !== SkipPlcHldr || true !== oItem.IsPlaceholder())
|
||
&& (true !== SkipNewLine || para_NewLine !== nType)
|
||
&& (true !== SkipCF || (para_InstrText !== nType && para_FieldChar !== nType)
|
||
&& (true !== SkipSpace || para_Space !== nType)
|
||
&& (true !== SkipTab || para_Tab !== nType)))
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.Is_CheckingNearestPos = function()
|
||
{
|
||
if (this.NearPosArray.length > 0)
|
||
return true;
|
||
|
||
return false;
|
||
};
|
||
|
||
// Начинается ли данный ран с новой строки
|
||
ParaRun.prototype.IsStartFromNewLine = function()
|
||
{
|
||
if (this.protected_GetLinesCount() < 2 || 0 !== this.protected_GetRangeStartPos(1, 0))
|
||
return false;
|
||
|
||
return true;
|
||
};
|
||
/**
|
||
* Добавляем новый элменет в текущую позицию
|
||
* @param {AscWord.CRunElementBase} oItem
|
||
*/
|
||
ParaRun.prototype.Add = function(oItem)
|
||
{
|
||
var oRun;
|
||
|
||
if (!this.IsMathRun() && !(oItem instanceof CMathText))
|
||
oRun = this.CheckRunBeforeAdd(oItem);
|
||
|
||
if (!oRun)
|
||
oRun = this;
|
||
|
||
oRun.private_AddItemToRun(oRun.State.ContentPos, oItem);
|
||
|
||
var nFlags = 0;
|
||
if (para_Run === oRun.Type && (nFlags = oItem.GetAutoCorrectFlags()))
|
||
oRun.ProcessAutoCorrect(oRun.State.ContentPos - 1, nFlags);
|
||
};
|
||
/**
|
||
* Ищем подходящий ран для добавления текста в режиме рецензирования (если нужно создаем новый), если возвращается
|
||
* null, значит текущий ран подходит.
|
||
* @param {?ParaRun} oNewRun
|
||
* @returns {?ParaRun}
|
||
*/
|
||
ParaRun.prototype.private_CheckTrackRevisionsBeforeAdd = function(oNewRun)
|
||
{
|
||
var TrackRevisions = false;
|
||
if (this.Paragraph && this.Paragraph.LogicDocument)
|
||
TrackRevisions = this.Paragraph.LogicDocument.IsTrackRevisions();
|
||
|
||
var ReviewType = this.GetReviewType();
|
||
if ((true === TrackRevisions && (reviewtype_Add !== ReviewType || true !== this.ReviewInfo.IsCurrentUser()))
|
||
|| (false === TrackRevisions && reviewtype_Common !== ReviewType))
|
||
{
|
||
var DstReviewType = true === TrackRevisions ? reviewtype_Add : reviewtype_Common;
|
||
|
||
if (oNewRun)
|
||
{
|
||
oNewRun.SetReviewType(DstReviewType);
|
||
return oNewRun;
|
||
}
|
||
|
||
// Если мы стоим в конце рана, тогда проверяем следующий элемент родительского класса, аналогично если мы стоим
|
||
// в начале рана, проверяем предыдущий элемент родительского класса.
|
||
|
||
var Parent = this.Get_Parent();
|
||
if (null === Parent)
|
||
return null;
|
||
|
||
// Ищем данный элемент в родительском классе
|
||
var RunPos = this.private_GetPosInParent(Parent);
|
||
|
||
if (-1 === RunPos)
|
||
return null;
|
||
|
||
var CurPos = this.State.ContentPos;
|
||
if (0 === CurPos && RunPos > 0)
|
||
{
|
||
var PrevElement = Parent.Content[RunPos - 1];
|
||
if (para_Run === PrevElement.Type && DstReviewType === PrevElement.GetReviewType() && true === this.Pr.Is_Equal(PrevElement.Pr) && PrevElement.ReviewInfo && true === PrevElement.ReviewInfo.IsCurrentUser())
|
||
{
|
||
PrevElement.State.ContentPos = PrevElement.Content.length;
|
||
return PrevElement;
|
||
}
|
||
}
|
||
|
||
if (this.Content.length === CurPos && (RunPos < Parent.Content.length - 2 || (RunPos < Parent.Content.length - 1 && !(Parent instanceof Paragraph))))
|
||
{
|
||
var NextElement = Parent.Content[RunPos + 1];
|
||
if (para_Run === NextElement.Type && DstReviewType === NextElement.GetReviewType() && true === this.Pr.Is_Equal(NextElement.Pr) && NextElement.ReviewInfo && true === NextElement.ReviewInfo.IsCurrentUser())
|
||
{
|
||
NextElement.State.ContentPos = 0;
|
||
return NextElement;
|
||
}
|
||
}
|
||
|
||
var NewRun = new ParaRun(this.Paragraph, this.IsMathRun());
|
||
NewRun.Set_Pr(this.Pr.Copy());
|
||
NewRun.SetReviewType(DstReviewType);
|
||
NewRun.State.ContentPos = 0;
|
||
|
||
if (0 === CurPos)
|
||
{
|
||
Parent.Add_ToContent(RunPos, NewRun);
|
||
}
|
||
else if (this.Content.length === CurPos)
|
||
{
|
||
Parent.Add_ToContent(RunPos + 1, NewRun);
|
||
}
|
||
else
|
||
{
|
||
var OldReviewInfo = (this.ReviewInfo ? this.ReviewInfo.Copy() : undefined);
|
||
var OldReviewType = this.GetReviewType();
|
||
|
||
// Нужно разделить данный ран в текущей позиции
|
||
var RightRun = this.Split2(CurPos);
|
||
Parent.Add_ToContent(RunPos + 1, NewRun);
|
||
Parent.Add_ToContent(RunPos + 2, RightRun);
|
||
|
||
this.SetReviewTypeWithInfo(OldReviewType, OldReviewInfo);
|
||
RightRun.SetReviewTypeWithInfo(OldReviewType, OldReviewInfo);
|
||
}
|
||
|
||
return NewRun;
|
||
}
|
||
|
||
return oNewRun;
|
||
};
|
||
/**
|
||
* Проверяем корректность настроек рана перед добавлением элемента
|
||
* @param {?ParaRun} oNewRun
|
||
* @param oItem
|
||
*/
|
||
ParaRun.prototype.private_CheckTextScriptBeforeAdd = function(oNewRun, oItem)
|
||
{
|
||
if (!oItem || !oItem.IsText())
|
||
return oNewRun;
|
||
|
||
let script = oItem.GetScript();
|
||
if (AscFonts.HB_SCRIPT.HB_SCRIPT_INHERITED === script || AscFonts.HB_SCRIPT.HB_SCRIPT_COMMON === script)
|
||
return oNewRun;
|
||
|
||
let oPr = this.Pr;
|
||
|
||
// TODO: Когда будет обрабатывать RTL добавить тут
|
||
let isAddRTL = false, isRemoveRTL = false;
|
||
|
||
let isAddCS = (AscCommon.IsComplexScript(oItem.GetCodePoint()) && !oPr.CS);
|
||
let isRemoveCS = (!AscCommon.IsComplexScript(oItem.GetCodePoint()) && oPr.CS);
|
||
|
||
if (!oNewRun
|
||
&& (isAddCS || isRemoveCS || isAddRTL || isRemoveRTL))
|
||
{
|
||
let runToApply;
|
||
if (this.IsOnlyCommonTextScript())
|
||
{
|
||
runToApply = this;
|
||
}
|
||
else
|
||
{
|
||
oNewRun = this.private_SplitRunInCurPos();
|
||
runToApply = oNewRun;
|
||
}
|
||
|
||
if (isAddCS)
|
||
runToApply.ApplyComplexScript(true);
|
||
else if (isRemoveCS)
|
||
runToApply.ApplyComplexScript(false);
|
||
}
|
||
|
||
return oNewRun;
|
||
};
|
||
/**
|
||
* Проверяем, не является ли это ран с символом конца параграфа
|
||
* @param {!ParaRun} oNewRun
|
||
* @returns {?ParaRun}
|
||
*/
|
||
ParaRun.prototype.private_CheckParaEndRunBeforeAdd = function(oNewRun)
|
||
{
|
||
if (!oNewRun && this.IsParaEndRun())
|
||
oNewRun = this.private_SplitRunInCurPos();
|
||
|
||
return oNewRun;
|
||
};
|
||
/**
|
||
* Проверяем язык ввода
|
||
* @param {!ParaRun} oNewRun
|
||
* @param {CDocument}oLogicDocument
|
||
* @param {!ParaRun} oNewRun
|
||
* @returns {?ParaRun}
|
||
*/
|
||
ParaRun.prototype.private_CheckLanguageBeforeAdd = function(oNewRun, oLogicDocument)
|
||
{
|
||
if (!oLogicDocument)
|
||
return oNewRun;
|
||
|
||
var oApi = oLogicDocument.GetApi();
|
||
|
||
// Специальный код, связанный с обработкой изменения языка ввода при наборе.
|
||
if (true === oLogicDocument.CheckLanguageOnTextAdd && oApi)
|
||
{
|
||
var nRequiredLanguage = oApi.asc_getKeyboardLanguage();
|
||
var nCurrentLanguage = this.Get_CompiledPr(false).Lang.Val;
|
||
if (-1 !== nRequiredLanguage && nRequiredLanguage !== nCurrentLanguage)
|
||
{
|
||
var oNewLang = new CLang();
|
||
oNewLang.Val = nRequiredLanguage;
|
||
|
||
if (oNewRun)
|
||
{
|
||
oNewRun.Set_Lang(oNewLang);
|
||
}
|
||
else if (this.IsEmpty())
|
||
{
|
||
this.Set_Lang(oNewLang);
|
||
}
|
||
else
|
||
{
|
||
oNewRun = this.private_SplitRunInCurPos();
|
||
if (oNewRun)
|
||
oNewRun.Set_Lang(oNewLang);
|
||
}
|
||
}
|
||
}
|
||
|
||
return oNewRun;
|
||
};
|
||
/**
|
||
* Провяеряем добавление ссылки на сноску или добавление текста рядом с ссылкой на сноску
|
||
* @param {!ParaRun} oNewRun
|
||
* @param {AscWord.CRunElementBase} oItem
|
||
* @param {CDocument} oLogicDocument
|
||
* @returns {?ParaRun}
|
||
*/
|
||
ParaRun.prototype.private_CheckFootnoteReferencesBeforeAdd = function(oNewRun, oItem, oLogicDocument)
|
||
{
|
||
if (!oLogicDocument || !this.Paragraph || !this.Paragraph.bFromDocument)
|
||
return oNewRun;
|
||
|
||
// Специальный код, связанный с работой сносок:
|
||
// 1. При добавлении сноски мы ее оборачиваем в отдельный ран со специальным стилем.
|
||
// 2. Если мы находимся в ране со специальным стилем сносок и следующий или предыдущий элемент и есть сноска, тогда
|
||
// мы добавляем элемент (если это не ссылка на сноску) в новый ран без стиля для сносок.
|
||
|
||
var oStyles = oLogicDocument.GetStyles();
|
||
if (oItem && (para_FootnoteRef === oItem.Type || para_FootnoteReference === oItem.Type || para_EndnoteRef === oItem.Type || para_EndnoteReference === oItem.Type))
|
||
{
|
||
var isFootnote = (para_FootnoteRef === oItem.Type || para_FootnoteReference === oItem.Type);
|
||
|
||
if (oNewRun)
|
||
{
|
||
oNewRun.SetVertAlign(undefined);
|
||
oNewRun.SetRStyle(isFootnote ? oStyles.GetDefaultFootnoteReference() : oStyles.GetDefaultEndnoteReference());
|
||
|
||
}
|
||
else if (this.IsEmpty())
|
||
{
|
||
this.SetVertAlign(undefined);
|
||
this.SetRStyle(isFootnote ? oStyles.GetDefaultFootnoteReference() : oStyles.GetDefaultEndnoteReference());
|
||
}
|
||
else
|
||
{
|
||
oNewRun = this.private_SplitRunInCurPos();
|
||
if (oNewRun)
|
||
{
|
||
oNewRun.SetVertAlign(undefined);
|
||
oNewRun.SetRStyle(isFootnote ? oStyles.GetDefaultFootnoteReference() : oStyles.GetDefaultEndnoteReference());
|
||
}
|
||
}
|
||
}
|
||
else if (true === this.IsCurPosNearFootEndnoteReference())
|
||
{
|
||
if (!oNewRun)
|
||
oNewRun = this.private_SplitRunInCurPos();
|
||
|
||
if (oNewRun)
|
||
oNewRun.SetVertAlign(AscCommon.vertalign_Baseline);
|
||
}
|
||
|
||
return oNewRun;
|
||
};
|
||
/**
|
||
* Проверяем выделение текста перед добавление нового элемента
|
||
* @param {!ParaRun} oNewRun
|
||
* @returns {?ParaRun}
|
||
*/
|
||
ParaRun.prototype.private_CheckHighlightBeforeAdd = function(oNewRun)
|
||
{
|
||
// Специальный код с обработкой выделения (highlight)
|
||
// Текст, который пишем до или после выделенного текста делаем без выделения.
|
||
if ((0 === this.State.ContentPos || this.Content.length === this.State.ContentPos) && highlight_None !== this.Get_CompiledPr(false).HighLight)
|
||
{
|
||
var Parent = this.Get_Parent();
|
||
var RunPos = this.private_GetPosInParent(Parent);
|
||
if (null !== Parent && -1 !== RunPos)
|
||
{
|
||
if ((0 === this.State.ContentPos
|
||
&& (0 === RunPos
|
||
|| Parent.Content[RunPos - 1].Type !== para_Run
|
||
|| highlight_None === Parent.Content[RunPos - 1].Get_CompiledPr(false).HighLight))
|
||
|| (this.Content.length === this.State.ContentPos
|
||
&& (RunPos === Parent.Content.length - 1
|
||
|| para_Run !== Parent.Content[RunPos + 1].Type
|
||
|| highlight_None === Parent.Content[RunPos + 1].Get_CompiledPr(false).HighLight)
|
||
|| (RunPos === Parent.Content.length - 2
|
||
&& Parent instanceof Paragraph)))
|
||
{
|
||
if (!oNewRun)
|
||
oNewRun = this.private_SplitRunInCurPos();
|
||
|
||
if (oNewRun)
|
||
oNewRun.Set_HighLight(highlight_None);
|
||
}
|
||
}
|
||
}
|
||
|
||
return oNewRun;
|
||
};
|
||
/**
|
||
* Проверяем выделение текста перед добавление нового элемента
|
||
* @param {!ParaRun} oNewRun
|
||
* @returns {?ParaRun}
|
||
*/
|
||
ParaRun.prototype.private_CheckHighlightColorBeforeAdd = function(oNewRun)
|
||
{
|
||
// Специальный код с обработкой выделения (highlight)
|
||
// Текст, который пишем до или после выделенного текста делаем без выделения.
|
||
if ((0 === this.State.ContentPos || this.Content.length === this.State.ContentPos) && undefined !== this.Get_CompiledPr(false).HighlightColor)
|
||
{
|
||
var Parent = this.Get_Parent();
|
||
var RunPos = this.private_GetPosInParent(Parent);
|
||
if (null !== Parent && -1 !== RunPos)
|
||
{
|
||
if ((0 === this.State.ContentPos
|
||
&& (0 === RunPos
|
||
|| Parent.Content[RunPos - 1].Type !== para_Run
|
||
|| undefined === Parent.Content[RunPos - 1].Get_CompiledPr(false).HighlightColor))
|
||
|| (this.Content.length === this.State.ContentPos
|
||
&& (RunPos === Parent.Content.length - 1
|
||
|| para_Run !== Parent.Content[RunPos + 1].Type
|
||
|| undefined === Parent.Content[RunPos + 1].Get_CompiledPr(false).HighlightColor)
|
||
|| (RunPos === Parent.Content.length - 2
|
||
&& Parent instanceof Paragraph)))
|
||
{
|
||
if (!oNewRun)
|
||
oNewRun = this.private_SplitRunInCurPos();
|
||
|
||
if (oNewRun)
|
||
{
|
||
oNewRun.SetHighlightColor(undefined);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return oNewRun;
|
||
};
|
||
/**
|
||
* Проверяем принудительный перенос в начале математического рана
|
||
* @param {!ParaRun} oNewRun
|
||
* @returns {?ParaRun}
|
||
*/
|
||
ParaRun.prototype.private_CheckMathBreakOperatorBeforeAdd = function(oNewRun)
|
||
{
|
||
// Если в начале текущего Run идет принудительный перенос => создаем новый Run
|
||
if (!oNewRun && para_Math_Run === this.Type && 0 === this.State.ContentPos && true === this.Is_StartForcedBreakOperator())
|
||
oNewRun = this.private_SplitRunInCurPos();
|
||
|
||
return oNewRun;
|
||
};
|
||
/**
|
||
* Функция проверяет настройки рана, перед добавлением внутрь элементов
|
||
* Если необходимо, то добавляется новый ран с необходимыми настройками
|
||
* @param {?AscWord.CRunElementBase} oItem
|
||
* @returns {?ParaRun}
|
||
*/
|
||
ParaRun.prototype.CheckRunBeforeAdd = function(oItem)
|
||
{
|
||
if (this.GetParentForm())
|
||
return null;
|
||
|
||
var oNewRun = null;
|
||
var oLogicDocument = this.GetLogicDocument();
|
||
|
||
oNewRun = this.private_CheckParaEndRunBeforeAdd(oNewRun);
|
||
oNewRun = this.private_CheckLanguageBeforeAdd(oNewRun, oLogicDocument);
|
||
oNewRun = this.private_CheckFootnoteReferencesBeforeAdd(oNewRun, oItem, oLogicDocument);
|
||
oNewRun = this.private_CheckHighlightBeforeAdd(oNewRun);
|
||
oNewRun = this.private_CheckHighlightColorBeforeAdd(oNewRun);
|
||
oNewRun = this.private_CheckMathBreakOperatorBeforeAdd(oNewRun);
|
||
oNewRun = this.private_CheckTextScriptBeforeAdd(oNewRun, oItem);
|
||
|
||
if (oNewRun)
|
||
oNewRun.MoveCursorToStartPos();
|
||
|
||
// В функции private_CheckTrackRevisionsBeforeAdd возможно, что вернется не новый, а существующий левый или правый ран
|
||
// и нужно брать позицию из рана, поэтому сдвигаться в начало рана нельзя
|
||
oNewRun = this.private_CheckTrackRevisionsBeforeAdd(oNewRun);
|
||
|
||
if (oNewRun)
|
||
oNewRun.SetThisElementCurrentInParagraph();
|
||
|
||
return oNewRun;
|
||
};
|
||
/**
|
||
* Специальная функция проверяет, что в ране присутствуют текстовые элементы только из общих скриптов (т.е. не
|
||
* принадлижащие какой-то конкретной пиьменности). Если текстовых элементов нет вообще, то вернется false
|
||
* @returns {boolean}
|
||
*/
|
||
ParaRun.prototype.IsOnlyCommonTextScript = function()
|
||
{
|
||
let isCommonScript = false;
|
||
for (let index = 0, count = this.Content.length; index < count; ++index)
|
||
{
|
||
let item = this.Content[index];
|
||
if (item.IsText())
|
||
{
|
||
let script = item.GetScript();
|
||
if (AscFonts.HB_SCRIPT.HB_SCRIPT_INHERITED === script || AscFonts.HB_SCRIPT.HB_SCRIPT_COMMON === script)
|
||
isCommonScript = true;
|
||
else
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return isCommonScript;
|
||
};
|
||
/**
|
||
* Is a run inside smartArt
|
||
* @param [bReturnSmartArtShape] {boolean}
|
||
* @returns {boolean|null|AscFormat.CShape}
|
||
*/
|
||
ParaRun.prototype.IsInsideSmartArtShape = function (bReturnSmartArtShape)
|
||
{
|
||
const oParagraph = this.GetParagraph();
|
||
if (oParagraph)
|
||
{
|
||
return oParagraph.IsInsideSmartArtShape(bReturnSmartArtShape);
|
||
}
|
||
return bReturnSmartArtShape ? null : false;
|
||
};
|
||
/**
|
||
* Проверяем, предзназначен ли данный ран чисто для математических формул.
|
||
* @returns {boolean}
|
||
*/
|
||
ParaRun.prototype.IsMathRun = function()
|
||
{
|
||
return this.Type === para_Math_Run ? true : false;
|
||
};
|
||
|
||
ParaRun.prototype.private_SplitRunInCurPos = function()
|
||
{
|
||
var NewRun = null;
|
||
var Parent = this.Get_Parent();
|
||
var RunPos = this.private_GetPosInParent();
|
||
if (null !== Parent && -1 !== RunPos)
|
||
{
|
||
// Если мы стоим в начале рана, тогда добавим новый ран в начало, если мы стоим в конце рана, тогда
|
||
// добавим новый ран после текущего, а если мы в середине рана, тогда надо разбивать текущий ран.
|
||
NewRun = new ParaRun(this.Paragraph, para_Math_Run === this.Type);
|
||
NewRun.Set_Pr(this.Pr.Copy());
|
||
|
||
var CurPos = this.State.ContentPos;
|
||
if (0 === CurPos)
|
||
{
|
||
Parent.Add_ToContent(RunPos, NewRun);
|
||
}
|
||
else if (this.Content.length === CurPos)
|
||
{
|
||
Parent.Add_ToContent(RunPos + 1, NewRun);
|
||
}
|
||
else
|
||
{
|
||
// Нужно разделить данный ран в текущей позиции
|
||
var RightRun = this.Split2(CurPos);
|
||
Parent.Add_ToContent(RunPos + 1, NewRun);
|
||
Parent.Add_ToContent(RunPos + 2, RightRun);
|
||
}
|
||
}
|
||
|
||
return NewRun;
|
||
};
|
||
ParaRun.prototype.IsCurPosNearFootEndnoteReference = function()
|
||
{
|
||
if (this.Paragraph && this.Paragraph.LogicDocument && this.Paragraph.bFromDocument)
|
||
{
|
||
var oStyles = this.Paragraph.LogicDocument.Get_Styles();
|
||
var nCurPos = this.State.ContentPos;
|
||
|
||
if (!oStyles)
|
||
return false;
|
||
|
||
if ((this.GetRStyle() === oStyles.GetDefaultFootnoteReference()
|
||
&& ((nCurPos > 0 && this.Content[nCurPos - 1] && (para_FootnoteRef === this.Content[nCurPos - 1].Type || para_FootnoteReference === this.Content[nCurPos - 1].Type))
|
||
|| (nCurPos < this.Content.length && this.Content[nCurPos] && (para_FootnoteRef === this.Content[nCurPos].Type || para_FootnoteReference === this.Content[nCurPos].Type))))
|
||
|| (this.GetRStyle() === oStyles.GetDefaultEndnoteReference()
|
||
&& ((nCurPos > 0 && this.Content[nCurPos - 1] && (para_EndnoteRef === this.Content[nCurPos - 1].Type || para_EndnoteReference === this.Content[nCurPos - 1].Type))
|
||
|| (nCurPos < this.Content.length && this.Content[nCurPos] && (para_EndnoteRef === this.Content[nCurPos].Type || para_EndnoteReference === this.Content[nCurPos].Type)))))
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
};
|
||
ParaRun.prototype.private_AddItemToRun = function(nPos, Item)
|
||
{
|
||
if ((para_FootnoteReference === Item.Type || para_EndnoteReference === Item.Type) && true === Item.IsCustomMarkFollows() && undefined !== Item.GetCustomText())
|
||
{
|
||
this.AddToContent(nPos, Item, true);
|
||
this.AddText(Item.GetCustomText(), nPos + 1);
|
||
}
|
||
else
|
||
{
|
||
this.Add_ToContent(nPos, Item, true);
|
||
}
|
||
};
|
||
/**
|
||
* Очищаем все содержимое данного рана
|
||
*/
|
||
ParaRun.prototype.ClearContent = function()
|
||
{
|
||
if (this.Content.length <= 0)
|
||
return;
|
||
|
||
this.RemoveFromContent(0, this.Content.length, true);
|
||
};
|
||
ParaRun.prototype.Remove = function(Direction, bOnAddText)
|
||
{
|
||
var TrackRevisions = null;
|
||
if (this.Paragraph && this.Paragraph.LogicDocument)
|
||
TrackRevisions = this.Paragraph.LogicDocument.IsTrackRevisions();
|
||
|
||
var Selection = this.State.Selection;
|
||
|
||
if (true === TrackRevisions && !this.CanDeleteInReviewMode())
|
||
{
|
||
if (reviewtype_Remove === this.GetReviewType())
|
||
{
|
||
// Тут мы ничего не делаем, просто перешагиваем через удаленный текст
|
||
if (true !== Selection.Use)
|
||
{
|
||
var CurPos = this.State.ContentPos;
|
||
|
||
if (Direction < 0)
|
||
{
|
||
while (CurPos > 0 && this.Content[CurPos - 1].IsDrawing() && !this.Content[CurPos - 1].IsInline())
|
||
CurPos--;
|
||
|
||
if (CurPos <= 0)
|
||
return false;
|
||
|
||
this.State.ContentPos--;
|
||
this.Make_ThisElementCurrent();
|
||
}
|
||
else
|
||
{
|
||
if (CurPos >= this.Content.length || para_End === this.Content[CurPos].Type)
|
||
return false;
|
||
|
||
let oItem = this.Content[CurPos];
|
||
if (oItem.IsText())
|
||
{
|
||
let oInfo = this.RemoveTextCluster(CurPos);
|
||
oInfo.SetDocumentPositionHere();
|
||
}
|
||
else
|
||
{
|
||
this.State.ContentPos++;
|
||
this.Make_ThisElementCurrent();
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// Ничего не делаем
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (true === Selection.Use)
|
||
{
|
||
// Мы должны данный ран разбить в начальной и конечной точках выделения и центральный ран пометить как
|
||
// удаленный.
|
||
|
||
var StartPos = Selection.StartPos;
|
||
var EndPos = Selection.EndPos;
|
||
|
||
if (StartPos > EndPos)
|
||
{
|
||
StartPos = Selection.EndPos;
|
||
EndPos = Selection.StartPos;
|
||
}
|
||
|
||
var Parent = this.Get_Parent();
|
||
var RunPos = this.private_GetPosInParent(Parent);
|
||
|
||
if (-1 !== RunPos)
|
||
{
|
||
var DeletedRun = null;
|
||
if (StartPos <= 0 && EndPos >= this.Content.length)
|
||
DeletedRun = this;
|
||
else if (StartPos <= 0)
|
||
{
|
||
this.Split2(EndPos, Parent, RunPos);
|
||
DeletedRun = this;
|
||
}
|
||
else if (EndPos >= this.Content.length)
|
||
{
|
||
DeletedRun = this.Split2(StartPos, Parent, RunPos);
|
||
}
|
||
else
|
||
{
|
||
this.Split2(EndPos, Parent, RunPos);
|
||
DeletedRun = this.Split2(StartPos, Parent, RunPos);
|
||
}
|
||
|
||
DeletedRun.SetReviewType(reviewtype_Remove, true);
|
||
DeletedRun.SelectAll(Selection.EndPos - Selection.StartPos);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
var CurPos = this.State.ContentPos;
|
||
let oInfo;
|
||
if (Direction < 0)
|
||
{
|
||
while (CurPos > 0 && this.Content[CurPos - 1].IsDrawing() && !this.Content[CurPos - 1].IsInline())
|
||
CurPos--;
|
||
|
||
if (CurPos <= 0)
|
||
return false;
|
||
|
||
if (this.Content[CurPos - 1].IsDrawing() && this.Content[CurPos - 1].IsInline())
|
||
return this.Paragraph.Parent.Select_DrawingObject(this.Content[CurPos - 1].GetId());
|
||
|
||
oInfo = this.RemoveItemInReview(CurPos, Direction);
|
||
}
|
||
else
|
||
{
|
||
if (CurPos >= this.Content.length || para_End === this.Content[CurPos].Type)
|
||
return false;
|
||
|
||
if (this.Content[CurPos].IsDrawing() && this.Content[CurPos].IsInline())
|
||
return this.Paragraph.Parent.Select_DrawingObject(this.Content[CurPos].GetId());
|
||
|
||
if (this.Content[CurPos].IsText())
|
||
oInfo = this.RemoveTextCluster(CurPos);
|
||
else
|
||
oInfo = this.RemoveItemInReview(CurPos, Direction);
|
||
}
|
||
|
||
oInfo.SetDocumentPositionHere();
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (true === Selection.Use)
|
||
{
|
||
var StartPos = Selection.StartPos;
|
||
var EndPos = Selection.EndPos;
|
||
|
||
if (StartPos > EndPos)
|
||
{
|
||
var Temp = StartPos;
|
||
StartPos = EndPos;
|
||
EndPos = Temp;
|
||
}
|
||
|
||
// Если в выделение попадает ParaEnd, тогда удаляем все кроме этого элемента
|
||
if (true === this.Selection_CheckParaEnd())
|
||
{
|
||
for (var CurPos = EndPos - 1; CurPos >= StartPos; CurPos--)
|
||
{
|
||
if (para_End !== this.Content[CurPos].Type)
|
||
this.Remove_FromContent(CurPos, 1, true);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
this.Remove_FromContent(StartPos, EndPos - StartPos, true);
|
||
}
|
||
|
||
this.RemoveSelection();
|
||
this.State.ContentPos = StartPos;
|
||
}
|
||
else
|
||
{
|
||
var CurPos = this.State.ContentPos;
|
||
|
||
if (Direction < 0)
|
||
{
|
||
while (CurPos > 0 && this.Content[CurPos - 1].IsDrawing() && !this.Content[CurPos - 1].IsInline())
|
||
CurPos--;
|
||
|
||
if (CurPos <= 0)
|
||
return false;
|
||
|
||
if (this.Content[CurPos - 1].IsDrawing() && this.Content[CurPos - 1].IsInline())
|
||
{
|
||
return this.Paragraph.Parent.Select_DrawingObject(this.Content[CurPos - 1].GetId());
|
||
}
|
||
else if (para_FieldChar === this.Content[CurPos - 1].Type)
|
||
{
|
||
var oComplexField = this.Content[CurPos - 1].GetComplexField();
|
||
if (oComplexField)
|
||
{
|
||
oComplexField.SelectField();
|
||
var oLogicDocument = (this.Paragraph && this.Paragraph.bFromDocument) ? this.Paragraph.LogicDocument : null;
|
||
if (oLogicDocument)
|
||
{
|
||
oLogicDocument.Document_UpdateInterfaceState();
|
||
oLogicDocument.Document_UpdateSelectionState();
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
var oStyles = (this.Paragraph && this.Paragraph.bFromDocument && this.Paragraph.LogicDocument) ? this.Paragraph.LogicDocument.GetStyles() : null;
|
||
if (oStyles && 1 === this.Content.length && ((para_FootnoteReference === this.Content[0].Type && this.GetRStyle() === oStyles.GetDefaultFootnoteReference()) || (para_EndnoteReference === this.Content[0].Type && this.GetRStyle() === oStyles.GetDefaultEndnoteReference())))
|
||
this.SetRStyle(undefined);
|
||
|
||
this.RemoveFromContent(CurPos - 1, 1, true);
|
||
this.State.ContentPos = CurPos - 1;
|
||
}
|
||
else
|
||
{
|
||
while (CurPos < this.Content.length && this.Content[CurPos].IsDrawing() && !this.Content[CurPos].IsInline())
|
||
CurPos++;
|
||
|
||
if (CurPos >= this.Content.length || para_End === this.Content[CurPos].Type)
|
||
return false;
|
||
|
||
if (this.Content[CurPos].IsDrawing() && this.Content[CurPos].IsInline())
|
||
{
|
||
return this.Paragraph.Parent.Select_DrawingObject(this.Content[CurPos].GetId());
|
||
}
|
||
else if (para_FieldChar === this.Content[CurPos].Type)
|
||
{
|
||
var oComplexField = this.Content[CurPos].GetComplexField();
|
||
if (oComplexField)
|
||
{
|
||
oComplexField.SelectField();
|
||
var oLogicDocument = (this.Paragraph && this.Paragraph.bFromDocument) ? this.Paragraph.LogicDocument : null;
|
||
if (oLogicDocument)
|
||
{
|
||
oLogicDocument.Document_UpdateInterfaceState();
|
||
oLogicDocument.Document_UpdateSelectionState();
|
||
}
|
||
}
|
||
return true;
|
||
}
|
||
|
||
var oStyles = (this.Paragraph && this.Paragraph.bFromDocument && this.Paragraph.LogicDocument) ? this.Paragraph.LogicDocument.GetStyles() : null;
|
||
if (oStyles && 1 === this.Content.length && ((para_FootnoteReference === this.Content[0].Type && this.GetRStyle() === oStyles.GetDefaultFootnoteReference()) || (para_EndnoteReference === this.Content[0].Type && this.GetRStyle() === oStyles.GetDefaultEndnoteReference())))
|
||
this.SetRStyle(undefined);
|
||
|
||
let oItem = this.Content[CurPos];
|
||
if (oItem.IsText() || oItem.IsMathText())
|
||
{
|
||
let oInfo = this.RemoveTextCluster(CurPos);
|
||
oInfo.SetDocumentPositionHere();
|
||
}
|
||
else
|
||
{
|
||
this.RemoveFromContent(CurPos, 1, true);
|
||
this.State.ContentPos = CurPos;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return true;
|
||
};
|
||
ParaRun.prototype.RemoveParaEnd = function()
|
||
{
|
||
let nEndPos = -1;
|
||
let nCount = this.Content.length;
|
||
for (let nPos = 0; nPos < nCount; ++nPos)
|
||
{
|
||
if (this.Content[nPos].IsParaEnd())
|
||
{
|
||
nEndPos = nPos;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (-1 === nEndPos)
|
||
return false;
|
||
|
||
this.RemoveFromContent(nEndPos, nCount - nEndPos, true);
|
||
return true;
|
||
};
|
||
ParaRun.prototype.RemoveTextCluster = function(nPos)
|
||
{
|
||
let oParagraph = this.GetParagraph();
|
||
let oLogicDocument = this.GetLogicDocument();
|
||
let isTrack = oLogicDocument && oLogicDocument.IsTrackRevisions() && !this.CanDeleteInReviewMode();
|
||
if (!oParagraph || nPos >= this.Content.length || (!this.Content[nPos].IsText() && !this.Content[nPos].IsMathText()))
|
||
return new CRunWithPosition(this, nPos);
|
||
|
||
let oCurRun = this;
|
||
if (!isTrack)
|
||
{
|
||
this.RemoveFromContent(nPos, 1, true);
|
||
}
|
||
else if (reviewtype_Remove !== this.GetReviewType())
|
||
{
|
||
let oInfo = this.RemoveItemInReview(nPos, 1);
|
||
oCurRun = oInfo.Run;
|
||
nPos = oInfo.Pos;
|
||
}
|
||
else
|
||
{
|
||
nPos++;
|
||
}
|
||
|
||
let oNextInfo = oCurRun.GetNextRunElementEx(nPos);
|
||
let oNext = oNextInfo ? oNextInfo.Element : null;
|
||
if (!oNext || (!oNext.IsText() && !oNext.IsMathText()) || !oNext.IsCombiningMark())
|
||
return new CRunWithPosition(oCurRun, nPos);
|
||
|
||
let oContentPos = oNextInfo.Pos;
|
||
let nInRunPos = oContentPos.Get(oContentPos.GetDepth());
|
||
oContentPos.DecreaseDepth(1);
|
||
let oRun = oParagraph.GetElementByPos(oContentPos);
|
||
if (!(oRun instanceof ParaRun))
|
||
return new CRunWithPosition(oCurRun, nPos);
|
||
|
||
return oRun.RemoveTextCluster(nInRunPos);
|
||
};
|
||
ParaRun.prototype.RemoveItemInReview = function(nPos, nDirection)
|
||
{
|
||
let nResultPos = nPos + 1;
|
||
let oResultRun = this;
|
||
|
||
let oParent = this.GetParent();
|
||
let nInParentPos = this.GetPosInParent(oParent);
|
||
if (!oParent || -1 === nInParentPos)
|
||
return new CRunWithPosition(oResultRun, nResultPos)
|
||
|
||
let oPrev, oNext;
|
||
if (nDirection > 0)
|
||
{
|
||
if (0 === nPos && 1 === this.Content.length)
|
||
{
|
||
this.SetReviewType(reviewtype_Remove, true);
|
||
|
||
oResultRun = this;
|
||
nResultPos = 1;
|
||
}
|
||
else if (0 === nPos
|
||
&& this.Content.length > 0
|
||
&& nInParentPos > 0
|
||
&& (oPrev = oParent.GetElement(nInParentPos - 1)).IsRun()
|
||
&& reviewtype_Remove === oPrev.GetReviewType()
|
||
&& this.Pr.IsEqual(oPrev.GetDirectTextPr()))
|
||
{
|
||
let oItem = this.Content[0];
|
||
this.RemoveFromContent(0, 1, true);
|
||
oPrev.AddToContent(oPrev.GetElementsCount(), oItem);
|
||
|
||
oResultRun = this;
|
||
nResultPos = 0;
|
||
}
|
||
else if (this.Content.length - 1 === nPos
|
||
&& this.Content.length > 0
|
||
&& nInParentPos < oParent.GetElementsCount() - 1
|
||
&& (oNext = oParent.GetElement(nInParentPos + 1)).IsRun()
|
||
&& reviewtype_Remove === oNext.GetReviewType()
|
||
&& this.Pr.IsEqual(oNext.GetDirectTextPr()))
|
||
{
|
||
let oItem = this.Content[nPos];
|
||
this.RemoveFromContent(nPos, 1, true);
|
||
oNext.AddToContent(0, oItem, true);
|
||
|
||
oResultRun = oNext;
|
||
nResultPos = 1;
|
||
}
|
||
else if (nPos < this.Content.length)
|
||
{
|
||
let oRRun = nPos < this.Content.length - 1 ? this.Split2(nPos + 1, oParent, nInParentPos) : null;
|
||
let oCRun = nPos > 0 ? this.Split2(nPos, oParent, nInParentPos) : this;
|
||
oCRun.SetReviewType(reviewtype_Remove, true);
|
||
|
||
if (oRRun)
|
||
{
|
||
oResultRun = oRRun;
|
||
nResultPos = 0;
|
||
}
|
||
else
|
||
{
|
||
oResultRun = this;
|
||
nResultPos = this.Content.length;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (1 === this.Content.length && 1 === nPos)
|
||
{
|
||
this.SetReviewType(reviewtype_Remove, true);
|
||
|
||
oResultRun = this;
|
||
nResultPos = 0;
|
||
}
|
||
else if (1 === nPos
|
||
&& this.Content.length > 0
|
||
&& nInParentPos > 0
|
||
&& (oPrev = oParent.GetElement(nInParentPos - 1)).IsRun()
|
||
&& reviewtype_Remove === oPrev.GetReviewType()
|
||
&& this.Pr.IsEqual(oPrev.GetDirectTextPr()))
|
||
{
|
||
let nPrevLen = oPrev.GetElementsCount();
|
||
let oItem = this.Content[0];
|
||
this.RemoveFromContent(0, 1, true);
|
||
oPrev.AddToContent(nPrevLen, oItem);
|
||
|
||
oResultRun = oPrev;
|
||
nResultPos = nPrevLen;
|
||
}
|
||
else if (this.Content.length === nPos
|
||
&& this.Content.length > 0
|
||
&& nInParentPos < oParent.GetElementsCount() - 1
|
||
&& (oNext = oParent.GetElement(nInParentPos + 1)).IsRun()
|
||
&& reviewtype_Remove === oNext.GetReviewType()
|
||
&& this.Pr.IsEqual(oNext.GetDirectTextPr()))
|
||
{
|
||
let oItem = this.Content[nPos - 1];
|
||
this.RemoveFromContent(nPos - 1, 1, true);
|
||
oNext.AddToContent(0, oItem);
|
||
|
||
oResultRun = this;
|
||
nResultPos = nPos - 1;
|
||
}
|
||
else if (nPos > 0)
|
||
{
|
||
if (nPos < this.Content.length)
|
||
this.Split2(nPos, oParent, nInParentPos);
|
||
|
||
let oCRun = nPos > 1 ? this.Split2(nPos - 1, oParent, nInParentPos) : this;
|
||
oCRun.SetReviewType(reviewtype_Remove, true);
|
||
|
||
oResultRun = oCRun;
|
||
nResultPos = 0;
|
||
}
|
||
}
|
||
|
||
return new CRunWithPosition(oResultRun, nResultPos);
|
||
};
|
||
|
||
/**
|
||
* Обновляем позиции селекта, курсора и переносов строк при добавлении элемента в контент данного рана.
|
||
* @param Pos
|
||
*/
|
||
ParaRun.prototype.private_UpdatePositionsOnAdd = function(Pos)
|
||
{
|
||
// Обновляем текущую позицию
|
||
if (this.State.ContentPos >= Pos)
|
||
this.State.ContentPos++;
|
||
|
||
// Обновляем начало и конец селекта
|
||
if (true === this.State.Selection.Use)
|
||
{
|
||
if (this.State.Selection.StartPos >= Pos)
|
||
this.State.Selection.StartPos++;
|
||
|
||
if (this.State.Selection.EndPos >= Pos)
|
||
this.State.Selection.EndPos++;
|
||
}
|
||
|
||
// Также передвинем всем метки переносов страниц и строк
|
||
var LinesCount = this.protected_GetLinesCount();
|
||
for (var CurLine = 0; CurLine < LinesCount; CurLine++)
|
||
{
|
||
var RangesCount = this.protected_GetRangesCount(CurLine);
|
||
|
||
for (var CurRange = 0; CurRange < RangesCount; CurRange++)
|
||
{
|
||
var StartPos = this.protected_GetRangeStartPos(CurLine, CurRange);
|
||
var EndPos = this.protected_GetRangeEndPos(CurLine, CurRange);
|
||
|
||
if (StartPos > Pos)
|
||
StartPos++;
|
||
|
||
if (EndPos > Pos)
|
||
EndPos++;
|
||
|
||
this.protected_FillRange(CurLine, CurRange, StartPos, EndPos);
|
||
}
|
||
|
||
// Особый случай, когда мы добавляем элемент в самый последний ран
|
||
if (Pos === this.Content.length - 1 && LinesCount - 1 === CurLine)
|
||
{
|
||
this.protected_FillRangeEndPos(CurLine, RangesCount - 1, this.protected_GetRangeEndPos(CurLine, RangesCount - 1) + 1);
|
||
}
|
||
}
|
||
};
|
||
|
||
/**
|
||
* Обновляем позиции селекта, курсора и переносов строк при удалении элементов из контента данного рана.
|
||
* @param Pos
|
||
* @param Count
|
||
*/
|
||
ParaRun.prototype.private_UpdatePositionsOnRemove = function(Pos, Count)
|
||
{
|
||
// Обновим текущую позицию
|
||
if (this.State.ContentPos > Pos + Count)
|
||
this.State.ContentPos -= Count;
|
||
else if (this.State.ContentPos > Pos)
|
||
this.State.ContentPos = Pos;
|
||
|
||
// Обновим начало и конец селекта
|
||
if (true === this.State.Selection.Use)
|
||
{
|
||
if (this.State.Selection.StartPos <= this.State.Selection.EndPos)
|
||
{
|
||
if (this.State.Selection.StartPos > Pos + Count)
|
||
this.State.Selection.StartPos -= Count;
|
||
else if (this.State.Selection.StartPos > Pos)
|
||
this.State.Selection.StartPos = Pos;
|
||
|
||
if (this.State.Selection.EndPos >= Pos + Count)
|
||
this.State.Selection.EndPos -= Count;
|
||
else if (this.State.Selection.EndPos > Pos)
|
||
this.State.Selection.EndPos = Math.max(0, Pos - 1);
|
||
}
|
||
else
|
||
{
|
||
if (this.State.Selection.StartPos >= Pos + Count)
|
||
this.State.Selection.StartPos -= Count;
|
||
else if (this.State.Selection.StartPos > Pos)
|
||
this.State.Selection.StartPos = Math.max(0, Pos - 1);
|
||
|
||
if (this.State.Selection.EndPos > Pos + Count)
|
||
this.State.Selection.EndPos -= Count;
|
||
else if (this.State.Selection.EndPos > Pos)
|
||
this.State.Selection.EndPos = Pos;
|
||
}
|
||
}
|
||
|
||
// Также передвинем всем метки переносов страниц и строк
|
||
var LinesCount = this.protected_GetLinesCount();
|
||
for (var CurLine = 0; CurLine < LinesCount; CurLine++)
|
||
{
|
||
var RangesCount = this.protected_GetRangesCount(CurLine);
|
||
for (var CurRange = 0; CurRange < RangesCount; CurRange++)
|
||
{
|
||
var StartPos = this.protected_GetRangeStartPos(CurLine, CurRange);
|
||
var EndPos = this.protected_GetRangeEndPos(CurLine, CurRange);
|
||
|
||
if (StartPos > Pos + Count)
|
||
StartPos -= Count;
|
||
else if (StartPos > Pos)
|
||
StartPos = Math.max(0, Pos);
|
||
|
||
if (EndPos >= Pos + Count)
|
||
EndPos -= Count;
|
||
else if (EndPos >= Pos)
|
||
EndPos = Math.max(0, Pos);
|
||
|
||
this.protected_FillRange(CurLine, CurRange, StartPos, EndPos);
|
||
}
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.private_UpdateCompositeInputPositionsOnAdd = function(Pos)
|
||
{
|
||
if (!this.CompositeInput)
|
||
return;
|
||
|
||
this.CompositeInput.updateOnAdd(Pos);
|
||
};
|
||
ParaRun.prototype.private_UpdateCompositeInputPositionsOnRemove = function(Pos, Count)
|
||
{
|
||
if (!this.CompositeInput)
|
||
return;
|
||
|
||
this.CompositeInput.updateOnRemove(Pos, Count);
|
||
};
|
||
|
||
ParaRun.prototype.GetLogicDocument = function()
|
||
{
|
||
if (this.Paragraph && this.Paragraph.LogicDocument)
|
||
return this.Paragraph.LogicDocument;
|
||
|
||
if (editor && editor.WordControl)
|
||
return editor.WordControl.m_oLogicDocument;
|
||
|
||
return null;
|
||
};
|
||
|
||
// Добавляем элемент в позицию с сохранием в историю
|
||
ParaRun.prototype.Add_ToContent = function(Pos, Item, UpdatePosition)
|
||
{
|
||
if (this.GetTextForm() && this.GetTextForm().IsComb())
|
||
this.RecalcInfo.Measure = true;
|
||
|
||
this.CheckParentFormKey();
|
||
|
||
if (-1 === Pos)
|
||
Pos = this.Content.length;
|
||
|
||
if (Item.SetParent)
|
||
Item.SetParent(this);
|
||
|
||
// Здесь проверка на возвожность добавления в историю стоит заранее для ускорения открытия файлов, чтобы
|
||
// не создавалось лишних классов
|
||
if (AscCommon.History.CanAddChanges())
|
||
AscCommon.History.Add(new CChangesRunAddItem(this, Pos, [Item], true));
|
||
|
||
if (Pos >= this.Content.length)
|
||
{
|
||
Pos = this.Content.length;
|
||
this.Content.push(Item);
|
||
}
|
||
else
|
||
{
|
||
this.Content.splice(Pos, 0, Item);
|
||
}
|
||
|
||
if (true === UpdatePosition)
|
||
this.private_UpdatePositionsOnAdd(Pos);
|
||
|
||
// Обновляем позиции в NearestPos
|
||
var NearPosLen = this.NearPosArray.length;
|
||
for ( var Index = 0; Index < NearPosLen; Index++ )
|
||
{
|
||
var RunNearPos = this.NearPosArray[Index];
|
||
var ContentPos = RunNearPos.NearPos.ContentPos;
|
||
var Depth = RunNearPos.Depth;
|
||
|
||
if ( ContentPos.Data[Depth] >= Pos )
|
||
ContentPos.Data[Depth]++;
|
||
}
|
||
|
||
this.private_UpdateMarksOnAdd(Pos, 1);
|
||
|
||
this.private_UpdateDocumentOutline();
|
||
this.private_UpdateTrackRevisionOnChangeContent(true);
|
||
|
||
// Обновляем позиции меток совместного редактирования
|
||
this.CollaborativeMarks.Update_OnAdd( Pos );
|
||
|
||
this.RecalcInfo.OnAdd(Pos);
|
||
this.OnContentChange();
|
||
};
|
||
|
||
ParaRun.prototype.Remove_FromContent = function(Pos, Count, UpdatePosition)
|
||
{
|
||
if (Count <= 0)
|
||
return;
|
||
|
||
if (this.GetTextForm() && this.GetTextForm().IsComb())
|
||
this.RecalcInfo.Measure = true;
|
||
|
||
this.CheckParentFormKey();
|
||
|
||
for (var nIndex = Pos, nCount = Math.min(Pos + Count, this.Content.length); nIndex < nCount; ++nIndex)
|
||
{
|
||
if (this.Content[nIndex].PreDelete)
|
||
this.Content[nIndex].PreDelete();
|
||
}
|
||
|
||
if (AscCommon.History.CanAddChanges())
|
||
{
|
||
var DeletedItems = this.Content.slice(Pos, Pos + Count);
|
||
AscCommon.History.Add(new CChangesRunRemoveItem(this, Pos, DeletedItems));
|
||
}
|
||
|
||
this.Content.splice(Pos, Count);
|
||
|
||
if (true === UpdatePosition)
|
||
this.private_UpdatePositionsOnRemove(Pos, Count);
|
||
|
||
// Обновляем позиции в NearestPos
|
||
var NearPosLen = this.NearPosArray.length;
|
||
for ( var Index = 0; Index < NearPosLen; Index++ )
|
||
{
|
||
var RunNearPos = this.NearPosArray[Index];
|
||
var ContentPos = RunNearPos.NearPos.ContentPos;
|
||
var Depth = RunNearPos.Depth;
|
||
|
||
if ( ContentPos.Data[Depth] > Pos + Count )
|
||
ContentPos.Data[Depth] -= Count;
|
||
else if ( ContentPos.Data[Depth] > Pos )
|
||
ContentPos.Data[Depth] = Math.max( 0 , Pos );
|
||
}
|
||
|
||
this.private_UpdateMarksOnRemove(Pos, Count);
|
||
|
||
this.private_UpdateDocumentOutline();
|
||
this.private_UpdateTrackRevisionOnChangeContent(true);
|
||
|
||
// Обновляем позиции меток совместного редактирования
|
||
this.CollaborativeMarks.Update_OnRemove( Pos, Count );
|
||
|
||
this.RecalcInfo.OnRemove(Pos, Count);
|
||
this.OnContentChange();
|
||
};
|
||
|
||
/**
|
||
* Добавляем к массиву содержимого массив новых элементов
|
||
* @param arrNewItems
|
||
*/
|
||
ParaRun.prototype.ConcatToContent = function(arrNewItems)
|
||
{
|
||
this.CheckParentFormKey();
|
||
|
||
for (var nIndex = 0, nCount = arrNewItems.length; nIndex < nCount; ++nIndex)
|
||
{
|
||
if (arrNewItems[nIndex].SetParent)
|
||
arrNewItems[nIndex].SetParent(this);
|
||
}
|
||
|
||
var StartPos = this.Content.length;
|
||
this.Content = this.Content.concat(arrNewItems);
|
||
|
||
AscCommon.History.Add(new CChangesRunAddItem(this, StartPos, arrNewItems, false));
|
||
|
||
this.private_UpdateTrackRevisionOnChangeContent(true);
|
||
|
||
// Отмечаем, что надо перемерить элементы в данном ране
|
||
this.RecalcInfo.Measure = true;
|
||
this.OnContentChange();
|
||
};
|
||
/**
|
||
* Добавляем в конец рана заданную строку
|
||
* @param {string} sString
|
||
* @param {number} [nPos=-1] если позиция не задана (или значение -1), то добавляем в конец
|
||
* @returns {number} Позиция после добавленных элементов
|
||
*/
|
||
ParaRun.prototype.AddText = function(sString, nPos)
|
||
{
|
||
var nCharPos = undefined !== nPos && null !== nPos && -1 !== nPos ? nPos : this.Content.length;
|
||
|
||
let oForm = this.GetParentForm();
|
||
var oTextForm = oForm ? oForm.GetTextFormPr() : null;
|
||
var nMax = oTextForm ? oTextForm.GetMaxCharacters() : 0;
|
||
|
||
if (this.IsMathRun())
|
||
{
|
||
for (var oIterator = sString.getUnicodeIterator(); oIterator.check(); oIterator.next())
|
||
{
|
||
var nCharCode = oIterator.value();
|
||
|
||
var oMathText = new CMathText();
|
||
oMathText.add(nCharCode);
|
||
this.AddToContent(nCharPos++, oMathText);
|
||
}
|
||
}
|
||
else if (nMax > 0)
|
||
{
|
||
var arrLetters = [], nLettersCount = 0;
|
||
for (var oIterator = sString.getUnicodeIterator(); oIterator.check(); oIterator.next())
|
||
{
|
||
var nCharCode = oIterator.value();
|
||
|
||
if (9 === nCharCode) // \t
|
||
continue;
|
||
else if (10 === nCharCode) // \n
|
||
continue;
|
||
else if (13 === nCharCode) // \r
|
||
continue;
|
||
else if (AscCommon.IsSpace(nCharCode)) // space
|
||
{
|
||
nLettersCount++;
|
||
arrLetters.push(new AscWord.CRunSpace(nCharCode));
|
||
}
|
||
else
|
||
{
|
||
nLettersCount++;
|
||
arrLetters.push(new AscWord.CRunText(nCharCode));
|
||
}
|
||
}
|
||
|
||
for (var nIndex = 0; nIndex < arrLetters.length; ++nIndex)
|
||
{
|
||
this.AddToContent(nCharPos++, arrLetters[nIndex], true);
|
||
}
|
||
|
||
oForm.TrimTextForm();
|
||
}
|
||
else
|
||
{
|
||
for (var oIterator = sString.getUnicodeIterator(); oIterator.check(); oIterator.next())
|
||
{
|
||
var nCharCode = oIterator.value();
|
||
|
||
if (9 === nCharCode) // \t
|
||
this.AddToContent(nCharPos++, new AscWord.CRunTab(), true);
|
||
else if (10 === nCharCode) // \n
|
||
this.AddToContent(nCharPos++, new AscWord.CRunBreak(AscWord.break_Line), true);
|
||
else if (13 === nCharCode) // \r
|
||
continue;
|
||
else if (AscCommon.IsSpace(nCharCode)) // space
|
||
this.AddToContent(nCharPos++, new AscWord.CRunSpace(nCharCode), true);
|
||
else
|
||
this.AddToContent(nCharPos++, new AscWord.CRunText(nCharCode), true);
|
||
}
|
||
}
|
||
return nCharPos;
|
||
};
|
||
/**
|
||
* Добавляем в конец рана заданную инструкцию для сложного поля
|
||
* @param {string} sString
|
||
* @param {number} [nPos=-1] если позиция не задана (или значение -1), то добавляем в конец
|
||
* @returns {AscWord.ParaInstrText[]}
|
||
*/
|
||
ParaRun.prototype.AddInstrText = function(sString, nPos)
|
||
{
|
||
let items = [];
|
||
var nCharPos = undefined !== nPos && null !== nPos && -1 !== nPos ? nPos : this.Content.length;
|
||
for (var oIterator = sString.getUnicodeIterator(); oIterator.check(); oIterator.next())
|
||
{
|
||
let instrText = new AscWord.ParaInstrText(oIterator.value());
|
||
this.AddToContent(nCharPos++, instrText);
|
||
items.push(instrText);
|
||
}
|
||
|
||
return items;
|
||
};
|
||
|
||
// Определим строку и отрезок текущей позиции
|
||
ParaRun.prototype.GetCurrentParaPos = function(align)
|
||
{
|
||
var Pos = this.State.ContentPos;
|
||
|
||
if (-1 === this.StartLine)
|
||
return new CParaPos(-1, -1, -1, -1);
|
||
|
||
var CurLine = 0;
|
||
var CurRange = 0;
|
||
|
||
var LinesCount = this.protected_GetLinesCount();
|
||
for (; CurLine < LinesCount; CurLine++)
|
||
{
|
||
var RangesCount = this.protected_GetRangesCount(CurLine);
|
||
for (CurRange = 0; CurRange < RangesCount; CurRange++)
|
||
{
|
||
var StartPos = this.protected_GetRangeStartPos(CurLine, CurRange);
|
||
var EndPos = this.protected_GetRangeEndPos(CurLine, CurRange);
|
||
|
||
if (((-1 === align) && (StartPos < Pos && Pos <= EndPos))
|
||
|| ((-1 !== align) && (StartPos <= Pos && Pos < EndPos)))
|
||
return new CParaPos((CurLine === 0 ? CurRange + this.StartRange : CurRange), CurLine + this.StartLine, 0, 0);
|
||
}
|
||
}
|
||
|
||
// Значит курсор стоит в самом конце, поэтому посылаем последний отрезок
|
||
if(this.Type == para_Math_Run && LinesCount > 1)
|
||
{
|
||
var Line = LinesCount - 1,
|
||
Range = this.protected_GetRangesCount(LinesCount - 1) - 1;
|
||
|
||
StartPos = this.protected_GetRangeStartPos(Line, Range);
|
||
EndPos = this.protected_GetRangeEndPos(Line, Range);
|
||
|
||
// учтем, что в одной строке в формуле может быть только один Range
|
||
while(StartPos == EndPos && Line > 0 && this.Content.length !== 0) // == this.Content.length, т.к. последний Range
|
||
{
|
||
Line--;
|
||
StartPos = this.protected_GetRangeStartPos(Line, Range);
|
||
EndPos = this.protected_GetRangeEndPos(Line, Range);
|
||
}
|
||
|
||
return new CParaPos((this.protected_GetRangesCount(Line) - 1), Line + this.StartLine, 0, 0 );
|
||
}
|
||
|
||
return new CParaPos((LinesCount <= 1 ? this.protected_GetRangesCount(0) - 1 + this.StartRange : this.protected_GetRangesCount(LinesCount - 1) - 1), LinesCount - 1 + this.StartLine, 0, 0 );
|
||
};
|
||
|
||
ParaRun.prototype.Get_ParaPosByContentPos = function(ContentPos, Depth)
|
||
{
|
||
if (this.StartRange < 0 || this.StartLine < 0)
|
||
return new CParaPos(0, 0, 0, 0);
|
||
|
||
var Pos = ContentPos.Get(Depth);
|
||
|
||
var CurLine = 0;
|
||
var CurRange = 0;
|
||
|
||
var LinesCount = this.protected_GetLinesCount();
|
||
if (LinesCount <= 0)
|
||
return new CParaPos(0, 0, 0, 0);
|
||
|
||
for (; CurLine < LinesCount; CurLine++)
|
||
{
|
||
var RangesCount = this.protected_GetRangesCount(CurLine);
|
||
for (CurRange = 0; CurRange < RangesCount; CurRange++)
|
||
{
|
||
var StartPos = this.protected_GetRangeStartPos(CurLine, CurRange);
|
||
var EndPos = this.protected_GetRangeEndPos(CurLine, CurRange);
|
||
|
||
var bUpdateMathRun = Pos == EndPos && StartPos == EndPos && EndPos == this.Content.length && this.Type == para_Math_Run; // для para_Run позиция может быть после последнего элемента (пример: Run, за ним идет мат объект)
|
||
if (Pos < EndPos && Pos >= StartPos || bUpdateMathRun)
|
||
return new CParaPos((CurLine === 0 ? CurRange + this.StartRange : CurRange), CurLine + this.StartLine, 0, 0);
|
||
}
|
||
}
|
||
|
||
return new CParaPos((LinesCount === 1 ? this.protected_GetRangesCount(0) - 1 + this.StartRange : this.protected_GetRangesCount(LinesCount - 1) - 1), LinesCount - 1 + this.StartLine, 0, 0);
|
||
};
|
||
|
||
ParaRun.prototype.recalculateCursorPosition = function(positionCalculator, isCurrent)
|
||
{
|
||
if (this.IsMathRun())
|
||
{
|
||
positionCalculator.handleMathRun(this, isCurrent, this.State.ContentPos);
|
||
return;
|
||
}
|
||
|
||
let rangePos = this.getRangePos(positionCalculator.line, positionCalculator.range);
|
||
let startPos = rangePos[0];
|
||
let endPos = rangePos[1];
|
||
for (let pos = startPos; pos < endPos; ++pos)
|
||
{
|
||
let item = this.private_CheckInstrText(this.Content[pos]);
|
||
let isCurPos = isCurrent && pos === this.State.ContentPos;
|
||
let isNearNoteRef = isCurPos ? this.IsCurPosNearFootEndnoteReference() : false;
|
||
positionCalculator.handleRunElement(item, this, isCurPos, isNearNoteRef, pos);
|
||
}
|
||
|
||
if (isCurrent && endPos === this.State.ContentPos)
|
||
positionCalculator.setNextCurrent(this, this.Content.length && endPos === this.Content.length ? this.Content[this.Content.length - 1] : null);
|
||
}
|
||
/**
|
||
* Get auto color against current background color
|
||
* @returns {AscWord.CDocumentColor}
|
||
*/
|
||
ParaRun.prototype.getAutoColor = function()
|
||
{
|
||
let paragraph = this.GetParagraph();
|
||
if (!paragraph)
|
||
return AscWord.BLACK_COLOR;
|
||
|
||
let textPr = this.getCompiledPr();
|
||
if (textPr.FontRef && textPr.FontRef.Color)
|
||
{
|
||
textPr.FontRef.Color.check(paragraph.getTheme(), paragraph.getColorMap());
|
||
let RGBA = textPr.FontRef.Color.RGBA;
|
||
return new AscWord.CDocumentColor(RGBA.R, RGBA.G, RGBA.B, RGBA.A);
|
||
}
|
||
|
||
let bgColor = null;
|
||
if (textPr.Shd && !textPr.Shd.IsNil())
|
||
{
|
||
bgColor = textPr.Shd.GetSimpleColor(paragraph.getTheme(), paragraph.getColorMap());
|
||
}
|
||
else
|
||
{
|
||
let paraPr = paragraph.getCompiledPr().ParaPr;
|
||
if (paraPr.Shd && !paraPr.Shd.IsNil())
|
||
{
|
||
if (paraPr.Shd.Unifill)
|
||
{
|
||
paraPr.Shd.Unifill.check(this.Paragraph.Get_Theme(), this.Paragraph.Get_ColorMap());
|
||
let RGBA = paraPr.Shd.Unifill.getRGBAColor();
|
||
bgColor = new AscWord.CDocumentColor(RGBA.R, RGBA.G, RGBA.B, RGBA.A);
|
||
}
|
||
else
|
||
{
|
||
bgColor = paraPr.Shd.Color;
|
||
}
|
||
}
|
||
else if (paragraph.GetParent())
|
||
{
|
||
bgColor = paragraph.GetParent().Get_TextBackGroundColor();
|
||
}
|
||
}
|
||
|
||
return bgColor && !bgColor.isBlackAutoColor() ? AscWord.WHITE_COLOR : AscWord.BLACK_COLOR;
|
||
};
|
||
/**
|
||
* Проверяем являются ли заданные изменения заданного рана простыми (например, последовательное удаление или набор текста)
|
||
* @param arrChanges
|
||
* @param [nStart=0] {number}
|
||
* @param [nEnd=arrChanges.length - 1] {number}
|
||
* @returns {?CParaPos}
|
||
*/
|
||
ParaRun.prototype.GetSimpleChangesRange = function(arrChanges, nStart, nEnd)
|
||
{
|
||
if (this.IsMathRun())
|
||
return null;
|
||
|
||
var oParaPos = null;
|
||
|
||
var _nStart = undefined !== nStart ? nStart : 0;
|
||
var _nEnd = undefined !== nEnd ? nEnd : arrChanges.length - 1;
|
||
|
||
var arrAddItems = [], arrRemItems = [];
|
||
for (var nIndex = _nStart; nIndex <= _nEnd; ++nIndex)
|
||
{
|
||
var oChange = arrChanges[nIndex];
|
||
|
||
if (oChange.IsDescriptionChange())
|
||
continue;
|
||
|
||
if (!oChange || !oChange.IsContentChange() || 1 !== oChange.GetItemsCount())
|
||
return null;
|
||
|
||
var nType = oChange.GetType();
|
||
if (AscDFH.historyitem_ParaRun_AddItem !== nType && AscDFH.historyitem_ParaRun_RemoveItem !== nType)
|
||
return null;
|
||
|
||
var nItemsCount = oChange.GetItemsCount();
|
||
for (var nItemIndex = 0; nItemIndex < nItemsCount; ++nItemIndex)
|
||
{
|
||
var oItem = oChange.GetItem(nItemIndex);
|
||
|
||
if (!oItem)
|
||
return null;
|
||
|
||
if (AscDFH.historyitem_ParaRun_AddItem === nType)
|
||
arrAddItems.push(oItem);
|
||
else
|
||
arrRemItems.push(oItem);
|
||
|
||
// Добавление/удаление картинок может изменить размер строки. Добавление/удаление переноса строки/страницы/колонки
|
||
// нельзя обсчитывать функцией Recalculate_Fast. Добавление и удаление разметок сложных полей тоже нельзя
|
||
// обсчитывать в быстром пересчете.
|
||
// TODO: Но на самом деле стоило бы сделать нормальную проверку на высоту строки в функции Recalculate_Fast
|
||
var nItemType = oItem.Type;
|
||
if (para_Drawing === nItemType
|
||
|| para_NewLine === nItemType
|
||
|| para_FootnoteRef === nItemType
|
||
|| para_FootnoteReference === nItemType
|
||
|| para_FieldChar === nItemType
|
||
|| para_InstrText === nItemType
|
||
|| para_EndnoteRef === nItemType
|
||
|| para_EndnoteReference === nItemType
|
||
|| para_Tab === nItemType)
|
||
return null;
|
||
|
||
var nChangePos = oChange.GetPos(nItemIndex);
|
||
// Проверяем, что все изменения произошли в одном и том же отрезке
|
||
var oCurParaPos = this.Get_SimpleChanges_ParaPos(nType, nChangePos);
|
||
if (!oCurParaPos)
|
||
return null;
|
||
|
||
if (!oParaPos)
|
||
oParaPos = oCurParaPos;
|
||
else if (oParaPos.Line !== oCurParaPos.Line
|
||
|| oParaPos.Range !== oCurParaPos.Range
|
||
|| oParaPos.Page !== oCurParaPos.Page)
|
||
return null;
|
||
}
|
||
}
|
||
|
||
// Сравниваем, нужно ли использовать метрики данного Run до и после изменений
|
||
// Если значение не совпало, тогда метрики поменялись, значит пересчитывать надо полноценно
|
||
if (this.private_IsChangedLineMetrics(arrAddItems, arrRemItems))
|
||
return null;
|
||
|
||
return oParaPos;
|
||
};
|
||
ParaRun.prototype.private_IsChangedLineMetrics = function(arrAddItems, arrRemItems)
|
||
{
|
||
var isUseMetricsBefore = false;
|
||
var isUseMetricsAfter = false;
|
||
|
||
for (var nPos = 0, nContentCount = this.Content.length; nPos < nContentCount; ++nPos)
|
||
{
|
||
var oItem = this.Content[nPos];
|
||
var nItemType = oItem.Type;
|
||
|
||
if (para_Sym === nItemType
|
||
|| para_Text === nItemType
|
||
|| para_PageNum === nItemType
|
||
|| para_PageCount === nItemType
|
||
|| para_FootnoteReference === nItemType
|
||
|| para_FootnoteRef === nItemType
|
||
|| para_EndnoteReference === nItemType
|
||
|| para_EndnoteRef === nItemType
|
||
|| para_Separator === nItemType
|
||
|| para_ContinuationSeparator === nItemType
|
||
|| para_Math_Text === nItemType
|
||
|| para_Math_Ampersand === nItemType
|
||
|| para_Math_Placeholder === nItemType
|
||
|| para_Math_BreakOperator === nItemType
|
||
|| (para_Drawing === nItemType && (true === oItem.Is_Inline() || true === this.GetParagraph().Parent.Is_DrawingShape()))
|
||
|| (para_FieldChar === nItemType && oItem.IsVisual()))
|
||
{
|
||
|
||
var isAdd = false;
|
||
for (var nIndex = 0, nCount = arrAddItems.length; nIndex < nCount; ++nIndex)
|
||
{
|
||
if (oItem === arrAddItems[nIndex])
|
||
{
|
||
isAdd = true;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (!isAdd)
|
||
isUseMetricsBefore = true;
|
||
|
||
isUseMetricsAfter = true;
|
||
}
|
||
|
||
if (isUseMetricsAfter && isUseMetricsBefore)
|
||
break;
|
||
}
|
||
|
||
if (!isUseMetricsBefore)
|
||
{
|
||
for (var nIndex = 0, nCount = arrRemItems.length; nIndex < nCount; ++nIndex)
|
||
{
|
||
var oItem = arrRemItems[nIndex];
|
||
var nItemType = oItem.Type;
|
||
|
||
if (para_Sym === nItemType
|
||
|| para_Text === nItemType
|
||
|| para_PageNum === nItemType
|
||
|| para_PageCount === nItemType
|
||
|| para_FootnoteReference === nItemType
|
||
|| para_FootnoteRef === nItemType
|
||
|| para_EndnoteReference === nItemType
|
||
|| para_EndnoteRef === nItemType
|
||
|| para_Separator === nItemType
|
||
|| para_ContinuationSeparator === nItemType
|
||
|| para_Math_Text === nItemType
|
||
|| para_Math_Ampersand === nItemType
|
||
|| para_Math_Placeholder === nItemType
|
||
|| para_Math_BreakOperator === nItemType
|
||
|| (para_Drawing === nItemType && (true === oItem.Is_Inline() || true === this.GetParagraph().Parent.Is_DrawingShape()))
|
||
|| (para_FieldChar === nItemType && oItem.IsVisual()))
|
||
{
|
||
isUseMetricsBefore = true;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
return (isUseMetricsBefore !== isUseMetricsAfter);
|
||
};
|
||
/**
|
||
* Проверяем произошло ли простое изменение параграфа, сейчас главное, чтобы это было не добавлениe/удаление картинки
|
||
* или ссылки на сноску или разметки сложного поля, или изменение типа реценизрования для рана со знаком конца
|
||
* параграфа. На вход приходит либо массив изменений, либо одно изменение
|
||
* (можно не в массиве).
|
||
* @param {[CChangesBase] | CChangesBase} arrChanges
|
||
* @returns {boolean}
|
||
*/
|
||
ParaRun.prototype.IsParagraphSimpleChanges = function(arrChanges)
|
||
{
|
||
var _arrChanges = arrChanges;
|
||
if (!arrChanges.length)
|
||
_arrChanges = [arrChanges];
|
||
|
||
for (var nChangesIndex = 0, nChangesCount = _arrChanges.length; nChangesIndex < nChangesCount; ++nChangesIndex)
|
||
{
|
||
var oChange = _arrChanges[nChangesIndex];
|
||
var nType = oChange.GetType();
|
||
|
||
if (AscDFH.historyitem_ParaRun_AddItem === nType || AscDFH.historyitem_ParaRun_RemoveItem === nType)
|
||
{
|
||
for (var nItemIndex = 0, nItemsCount = oChange.GetItemsCount(); nItemIndex < nItemsCount; ++nItemIndex)
|
||
{
|
||
var oItem = oChange.GetItem(nItemIndex);
|
||
if (para_Drawing === oItem.Type
|
||
|| para_FootnoteReference === oItem.Type
|
||
|| para_FieldChar === oItem.Type
|
||
|| para_InstrText === oItem.Type
|
||
|| para_EndnoteReference === oItem.Type)
|
||
return false;
|
||
}
|
||
}
|
||
else if (AscDFH.historyitem_ParaRun_ReviewType === nType && this.GetParaEnd())
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return true;
|
||
};
|
||
/**
|
||
* Проверяем, подходит ли содержимое данного рана быстрого пересчета
|
||
* @returns {boolean}
|
||
*/
|
||
ParaRun.prototype.IsContentSuitableForParagraphSimpleChanges = function()
|
||
{
|
||
for (var nPos = 0, nCount = this.Content.length; nPos < nCount; ++nPos)
|
||
{
|
||
var nItemType = this.Content[nPos].Type;
|
||
if (1 !== g_oSRCFPSC[nItemType])
|
||
return false;
|
||
}
|
||
return true;
|
||
};
|
||
|
||
// Возвращаем строку и отрезок, в котором произошли простейшие изменения
|
||
ParaRun.prototype.Get_SimpleChanges_ParaPos = function(Type, Pos)
|
||
{
|
||
if (AscDFH.historyitem_ParaRun_AddItem !== Type && AscDFH.historyitem_ParaRun_RemoveItem !== Type)
|
||
return null;
|
||
|
||
if (Pos < this.protected_GetRangeStartPos(0, 0))
|
||
{
|
||
// Если отрезок остается пустым, тогда надо все заново пересчитывать
|
||
if (this.protected_GetRangeStartPos(0, 0) === this.protected_GetRangeEndPos(0, 0))
|
||
return null;
|
||
|
||
return new CParaPos(this.StartRange, this.StartLine, 0, 0);
|
||
}
|
||
else
|
||
{
|
||
for (let curLine = 0, lineCount = this.protected_GetLinesCount(); curLine < lineCount; ++curLine)
|
||
{
|
||
for (let curRange = 0, rangeCount = this.protected_GetRangesCount(curLine); curRange < rangeCount; ++curRange)
|
||
{
|
||
let rangeStartPos = this.protected_GetRangeStartPos(curLine, curRange);
|
||
let rangeEndPos = this.protected_GetRangeEndPos(curLine, curRange);
|
||
|
||
if ((rangeStartPos <= Pos && Pos < rangeEndPos)
|
||
|| (Pos >= rangeEndPos && curLine === lineCount - 1 && curRange === rangeCount - 1))
|
||
{
|
||
// Если отрезок остается пустым, тогда надо все заново пересчитывать
|
||
if (rangeStartPos === rangeEndPos)
|
||
return null;
|
||
|
||
return new CParaPos((curLine === 0 ? curRange + this.StartRange : curRange), curLine + this.StartLine, 0, 0);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return null;
|
||
};
|
||
|
||
ParaRun.prototype.Split = function (ContentPos, Depth)
|
||
{
|
||
var CurPos = ContentPos.Get(Depth);
|
||
return this.Split2( CurPos );
|
||
};
|
||
|
||
ParaRun.prototype.Split2 = function(CurPos, Parent, ParentPos)
|
||
{
|
||
// Данная функция специальная, расчитана на то, что в параграфе данный ран делится в заданной позиции на 2 рана
|
||
// Поэтому ВСЕ метки (поиск, орфографии, позиций и остального) обновляются именно здесь, а не через
|
||
// стандартный механизм AddToContent/RemoveFromContent. Чтобы все работало правильно, делаем в следующей
|
||
// последовательности:
|
||
// 1 Создаем новый ран и добавляем туда КОПИИ элементов после точки разделения
|
||
// 2 Переносим все метки, попадающие после точки разделения, в новый ран
|
||
// 3 Удаляем из текущего рана элементы после точки разделения
|
||
|
||
// Если задается Parent и ParentPos, тогда ран автоматически добавляется в родительский класс
|
||
var UpdateParent = (undefined !== Parent && undefined !== ParentPos && this === Parent.Content[ParentPos] ? true : false);
|
||
var UpdateSelection = (true === UpdateParent && true === Parent.IsSelectionUse() && true === this.IsSelectionUse() ? true : false);
|
||
|
||
// Создаем новый ран
|
||
var bMathRun = this.Type == para_Math_Run;
|
||
var NewRun = new ParaRun(this.Paragraph, bMathRun);
|
||
|
||
AscCommon.History.Add(new CChangesRunOnStartSplit(this, CurPos, NewRun));
|
||
AscCommon.CollaborativeEditing.OnStart_SplitRun(this, CurPos);
|
||
|
||
// Копируем настройки
|
||
NewRun.SetPr(this.Pr.Copy(true));
|
||
|
||
if ((0 === CurPos || this.Content.length === CurPos)
|
||
&& this.Paragraph
|
||
&& this.Paragraph.LogicDocument
|
||
&& this.Paragraph.bFromDocument)
|
||
{
|
||
var oStyles = this.Paragraph.LogicDocument.GetStyles();
|
||
if (this.GetRStyle() === oStyles.GetDefaultFootnoteReference() || this.GetRStyle() === oStyles.GetDefaultEndnoteReference())
|
||
{
|
||
if (0 === CurPos)
|
||
{
|
||
this.SetRStyle(undefined);
|
||
this.SetVertAlign(undefined);
|
||
}
|
||
else
|
||
{
|
||
NewRun.SetRStyle(undefined);
|
||
NewRun.SetVertAlign(undefined);
|
||
}
|
||
}
|
||
}
|
||
|
||
NewRun.SetReviewTypeWithInfo(this.GetReviewType(), this.ReviewInfo ? this.ReviewInfo.Copy() : undefined);
|
||
|
||
NewRun.CollPrChangeMine = this.CollPrChangeMine;
|
||
NewRun.CollPrChangeColor = this.CollPrChangeColor;
|
||
|
||
if(bMathRun)
|
||
NewRun.Set_MathPr(this.MathPrp.Copy());
|
||
|
||
// TODO: Как только избавимся от para_End переделать тут
|
||
// Проверим, если наш ран содержит para_End, тогда мы должны para_End переметить в правый ран
|
||
|
||
var CheckEndPos = -1;
|
||
var CheckEndPos2 = Math.min( CurPos, this.Content.length );
|
||
for ( var Pos = 0; Pos < CheckEndPos2; Pos++ )
|
||
{
|
||
if ( para_End === this.Content[Pos].Type )
|
||
{
|
||
CheckEndPos = Pos;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if ( -1 !== CheckEndPos )
|
||
CurPos = CheckEndPos;
|
||
|
||
var ParentOldSelectionStartPos, ParentOldSelectionEndPos, OldSelectionStartPos, OldSelectionEndPos;
|
||
if (true === UpdateSelection)
|
||
{
|
||
ParentOldSelectionStartPos = Parent.Selection.StartPos;
|
||
ParentOldSelectionEndPos = Parent.Selection.EndPos;
|
||
OldSelectionStartPos = this.Selection.StartPos;
|
||
OldSelectionEndPos = this.Selection.EndPos;
|
||
}
|
||
|
||
// ВСЕГДА копируем элементы, для корректной работы не надо переносить имеющиеся элементы в новый ран
|
||
for (var nIndex = CurPos, nNewIndex = 0, nCount = this.Content.length; nIndex < nCount; ++nIndex, ++nNewIndex)
|
||
{
|
||
var oNewItem = this.Content[nIndex].Copy();
|
||
NewRun.AddToContent(nNewIndex, oNewItem, false);
|
||
if (para_FieldChar === this.Content[nIndex].Type)
|
||
{
|
||
var oComplexField = this.Content[nIndex].GetComplexField();
|
||
if (oComplexField)
|
||
oComplexField.ReplaceChar(oNewItem);
|
||
}
|
||
}
|
||
|
||
if (UpdateParent)
|
||
{
|
||
Parent.Add_ToContent(ParentPos + 1, NewRun);
|
||
|
||
// Обновим массив NearPosArray
|
||
for (var Index = 0, Count = this.NearPosArray.length; Index < Count; Index++)
|
||
{
|
||
var RunNearPos = this.NearPosArray[Index];
|
||
var ContentPos = RunNearPos.NearPos.ContentPos;
|
||
var Depth = RunNearPos.Depth;
|
||
|
||
var Pos = ContentPos.Get(Depth);
|
||
|
||
if (Pos >= CurPos)
|
||
{
|
||
ContentPos.Update2(Pos - CurPos, Depth);
|
||
ContentPos.Update2(ParentPos + 1, Depth - 1);
|
||
|
||
this.NearPosArray.splice(Index, 1);
|
||
Count--;
|
||
Index--;
|
||
|
||
NewRun.NearPosArray.push(RunNearPos);
|
||
|
||
if (this.Paragraph)
|
||
{
|
||
for (var ParaIndex = 0, ParaCount = this.Paragraph.NearPosArray.length; ParaIndex < ParaCount; ParaIndex++)
|
||
{
|
||
var ParaNearPos = this.Paragraph.NearPosArray[ParaIndex];
|
||
if (ParaNearPos.Classes[ParaNearPos.Classes.length - 1] === this)
|
||
ParaNearPos.Classes[ParaNearPos.Classes.length - 1] = NewRun;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Обновляем позиции в поиске
|
||
for (var nIndex = 0, nSearchMarksCount = this.SearchMarks.length; nIndex < nSearchMarksCount; ++nIndex)
|
||
{
|
||
var oMark = this.SearchMarks[nIndex];
|
||
var oContentPos = oMark.Start ? oMark.SearchResult.StartPos : oMark.SearchResult.EndPos;
|
||
var nDepth = oMark.Depth;
|
||
|
||
if (oContentPos.Get(nDepth) > CurPos || (oContentPos.Get(nDepth) === CurPos && oMark.Start))
|
||
{
|
||
this.SearchMarks.splice(nIndex, 1);
|
||
NewRun.SearchMarks.splice(NewRun.SearchMarks.length, 0, oMark);
|
||
oContentPos.Data[nDepth] -= CurPos;
|
||
oContentPos.Data[nDepth - 1]++;
|
||
|
||
if (oMark.Start)
|
||
oMark.SearchResult.ClassesS[oMark.SearchResult.ClassesS.length - 1] = NewRun;
|
||
else
|
||
oMark.SearchResult.ClassesE[oMark.SearchResult.ClassesE.length - 1] = NewRun;
|
||
|
||
nSearchMarksCount--;
|
||
nIndex--;
|
||
}
|
||
}
|
||
}
|
||
|
||
this.private_UpdateMarksOnSplit(CurPos, NewRun);
|
||
|
||
this.RemoveFromContent(CurPos, this.Content.length - CurPos, true);
|
||
|
||
if (true === UpdateSelection)
|
||
{
|
||
if (ParentOldSelectionStartPos <= ParentPos && ParentPos <= ParentOldSelectionEndPos)
|
||
Parent.Selection.EndPos = ParentOldSelectionEndPos + 1;
|
||
else if (ParentOldSelectionEndPos <= ParentPos && ParentPos <= ParentOldSelectionStartPos)
|
||
Parent.Selection.StartPos = ParentOldSelectionStartPos + 1;
|
||
|
||
if (OldSelectionStartPos <= CurPos && CurPos <= OldSelectionEndPos)
|
||
{
|
||
this.Selection.EndPos = this.Content.length;
|
||
NewRun.Selection.Use = true;
|
||
NewRun.Selection.StartPos = 0;
|
||
NewRun.Selection.EndPos = OldSelectionEndPos - CurPos;
|
||
}
|
||
else if (OldSelectionEndPos <= CurPos && CurPos <= OldSelectionStartPos)
|
||
{
|
||
this.Selection.StartPos = this.Content.length;
|
||
NewRun.Selection.Use = true;
|
||
NewRun.Selection.EndPos = 0;
|
||
NewRun.Selection.StartPos = OldSelectionStartPos - CurPos;
|
||
}
|
||
}
|
||
|
||
AscCommon.History.Add(new CChangesRunOnEndSplit(this, CurPos, NewRun));
|
||
AscCommon.CollaborativeEditing.OnEnd_SplitRun(NewRun);
|
||
return NewRun;
|
||
};
|
||
ParaRun.prototype.SplitNoDuplicate = function(oContentPos, nDepth, oNewParagraph)
|
||
{
|
||
if (this.IsSolid())
|
||
return;
|
||
|
||
var oNewRun = this.Split(oContentPos, nDepth);
|
||
if (!oNewRun)
|
||
return;
|
||
|
||
var oLogicDocument = this.GetLogicDocument();
|
||
if (oLogicDocument && oNewRun.GetRStyle() === oLogicDocument.GetStyles().GetDefaultHyperlink())
|
||
oNewRun.SetRStyle(null);
|
||
|
||
oNewParagraph.AddToContent(oNewParagraph.Content.length, oNewRun, false);
|
||
};
|
||
ParaRun.prototype.SplitForSpreadCollaborativeMark = function(CurPos) // переносим сами объекты, а не копии
|
||
{
|
||
var bMathRun = this.Type == para_Math_Run;
|
||
var NewRun = new ParaRun(this.Paragraph, false);
|
||
|
||
AscCommon.History.Add(new CChangesRunOnStartSplit(this, CurPos, NewRun));
|
||
AscCommon.CollaborativeEditing.OnStart_SplitRun(this, CurPos);
|
||
|
||
NewRun.SetReviewTypeWithInfo(this.GetReviewType(), this.ReviewInfo ? this.ReviewInfo.Copy() : undefined);
|
||
if(bMathRun)
|
||
NewRun.Set_MathPr(this.MathPrp.Copy());
|
||
|
||
// Копируем настройки
|
||
NewRun.SetPr(this.Pr.Copy(true));
|
||
|
||
for (let nIndex = CurPos, nNewIndex = 0, nCount = this.Content.length; nIndex < nCount; ++nIndex, ++nNewIndex)
|
||
{
|
||
let oNewItem = this.Content[nIndex];
|
||
NewRun.AddToContent(nNewIndex, oNewItem, false);
|
||
if (para_FieldChar === this.Content[nIndex].Type)
|
||
{
|
||
let oComplexField = this.Content[nIndex].GetComplexField();
|
||
if (oComplexField)
|
||
oComplexField.ReplaceChar(oNewItem);
|
||
}
|
||
}
|
||
|
||
this.RemoveFromContent(CurPos, this.Content.length - CurPos, true);
|
||
|
||
AscCommon.History.Add(new CChangesRunOnEndSplit(this, CurPos, NewRun));
|
||
AscCommon.CollaborativeEditing.OnEnd_SplitRun(NewRun);
|
||
|
||
return NewRun;
|
||
};
|
||
ParaRun.prototype.GetCollaborativeMarks = function ()
|
||
{
|
||
return this.CollaborativeMarks.Ranges;
|
||
}
|
||
ParaRun.prototype.Check_NearestPos = function(ParaNearPos, Depth)
|
||
{
|
||
var RunNearPos = new CParagraphElementNearPos();
|
||
RunNearPos.NearPos = ParaNearPos.NearPos;
|
||
RunNearPos.Depth = Depth;
|
||
|
||
this.NearPosArray.push( RunNearPos );
|
||
ParaNearPos.Classes.push( this );
|
||
};
|
||
|
||
ParaRun.prototype.Get_DrawingObjectRun = function(Id)
|
||
{
|
||
var ContentLen = this.Content.length;
|
||
for ( var CurPos = 0; CurPos < ContentLen; CurPos++ )
|
||
{
|
||
var Element = this.Content[CurPos];
|
||
|
||
if ( para_Drawing === Element.Type && Id === Element.Get_Id() )
|
||
return this;
|
||
}
|
||
|
||
return null;
|
||
};
|
||
|
||
ParaRun.prototype.Get_DrawingObjectContentPos = function(Id, ContentPos, Depth)
|
||
{
|
||
var ContentLen = this.Content.length;
|
||
for ( var CurPos = 0; CurPos < ContentLen; CurPos++ )
|
||
{
|
||
var Element = this.Content[CurPos];
|
||
|
||
if ( para_Drawing === Element.Type && Id === Element.Get_Id() )
|
||
{
|
||
ContentPos.Update( CurPos, Depth );
|
||
return true;
|
||
}
|
||
}
|
||
|
||
return false;
|
||
};
|
||
|
||
ParaRun.prototype.GetRunByElement = function(oRunElement)
|
||
{
|
||
for (var nCurPos = 0, nLen = this.Content.length; nCurPos < nLen; ++nCurPos)
|
||
{
|
||
if (this.Content[nCurPos] === oRunElement)
|
||
return {Run : this, Pos : nCurPos};
|
||
}
|
||
|
||
return null;
|
||
};
|
||
|
||
ParaRun.prototype.Get_DrawingObjectSimplePos = function(Id)
|
||
{
|
||
var ContentLen = this.Content.length;
|
||
for (var CurPos = 0; CurPos < ContentLen; CurPos++)
|
||
{
|
||
var Element = this.Content[CurPos];
|
||
if (para_Drawing === Element.Type && Id === Element.Get_Id())
|
||
return CurPos;
|
||
}
|
||
|
||
return -1;
|
||
};
|
||
|
||
ParaRun.prototype.Remove_DrawingObject = function(Id)
|
||
{
|
||
var ContentLen = this.Content.length;
|
||
for ( var CurPos = 0; CurPos < ContentLen; CurPos++ )
|
||
{
|
||
var Element = this.Content[CurPos];
|
||
|
||
if ( para_Drawing === Element.Type && Id === Element.Get_Id() )
|
||
{
|
||
var TrackRevisions = null;
|
||
if (this.Paragraph && this.Paragraph.LogicDocument && this.Paragraph.bFromDocument)
|
||
TrackRevisions = this.Paragraph.LogicDocument.IsTrackRevisions();
|
||
|
||
if (true === TrackRevisions)
|
||
{
|
||
var ReviewType = this.GetReviewType();
|
||
if (reviewtype_Common === ReviewType)
|
||
{
|
||
// Разбиваем ран на две части
|
||
var StartPos = CurPos;
|
||
var EndPos = CurPos + 1;
|
||
|
||
var Parent = this.Get_Parent();
|
||
var RunPos = this.private_GetPosInParent(Parent);
|
||
|
||
if (-1 !== RunPos && Parent)
|
||
{
|
||
var DeletedRun = null;
|
||
if (StartPos <= 0 && EndPos >= this.Content.length)
|
||
DeletedRun = this;
|
||
else if (StartPos <= 0)
|
||
{
|
||
this.Split2(EndPos, Parent, RunPos);
|
||
DeletedRun = this;
|
||
}
|
||
else if (EndPos >= this.Content.length)
|
||
{
|
||
DeletedRun = this.Split2(StartPos, Parent, RunPos);
|
||
}
|
||
else
|
||
{
|
||
this.Split2(EndPos, Parent, RunPos);
|
||
DeletedRun = this.Split2(StartPos, Parent, RunPos);
|
||
}
|
||
|
||
DeletedRun.SetReviewType(reviewtype_Remove);
|
||
}
|
||
}
|
||
else if (reviewtype_Add === ReviewType)
|
||
{
|
||
this.Remove_FromContent(CurPos, 1, true);
|
||
}
|
||
else if (reviewtype_Remove === ReviewType)
|
||
{
|
||
// Ничего не делаем
|
||
}
|
||
}
|
||
else
|
||
{
|
||
this.Remove_FromContent(CurPos, 1, true);
|
||
}
|
||
|
||
return;
|
||
}
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.Get_Layout = function(DrawingLayout, UseContentPos, ContentPos, Depth)
|
||
{
|
||
var CurLine = DrawingLayout.Line - this.StartLine;
|
||
var CurRange = ( 0 === CurLine ? DrawingLayout.Range - this.StartRange : DrawingLayout.Range );
|
||
|
||
var StartPos = this.protected_GetRangeStartPos(CurLine, CurRange);
|
||
var EndPos = this.protected_GetRangeEndPos(CurLine, CurRange);
|
||
|
||
var CurContentPos = ( true === UseContentPos ? ContentPos.Get(Depth) : -1 );
|
||
|
||
var CurPos = StartPos;
|
||
for ( ; CurPos < EndPos; CurPos++ )
|
||
{
|
||
if ( CurContentPos === CurPos )
|
||
break;
|
||
|
||
var Item = this.Content[CurPos];
|
||
var ItemType = Item.Type;
|
||
var WidthVisible = Item.GetWidthVisible();
|
||
|
||
switch ( ItemType )
|
||
{
|
||
case para_Text:
|
||
case para_Space:
|
||
case para_PageNum:
|
||
case para_PageCount:
|
||
{
|
||
DrawingLayout.LastW = WidthVisible;
|
||
|
||
break;
|
||
}
|
||
case para_Drawing:
|
||
{
|
||
if ( true === Item.Is_Inline() || true === DrawingLayout.Paragraph.Parent.Is_DrawingShape() )
|
||
{
|
||
DrawingLayout.LastW = WidthVisible;
|
||
}
|
||
|
||
break;
|
||
}
|
||
}
|
||
|
||
DrawingLayout.X += WidthVisible;
|
||
}
|
||
|
||
if (CurContentPos === CurPos)
|
||
DrawingLayout.Layout = true;
|
||
};
|
||
|
||
ParaRun.prototype.GetNextRunElements = function(oRunElements, isUseContentPos, nDepth)
|
||
{
|
||
if (true === isUseContentPos)
|
||
oRunElements.SetStartClass(this.GetParent());
|
||
|
||
var nStartPos = true === isUseContentPos ? oRunElements.ContentPos.Get(nDepth) : 0;
|
||
|
||
for (var nCurPos = nStartPos, nCount = this.Content.length; nCurPos < nCount; ++nCurPos)
|
||
{
|
||
if (oRunElements.IsEnoughElements() || this.IsEmpty())
|
||
return;
|
||
|
||
oRunElements.UpdatePos(nCurPos, nDepth);
|
||
oRunElements.Add(this.Content[nCurPos], this);
|
||
}
|
||
};
|
||
ParaRun.prototype.GetPrevRunElements = function(oRunElements, isUseContentPos, nDepth)
|
||
{
|
||
if (true === isUseContentPos)
|
||
oRunElements.SetStartClass(this.GetParent());
|
||
|
||
var nStartPos = true === isUseContentPos ? oRunElements.ContentPos.Get(nDepth) - 1 : this.Content.length - 1;
|
||
|
||
for (var nCurPos = nStartPos; nCurPos >= 0; --nCurPos)
|
||
{
|
||
if (oRunElements.IsEnoughElements() || this.IsEmpty())
|
||
return;
|
||
|
||
oRunElements.UpdatePos(nCurPos, nDepth);
|
||
oRunElements.Add(this.Content[nCurPos], this);
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.CollectDocumentStatistics = function(ParaStats)
|
||
{
|
||
var Count = this.Content.length;
|
||
for (var Index = 0; Index < Count; Index++)
|
||
{
|
||
var Item = this.Content[Index];
|
||
var ItemType = Item.Type;
|
||
|
||
var bSymbol = false;
|
||
var bSpace = false;
|
||
var bNewWord = false;
|
||
|
||
if ((para_Text === ItemType && false === Item.IsNBSP()) || (para_PageNum === ItemType || para_PageCount === ItemType))
|
||
{
|
||
if (false === ParaStats.Word)
|
||
bNewWord = true;
|
||
|
||
bSymbol = true;
|
||
bSpace = false;
|
||
|
||
ParaStats.Word = true;
|
||
ParaStats.EmptyParagraph = false;
|
||
}
|
||
else if ((para_Text === ItemType && true === Item.IsNBSP()) || para_Space === ItemType || para_Tab === ItemType)
|
||
{
|
||
bSymbol = true;
|
||
bSpace = true;
|
||
|
||
ParaStats.Word = false;
|
||
}
|
||
|
||
if (true === bSymbol)
|
||
ParaStats.Stats.Add_Symbol(bSpace);
|
||
|
||
if (true === bNewWord)
|
||
ParaStats.Stats.Add_Word();
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.Create_FontMap = function(Map)
|
||
{
|
||
// для Math_Para_Pun argSize учитывается, когда мержатся текстовые настройки в Internal_Compile_Pr()
|
||
if ( undefined !== this.Paragraph && null !== this.Paragraph )
|
||
{
|
||
var TextPr;
|
||
var FontSize, FontSizeCS;
|
||
if(this.Type === para_Math_Run)
|
||
{
|
||
TextPr = this.Get_CompiledPr(false);
|
||
|
||
FontSize = TextPr.FontSize;
|
||
FontSizeCS = TextPr.FontSizeCS;
|
||
|
||
if(null !== this.Parent && undefined !== this.Parent && null !== this.Parent.ParaMath && undefined !== this.Parent.ParaMath)
|
||
{
|
||
TextPr.FontSize = this.Math_GetRealFontSize(TextPr.FontSize);
|
||
TextPr.FontSizeCS = this.Math_GetRealFontSize(TextPr.FontSizeCS);
|
||
}
|
||
}
|
||
else
|
||
TextPr = this.Get_CompiledPr(false);
|
||
|
||
TextPr.Document_CreateFontMap(Map, this.Paragraph.Get_Theme().themeElements.fontScheme);
|
||
var Count = this.Content.length;
|
||
for (var Index = 0; Index < Count; Index++)
|
||
{
|
||
var Item = this.Content[Index];
|
||
|
||
if (para_Drawing === Item.Type)
|
||
Item.documentCreateFontMap(Map);
|
||
else if (para_FootnoteReference === Item.Type || para_EndnoteReference === Item.Type)
|
||
Item.CreateDocumentFontMap(Map);
|
||
}
|
||
|
||
if(this.Type === para_Math_Run)
|
||
{
|
||
TextPr.FontSize = FontSize;
|
||
TextPr.FontSizeCS = FontSizeCS;
|
||
}
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.Get_AllFontNames = function(AllFonts)
|
||
{
|
||
this.Pr.Document_Get_AllFontNames(AllFonts);
|
||
|
||
var Count = this.Content.length;
|
||
for (var Index = 0; Index < Count; Index++)
|
||
{
|
||
var Item = this.Content[Index];
|
||
|
||
if (para_Drawing === Item.Type)
|
||
Item.documentGetAllFontNames(AllFonts);
|
||
else if (para_FootnoteReference === Item.Type || para_EndnoteReference === Item.Type)
|
||
Item.GetAllFontNames(AllFonts);
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.GetSelectedText = function(bAll, bClearText, oPr)
|
||
{
|
||
var StartPos = 0;
|
||
var EndPos = 0;
|
||
|
||
if ( true === bAll )
|
||
{
|
||
StartPos = 0;
|
||
EndPos = this.Content.length;
|
||
}
|
||
else if ( true === this.Selection.Use )
|
||
{
|
||
StartPos = this.State.Selection.StartPos;
|
||
EndPos = this.State.Selection.EndPos;
|
||
|
||
if ( StartPos > EndPos )
|
||
{
|
||
var Temp = EndPos;
|
||
EndPos = StartPos;
|
||
StartPos = Temp;
|
||
}
|
||
}
|
||
|
||
var Str = "";
|
||
|
||
for ( var Pos = StartPos; Pos < EndPos; Pos++ )
|
||
{
|
||
var Item = this.Content[Pos];
|
||
var ItemType = Item.Type;
|
||
|
||
switch ( ItemType )
|
||
{
|
||
case para_Drawing:
|
||
case para_Numbering:
|
||
case para_PresentationNumbering:
|
||
case para_PageNum:
|
||
case para_PageCount:
|
||
{
|
||
if ( true === bClearText )
|
||
return null;
|
||
|
||
break;
|
||
}
|
||
|
||
case para_Text :
|
||
{
|
||
Str += AscCommon.encodeSurrogateChar(Item.Value);
|
||
break;
|
||
}
|
||
case para_Space:
|
||
{
|
||
Str += " ";
|
||
break;
|
||
}
|
||
case para_Tab:
|
||
{
|
||
Str += oPr && undefined !== oPr.TabSymbol ? oPr.TabSymbol : ' ';
|
||
break;
|
||
}
|
||
case para_Math_Text:
|
||
case para_Math_BreakOperator:
|
||
{
|
||
Str += AscCommon.encodeSurrogateChar(Item.value);
|
||
break;
|
||
}
|
||
case para_NewLine:
|
||
{
|
||
Str += oPr && undefined !== oPr.NewLineSeparator ? oPr.NewLineSeparator : '\r';
|
||
break;
|
||
}
|
||
case para_End:
|
||
{
|
||
var oParagraph = this.GetParagraph();
|
||
if (oParagraph && null === oParagraph.Get_DocumentNext() && oParagraph.IsTableCellContent())
|
||
{
|
||
if (!oParagraph.Parent.IsLastTableCellInRow(true))
|
||
Str += oPr && undefined !== oPr.TableCellSeparator ? oPr.TableCellSeparator : '\t';
|
||
else
|
||
Str += oPr && undefined !== oPr.TableRowSeparator ? oPr.TableRowSeparator : '\r\n';
|
||
}
|
||
else
|
||
{
|
||
Str += oPr && undefined !== oPr.ParaSeparator ? oPr.ParaSeparator : '\r\n';
|
||
}
|
||
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
return Str;
|
||
};
|
||
|
||
ParaRun.prototype.GetSelectDirection = function()
|
||
{
|
||
if (true !== this.Selection.Use)
|
||
return 0;
|
||
|
||
if (this.Selection.StartPos <= this.Selection.EndPos)
|
||
return 1;
|
||
|
||
return -1;
|
||
};
|
||
|
||
ParaRun.prototype.CanAddDropCap = function()
|
||
{
|
||
for (var nPos = 0, nCount = this.Content.length; nPos < nCount; ++nPos)
|
||
{
|
||
switch (this.Content[nPos].Type)
|
||
{
|
||
case para_Text:
|
||
return true;
|
||
|
||
case para_Space:
|
||
case para_Tab:
|
||
case para_PageNum:
|
||
case para_PageCount:
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return null;
|
||
};
|
||
|
||
ParaRun.prototype.Get_TextForDropCap = function(DropCapText, UseContentPos, ContentPos, Depth)
|
||
{
|
||
var EndPos = ( true === UseContentPos ? ContentPos.Get(Depth) : this.Content.length );
|
||
|
||
for ( var Pos = 0; Pos < EndPos; Pos++ )
|
||
{
|
||
var Item = this.Content[Pos];
|
||
var ItemType = Item.Type;
|
||
|
||
if ( true === DropCapText.Check )
|
||
{
|
||
if (para_Space === ItemType || para_Tab === ItemType || para_PageNum === ItemType || para_PageCount === ItemType || para_Drawing === ItemType || para_End === ItemType)
|
||
{
|
||
DropCapText.Mixed = true;
|
||
return;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if ( para_Text === ItemType )
|
||
{
|
||
DropCapText.Runs.push(this);
|
||
DropCapText.Text.push(Item);
|
||
|
||
this.Remove_FromContent( Pos, 1, true );
|
||
Pos--;
|
||
EndPos--;
|
||
|
||
if ( true === DropCapText.Mixed )
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.Get_StartTabsCount = function(TabsCounter)
|
||
{
|
||
var ContentLen = this.Content.length;
|
||
|
||
for ( var Pos = 0; Pos < ContentLen; Pos++ )
|
||
{
|
||
var Item = this.Content[Pos];
|
||
var ItemType = Item.Type;
|
||
|
||
if ( para_Tab === ItemType )
|
||
{
|
||
TabsCounter.Count++;
|
||
TabsCounter.Pos.push( Pos );
|
||
}
|
||
else if ( para_Text === ItemType || para_Space === ItemType || (para_Drawing === ItemType && true === Item.Is_Inline() ) || para_PageNum === ItemType || para_PageCount === ItemType || para_Math === ItemType )
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
};
|
||
|
||
ParaRun.prototype.Remove_StartTabs = function(TabsCounter)
|
||
{
|
||
var ContentLen = this.Content.length;
|
||
for ( var Pos = 0; Pos < ContentLen; Pos++ )
|
||
{
|
||
var Item = this.Content[Pos];
|
||
var ItemType = Item.Type;
|
||
|
||
if ( para_Tab === ItemType )
|
||
{
|
||
this.Remove_FromContent( Pos, 1, true );
|
||
|
||
TabsCounter.Count--;
|
||
Pos--;
|
||
ContentLen--;
|
||
}
|
||
else if ( para_Text === ItemType || para_Space === ItemType || (para_Drawing === ItemType && true === Item.Is_Inline() ) || para_PageNum === ItemType || para_PageCount === ItemType || para_Math === ItemType )
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
};
|
||
//-----------------------------------------------------------------------------------
|
||
// Функции пересчета
|
||
//-----------------------------------------------------------------------------------
|
||
// Пересчитываем размеры всех элементов
|
||
ParaRun.prototype.Recalculate_MeasureContent = function()
|
||
{
|
||
if (!this.RecalcInfo.IsMeasureNeed())
|
||
return;
|
||
|
||
this.Paragraph.ShapeText();
|
||
|
||
var oTextPr = this.Get_CompiledPr(false);
|
||
var oTheme = this.Paragraph.GetTheme();
|
||
|
||
let _oTextPr = oTextPr;
|
||
if (this.IsUseAscFont(oTextPr))
|
||
{
|
||
_oTextPr = oTextPr.Copy();
|
||
_oTextPr.RFonts.SetAll("ASCW3");
|
||
}
|
||
|
||
g_oTextMeasurer.SetTextPr(_oTextPr, oTheme);
|
||
|
||
var oInfoMathText;
|
||
if (this.IsMathRun())
|
||
{
|
||
oInfoMathText = new CMathInfoTextPr({
|
||
TextPr : oTextPr,
|
||
ArgSize : this.Parent.Compiled_ArgSz.value,
|
||
bNormalText : this.IsNormalText(),
|
||
bEqArray : this.Parent.IsEqArray()
|
||
});
|
||
}
|
||
|
||
var nMaxComb = -1;
|
||
var nCombWidth = null;
|
||
var oTextForm = this.GetTextForm();
|
||
let oTextFormPDF = this.GetFormPDF();
|
||
if (oTextFormPDF && oTextFormPDF.GetType() !== AscPDF.FIELD_TYPES.text)
|
||
oTextFormPDF = null;
|
||
|
||
let isKeepWidth = false;
|
||
if (oTextForm && oTextForm.IsComb())
|
||
{
|
||
let textMetrics = this.getTextMetrics();
|
||
let textAscent = textMetrics.Ascent + textMetrics.LineGap;
|
||
|
||
const nWRule = oTextForm.GetWidthRule();
|
||
isKeepWidth = Asc.CombFormWidthRule.Exact === nWRule;
|
||
|
||
nMaxComb = oTextForm.GetMaxCharacters();
|
||
|
||
if (undefined === oTextForm.Width || nWRule === Asc.CombFormWidthRule.Auto)
|
||
nCombWidth = 0;
|
||
else if (oTextForm.Width < 0)
|
||
nCombWidth = textAscent * (Math.abs(oTextForm.Width) / 100);
|
||
else
|
||
nCombWidth = AscCommon.TwipsToMM(oTextForm.Width);
|
||
|
||
if (!nCombWidth || nCombWidth < 0)
|
||
nCombWidth = textAscent;
|
||
|
||
let oParagraph = this.GetParagraph();
|
||
if (oParagraph
|
||
&& oParagraph.IsInFixedForm()
|
||
&& oParagraph.GetInnerForm()
|
||
&& !oParagraph.GetInnerForm().IsComplexForm())
|
||
{
|
||
isKeepWidth = true;
|
||
var oShape = oParagraph.Parent.Is_DrawingShape(true);
|
||
var oBounds = oShape.getFormRelRect();
|
||
|
||
if (nMaxComb > 0)
|
||
nCombWidth = oBounds.W / nMaxComb;
|
||
}
|
||
|
||
}
|
||
// for pdf text forms
|
||
else if (oTextFormPDF && oTextFormPDF.IsComb() == true)
|
||
{
|
||
isKeepWidth = true;
|
||
nMaxComb = oTextFormPDF.GetCharLimit();
|
||
nCombWidth = oTextFormPDF.getFormRelRect().W / nMaxComb;
|
||
}
|
||
|
||
if (nCombWidth && nMaxComb > 1)
|
||
{
|
||
var oCombBorder, nCombBorderW;
|
||
if (oTextForm)
|
||
{
|
||
oCombBorder = oTextForm.GetCombBorder();
|
||
nCombBorderW = oCombBorder? oCombBorder.GetWidth() : 0;
|
||
this.private_MeasureCombForm(nCombBorderW, nCombWidth, nMaxComb, oTextForm, isKeepWidth, oTextPr, oTheme, oInfoMathText);
|
||
}
|
||
else if (oTextFormPDF)
|
||
{
|
||
let oViewer = editor.getDocumentRenderer();
|
||
let scaleCoef = oViewer.zoom * AscCommon.AscBrowser.retinaPixelRatio;
|
||
if (oTextFormPDF.borderStyle == "solid" || oTextFormPDF.borderStyle == "dashed")
|
||
nCombBorderW = oTextFormPDF.GetBordersWidth().left * AscCommon.g_dKoef_pix_to_mm / scaleCoef;
|
||
else
|
||
nCombBorderW = 0;
|
||
this.private_MeasureCombForm(nCombBorderW, nCombWidth, nMaxComb, oTextFormPDF, isKeepWidth, oTextPr, oTheme, oInfoMathText);
|
||
}
|
||
}
|
||
else if (this.RecalcInfo.Measure)
|
||
{
|
||
for (var nPos = 0, nCount = this.Content.length; nPos < nCount; ++nPos)
|
||
{
|
||
this.private_MeasureElement(nPos, oTextPr, oTheme, oInfoMathText);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
for (var nIndex = 0, nCount = this.RecalcInfo.MeasurePositions.length; nIndex < nCount; ++nIndex)
|
||
{
|
||
var nPos = this.RecalcInfo.MeasurePositions[nIndex];
|
||
if (!this.Content[nPos])
|
||
continue;
|
||
|
||
this.private_MeasureElement(nPos, oTextPr, oTheme, oInfoMathText);
|
||
}
|
||
}
|
||
|
||
this.RecalcInfo.Recalc = true;
|
||
this.RecalcInfo.ResetMeasure();
|
||
};
|
||
ParaRun.prototype.getTextMetrics = function(isForceEmpty)
|
||
{
|
||
let textPr = this.Get_CompiledPr(false);
|
||
if (this.IsUseAscFont(textPr))
|
||
{
|
||
textPr = textPr.Copy();
|
||
textPr.RFonts.SetAll("ASCW3");
|
||
}
|
||
|
||
// TODO: Пока для формул сделаем, чтобы работало по-старому, в дальнейшем надо будет переделать на fontslot
|
||
let fontSlot = this.IsMathRun() ? AscWord.fontslot_ASCII : AscWord.fontslot_None;
|
||
for (let nPos = 0, nCount = this.Content.length; nPos < nCount; ++nPos)
|
||
{
|
||
fontSlot |= this.Content[nPos].GetFontSlot(textPr);
|
||
}
|
||
|
||
if ((AscWord.fontslot_Unknown === fontSlot) || (AscWord.fontslot_None === fontSlot && isForceEmpty))
|
||
fontSlot = textPr.CS || textPr.RTL ? AscWord.fontslot_CS : AscWord.fontslot_ASCII;
|
||
|
||
return textPr.GetTextMetrics(fontSlot, this.Paragraph.GetTheme());
|
||
};
|
||
ParaRun.prototype.getYOffset = function()
|
||
{
|
||
return this.Get_Position();
|
||
};
|
||
ParaRun.prototype.private_MeasureCombForm = function(nCombBorderW, nCombWidth, nMaxComb, oTextForm, isKeepWidth, oTextPr, oTheme, oInfoMathText)
|
||
{
|
||
let nCharsCount = 0;
|
||
for (let nPos = 0, nCount = this.Content.length; nPos < nCount; ++nPos)
|
||
{
|
||
let oItem = this.Content[nPos];
|
||
if (!oItem.IsText() && !oItem.IsSpace())
|
||
continue;
|
||
|
||
nCharsCount++;
|
||
|
||
while (oItem.IsText()
|
||
&& nPos < nCount - 1
|
||
&& this.Content[nPos + 1].IsText()
|
||
&& this.Content[nPos + 1].IsCombiningMark())
|
||
{
|
||
nPos++;
|
||
}
|
||
}
|
||
|
||
for (let nPos = 0, nCount = this.Content.length; nPos < nCount; ++nPos)
|
||
{
|
||
this.private_MeasureElement(nPos, oTextPr, oTheme, oInfoMathText);
|
||
|
||
let oItem = this.Content[nPos];
|
||
if (!oItem.IsText() && !oItem.IsSpace())
|
||
continue;
|
||
|
||
let nLeftGap = nCombBorderW / 2;
|
||
let nRightGap = nCombBorderW / 2;
|
||
|
||
let nWidth = oItem.GetCombWidth() + nLeftGap + nRightGap;
|
||
|
||
if (isKeepWidth || nWidth < nCombWidth)
|
||
{
|
||
nLeftGap += (nCombWidth - nWidth) / 2;
|
||
nRightGap += (nCombWidth - nWidth) / 2;
|
||
}
|
||
let nCellWidth = Math.max(oItem.GetCombWidth() + nLeftGap + nRightGap, nCombWidth);
|
||
|
||
oItem.ResetGapBackground();
|
||
|
||
if (oItem.IsText()
|
||
&& nPos < nCount - 1
|
||
&& this.Content[nPos + 1].IsText()
|
||
&& this.Content[nPos + 1].IsCombiningMark())
|
||
{
|
||
let nFirstPos = nPos;
|
||
oItem.SetGaps(nLeftGap, 0, nCellWidth);
|
||
while (this.Content[nPos].IsText() && nPos < nCount - 1 && this.Content[nPos + 1].IsText() && this.Content[nPos + 1].IsCombiningMark())
|
||
{
|
||
if (nPos !== nFirstPos)
|
||
this.Content[nPos].SetGaps(0, 0, nCellWidth);
|
||
|
||
nPos++;
|
||
this.Content[nPos].ResetGapBackground();
|
||
}
|
||
oItem = this.Content[nPos];
|
||
nLeftGap = 0;
|
||
}
|
||
|
||
if (nPos === nCount - 1 && nCharsCount < nMaxComb)
|
||
{
|
||
if (oTextForm.CombPlaceholderSymbol)
|
||
{
|
||
oItem.SetGapBackground(nMaxComb - nCharsCount, oTextForm.CombPlaceholderSymbol, nCombWidth, g_oTextMeasurer, oTextForm.CombPlaceholderFont, oTextPr, oTheme, nCombBorderW);
|
||
nRightGap += (nMaxComb - nCharsCount) * oItem.RGapShift;
|
||
}
|
||
else
|
||
{
|
||
if (Asc.editor.isPdfEditor())
|
||
{
|
||
let nCellsToGap;
|
||
if (oTextForm.GetAlign() == AscPDF.ALIGN_TYPE.center)
|
||
nCellsToGap = (nMaxComb - nCharsCount) % 2 == 0 ? 0 : 1;
|
||
else if (oTextForm.GetAlign() == AscPDF.ALIGN_TYPE.right)
|
||
nCellsToGap = 0;
|
||
else
|
||
nCellsToGap = nMaxComb - nCharsCount;
|
||
|
||
oItem.SetGapBackground(nCellsToGap, 0, nCombWidth, g_oTextMeasurer, null, oTextPr, oTheme, nCombBorderW);
|
||
nRightGap += nCellsToGap * Math.max(nCombWidth, nCombBorderW);
|
||
}
|
||
else
|
||
{
|
||
oItem.SetGapBackground(nMaxComb - nCharsCount, 0, nCombWidth, g_oTextMeasurer, null, oTextPr, oTheme, nCombBorderW);
|
||
nRightGap += (nMaxComb - nCharsCount) * Math.max(nCombWidth, nCombBorderW);
|
||
}
|
||
}
|
||
}
|
||
|
||
oItem.SetGaps(nLeftGap, nRightGap, nCellWidth);
|
||
}
|
||
};
|
||
ParaRun.prototype.private_MeasureElement = function(nPos, oTextPr, oTheme, oInfoMathText)
|
||
{
|
||
let oParagraph = this.GetParagraph();
|
||
|
||
let oItem = this.Content[nPos];
|
||
if (oItem.IsDrawing())
|
||
{
|
||
oItem.Parent = oParagraph;
|
||
oItem.DocumentContent = oParagraph.Parent;
|
||
oItem.DrawingDocument = oParagraph.Parent.DrawingDocument;
|
||
}
|
||
|
||
// TODO: Как только избавимся от para_End переделать здесь
|
||
if (oItem.IsParaEnd())
|
||
{
|
||
var oEndTextPr = oParagraph.GetParaEndCompiledPr();
|
||
g_oTextMeasurer.SetTextPr(oEndTextPr, oTheme);
|
||
oItem.Measure(g_oTextMeasurer, oEndTextPr, oParagraph.IsLastParagraphInCell());
|
||
}
|
||
else
|
||
{
|
||
oItem.Measure(g_oTextMeasurer, oTextPr, oInfoMathText, this);
|
||
}
|
||
|
||
if (oItem.IsDrawing())
|
||
{
|
||
// После автофигур надо заново выставлять настройки
|
||
g_oTextMeasurer.SetTextPr(oTextPr, oTheme);
|
||
g_oTextMeasurer.SetFontSlot(AscWord.fontslot_ASCII);
|
||
}
|
||
};
|
||
ParaRun.prototype.Recalculate_Measure2 = function(Metrics)
|
||
{
|
||
var TAscent = Metrics.Ascent;
|
||
var TDescent = Metrics.Descent;
|
||
|
||
var Count = this.Content.length;
|
||
for ( var Index = 0; Index < Count; Index++ )
|
||
{
|
||
var Item = this.Content[Index];
|
||
var ItemType = Item.Type;
|
||
|
||
if ( para_Text === ItemType )
|
||
{
|
||
var Temp = g_oTextMeasurer.Measure2(String.fromCharCode(Item.Value));
|
||
|
||
if ( null === TAscent || TAscent < Temp.Ascent )
|
||
TAscent = Temp.Ascent;
|
||
|
||
if ( null === TDescent || TDescent > Temp.Ascent - Temp.Height )
|
||
TDescent = Temp.Ascent - Temp.Height;
|
||
}
|
||
}
|
||
|
||
Metrics.Ascent = TAscent;
|
||
Metrics.Descent = TDescent;
|
||
};
|
||
|
||
ParaRun.prototype.Recalculate_Range = function(PRS, ParaPr, Depth)
|
||
{
|
||
if ( this.Paragraph !== PRS.Paragraph )
|
||
{
|
||
this.Paragraph = PRS.Paragraph;
|
||
this.RecalcInfo.TextPr = true;
|
||
this.RecalcInfo.Measure = true;
|
||
this.OnContentChange();
|
||
}
|
||
|
||
// Сначала измеряем элементы (можно вызывать каждый раз, внутри разруливается, чтобы измерялось 1 раз)
|
||
this.Recalculate_MeasureContent();
|
||
|
||
var CurLine = PRS.Line - this.StartLine;
|
||
var CurRange = ( 0 === CurLine ? PRS.Range - this.StartRange : PRS.Range );
|
||
|
||
// Если мы рассчитываем первый отрезок в первой строке, тогда нам нужно обновить информацию о нумерации
|
||
if ( 0 === CurRange && 0 === CurLine )
|
||
{
|
||
var PrevRecalcInfo = PRS.RunRecalcInfoLast;
|
||
|
||
// Либо до этого ничего не было (изначально первая строка и первый отрезок), либо мы заново пересчитываем
|
||
// первую строку и первый отрезок (из-за обтекания, например).
|
||
if ( null === PrevRecalcInfo )
|
||
this.RecalcInfo.NumberingAdd = true;
|
||
else
|
||
this.RecalcInfo.NumberingAdd = PrevRecalcInfo.NumberingAdd;
|
||
|
||
this.RecalcInfo.NumberingUse = false;
|
||
this.RecalcInfo.NumberingItem = null;
|
||
}
|
||
|
||
// Сохраняем ссылку на информацию пересчета данного рана
|
||
PRS.RunRecalcInfoLast = this.RecalcInfo;
|
||
|
||
// Добавляем информацию о новом отрезке
|
||
var RangeStartPos = this.protected_AddRange(CurLine, CurRange);
|
||
var RangeEndPos = 0;
|
||
|
||
var Para = PRS.Paragraph;
|
||
|
||
var MoveToLBP = PRS.MoveToLBP;
|
||
var NewRange = PRS.NewRange;
|
||
var ForceNewPage = PRS.ForceNewPage;
|
||
var NewPage = PRS.NewPage;
|
||
var End = PRS.End;
|
||
|
||
var Word = PRS.Word;
|
||
var StartWord = PRS.StartWord;
|
||
var FirstItemOnLine = PRS.FirstItemOnLine;
|
||
var EmptyLine = PRS.EmptyLine;
|
||
var TextOnLine = PRS.TextOnLine;
|
||
|
||
var RangesCount = PRS.RangesCount;
|
||
|
||
var SpaceLen = PRS.SpaceLen;
|
||
var WordLen = PRS.WordLen;
|
||
|
||
var X = PRS.X;
|
||
var XEnd = this.Paragraph.IsUseXLimit() ? PRS.XEnd : MEASUREMENT_MAX_MM_VALUE * 10;
|
||
|
||
var ParaLine = PRS.Line;
|
||
var ParaRange = PRS.Range;
|
||
var bMathWordLarge = PRS.bMathWordLarge;
|
||
var OperGapRight = PRS.OperGapRight;
|
||
var OperGapLeft = PRS.OperGapLeft;
|
||
|
||
var bInsideOper = PRS.bInsideOper;
|
||
var bContainCompareOper = PRS.bContainCompareOper;
|
||
var bEndRunToContent = PRS.bEndRunToContent;
|
||
var bNoOneBreakOperator = PRS.bNoOneBreakOperator;
|
||
var bForcedBreak = PRS.bForcedBreak;
|
||
|
||
var Pos = RangeStartPos;
|
||
|
||
var ContentLen = this.Content.length;
|
||
var XRange = PRS.XRange;
|
||
var oSectionPr = undefined;
|
||
|
||
let isSkipFillRange = false;
|
||
|
||
let textPr = this.Get_CompiledPr(false);
|
||
|
||
// TODO: Сделать возможность показывать инструкцию
|
||
var isHiddenCFPart = PRS.ComplexFields.isHiddenComplexFieldPart();
|
||
|
||
PRS.CheckUpdateLBP(Pos, Depth);
|
||
|
||
if (false === StartWord && true === FirstItemOnLine && XEnd - X < 0.001 && RangesCount > 0)
|
||
{
|
||
NewRange = true;
|
||
RangeEndPos = Pos;
|
||
}
|
||
else
|
||
{
|
||
for (; Pos < ContentLen; Pos++)
|
||
{
|
||
var Item = this.Content[Pos];
|
||
var ItemType = Item.Type;
|
||
|
||
if (PRS.ComplexFields.isHiddenFieldContent() && para_End !== ItemType && para_FieldChar !== ItemType)
|
||
continue;
|
||
|
||
if (para_InstrText === ItemType)
|
||
{
|
||
if (PRS.IsFastRecalculate())
|
||
{
|
||
if (Item.GetReplacementItem())
|
||
{
|
||
Item = Item.GetReplacementItem();
|
||
ItemType = Item.Type;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
var oInstrText = Item;
|
||
if (!isHiddenCFPart)
|
||
{
|
||
if (AscCommon.IsSpace(Item.Value))
|
||
{
|
||
Item = new AscWord.CRunSpace(Item.Value);
|
||
ItemType = para_Space;
|
||
Item.Measure(g_oTextMeasurer, this.getCompiledPr());
|
||
}
|
||
else
|
||
{
|
||
// TODO: Пока для такого текста не шейпим по-нормальному, а как по-старому по одному отдельному символу
|
||
Item = new AscWord.CRunText(Item.Value);
|
||
ItemType = para_Text;
|
||
AscWord.ParagraphTextShaper.ShapeRunTextItem(Item, this.getCompiledPr());
|
||
}
|
||
|
||
oInstrText.SetReplacementItem(Item);
|
||
}
|
||
else
|
||
{
|
||
oInstrText.SetReplacementItem(null);
|
||
}
|
||
}
|
||
}
|
||
|
||
if (isHiddenCFPart && para_End !== ItemType && para_FieldChar !== ItemType)
|
||
continue;
|
||
|
||
// Проверяем, не нужно ли добавить нумерацию к данному элементу
|
||
if (true === this.RecalcInfo.NumberingAdd && true === Item.CanAddNumbering())
|
||
X = this.private_RecalculateNumbering(PRS, Item, ParaPr, X);
|
||
|
||
switch (ItemType)
|
||
{
|
||
case para_Sym:
|
||
case para_Text:
|
||
case para_FootnoteReference:
|
||
case para_FootnoteRef:
|
||
case para_Separator:
|
||
case para_ContinuationSeparator:
|
||
case para_EndnoteReference:
|
||
case para_EndnoteRef:
|
||
{
|
||
// Отмечаем, что началось слово
|
||
StartWord = true;
|
||
|
||
if (para_ContinuationSeparator === ItemType || para_Separator === ItemType)
|
||
Item.UpdateWidth(PRS);
|
||
else if (para_Text === ItemType)
|
||
{
|
||
Item.ResetTemporaryGrapheme();
|
||
Item.ResetTemporaryHyphenAfter();
|
||
}
|
||
|
||
if (true !== PRS.IsFastRecalculate())
|
||
{
|
||
if (para_FootnoteReference === ItemType)
|
||
{
|
||
if (this.GetLogicDocument() && !this.GetLogicDocument().RecalcTableHeader)
|
||
{
|
||
Item.UpdateNumber(PRS, this.GetLogicDocument().PrintSelection);
|
||
PRS.AddFootnoteReference(Item, PRS.GetCurrentContentPos(Pos));
|
||
}
|
||
else
|
||
{
|
||
Item.private_Measure();
|
||
}
|
||
}
|
||
else if (para_EndnoteReference === ItemType)
|
||
{
|
||
if (this.GetLogicDocument() && !this.GetLogicDocument().RecalcTableHeader)
|
||
{
|
||
Item.UpdateNumber(PRS, this.GetLogicDocument().PrintSelection);
|
||
PRS.AddEndnoteReference(Item, PRS.GetCurrentContentPos(Pos));
|
||
}
|
||
else
|
||
{
|
||
Item.private_Measure();
|
||
}
|
||
}
|
||
else if (para_FootnoteRef === ItemType || para_EndnoteRef === ItemType)
|
||
{
|
||
Item.UpdateNumber(PRS.TopDocument);
|
||
}
|
||
}
|
||
|
||
let isBreakBefore = Item.IsSpaceBefore();
|
||
if (isBreakBefore
|
||
&& Word
|
||
&& PRS.LastItem.CanBeAtEndOfLine()
|
||
&& Item.CanBeAtBeginOfLine())
|
||
{
|
||
PRS.Set_LineBreakPos(Pos, FirstItemOnLine);
|
||
|
||
X += SpaceLen + WordLen;
|
||
Word = false;
|
||
EmptyLine = false;
|
||
TextOnLine = true;
|
||
FirstItemOnLine = false;
|
||
SpaceLen = 0;
|
||
WordLen = 0;
|
||
}
|
||
|
||
// При проверке, убирается ли слово, мы должны учитывать ширину предшествующих пробелов
|
||
let LetterLen = Item.GetWidth();
|
||
let isLigature = Item.IsLigature();
|
||
let GraphemeLen = isLigature ? Item.GetLigatureWidth() : LetterLen;
|
||
|
||
let isBreakAfter = Item.IsSpaceAfter() || textPr.RFonts.Hint === AscWord.fonthint_EastAsia;
|
||
|
||
if (FirstItemOnLine
|
||
&& (X + SpaceLen + WordLen + GraphemeLen > XEnd
|
||
|| (PRS.IsNeedShapeFirstWord(PRS.Line) && PRS.IsLastElementInWord(this, Pos))))
|
||
{
|
||
let oCurrentPos = PRS.CurPos.Copy();
|
||
oCurrentPos.Update(Pos, Depth);
|
||
|
||
if (isLigature)
|
||
oCurrentPos = Para.GetLigatureEndPos(oCurrentPos);
|
||
else
|
||
oCurrentPos.Update(Pos + 1, Depth);
|
||
|
||
Para.ShapeTextInRange(PRS.LineBreakPos, oCurrentPos);
|
||
|
||
SpaceLen = 0;
|
||
LetterLen = 0;
|
||
GraphemeLen = 0;
|
||
WordLen = Para.GetContentWidthInRange(PRS.LineBreakPos, oCurrentPos);
|
||
|
||
if (X + WordLen > XEnd && (Word || !Para.IsSingleRangeOnLine(ParaLine, ParaRange)))
|
||
{
|
||
// Слово оказалось единственным элементом в промежутке, и, все равно,
|
||
// не умещается целиком. Делаем следующее:
|
||
//
|
||
// 1) Если у нас строка с вырезами, тогда ставим перенос внутри строки в начале слова
|
||
// 2) Если у нас строка без вырезов, тогда мы ищем перенос строки, начиная с текущего
|
||
// места в обратном направлении, при этом решейпим текст в заданном промежутке
|
||
|
||
let isBreak = true;
|
||
if (Para.IsSingleRangeOnLine(ParaLine, ParaRange))
|
||
{
|
||
let oLineStartPos = PRS.LineBreakPos.Copy();
|
||
PRS.LineBreakPos = Para.FindLineBreakInLongWord(XEnd - X, PRS.LineBreakPos, oCurrentPos);
|
||
|
||
if (PRS.LineBreakPos.IsEqual(oLineStartPos) || PRS.LineBreakPos.IsEqual(oCurrentPos))
|
||
{
|
||
PRS.LineBreakPos = oLineStartPos;
|
||
LetterLen = WordLen;
|
||
WordLen = 0;
|
||
isBreak = false;
|
||
}
|
||
else
|
||
{
|
||
this.protected_FillRange(CurLine, CurRange, RangeStartPos, RangeStartPos);
|
||
Para.Recalculate_SetRangeBounds(ParaLine, ParaRange, oLineStartPos, PRS.LineBreakPos);
|
||
|
||
isSkipFillRange = true;
|
||
|
||
PRS.LongWord = true;
|
||
|
||
EmptyLine = false;
|
||
TextOnLine = true;
|
||
|
||
X += WordLen;
|
||
WordLen = 0;
|
||
}
|
||
}
|
||
|
||
if (isBreak)
|
||
{
|
||
MoveToLBP = true;
|
||
NewRange = true;
|
||
break;
|
||
}
|
||
}
|
||
else if (!Word)
|
||
{
|
||
WordLen = 0;
|
||
LetterLen = Item.GetWidth();
|
||
}
|
||
}
|
||
|
||
if (!Word)
|
||
{
|
||
// Слово только началось. Делаем следующее:
|
||
// 1) Если до него на строке ничего не было и данная строка не
|
||
// имеет разрывов, тогда не надо проверять убирается ли слово в строке.
|
||
// 2) В противном случае, проверяем убирается ли слово в промежутке.
|
||
|
||
// Если слово только началось, и до него на строке ничего не было, и в строке нет разрывов, тогда не надо проверять убирается ли оно на строке.
|
||
if (!FirstItemOnLine || !Para.IsSingleRangeOnLine(ParaLine, ParaRange))
|
||
{
|
||
if (X + SpaceLen + LetterLen > XEnd)
|
||
{
|
||
if (para_Text === ItemType && !Item.CanBeAtBeginOfLine() && !PRS.LineBreakFirst)
|
||
{
|
||
MoveToLBP = true;
|
||
NewRange = true;
|
||
}
|
||
else
|
||
{
|
||
NewRange = true;
|
||
RangeEndPos = Pos;
|
||
PRS.checkLastAutoHyphen();
|
||
}
|
||
}
|
||
}
|
||
|
||
if (true !== NewRange)
|
||
{
|
||
// Если с данного элемента не может начинаться строка, тогда считает все пробелы идущие
|
||
// до него частью этого слова.
|
||
// Если места для разрыва строки еще не было, значит это все еще первый элемент идет, и
|
||
// тогда общую ширину пробелов прибавляем к ширине символа.
|
||
// Если разрыв были и с данного символа не может начинаться строка, тогда испоьльзуем
|
||
// предыдущий разрыв.
|
||
if (PRS.LineBreakFirst && !Item.CanBeAtBeginOfLine())
|
||
{
|
||
Word = true;
|
||
FirstItemOnLine = true;
|
||
|
||
WordLen = X - PRS.XRange + LetterLen + SpaceLen;
|
||
SpaceLen = 0;
|
||
|
||
X = PRS.XRange;
|
||
PRS.X = X;
|
||
}
|
||
else
|
||
{
|
||
if (Item.CanBeAtBeginOfLine())
|
||
{
|
||
PRS.Set_LineBreakPos(Pos, FirstItemOnLine);
|
||
PRS.checkLastAutoHyphen();
|
||
}
|
||
|
||
// Если текущий символ с переносом, например, дефис, тогда на нем заканчивается слово
|
||
if (isBreakAfter
|
||
|| (PRS.canPlaceAutoHyphenAfter(Item)
|
||
&& X + SpaceLen + LetterLen + PRS.getAutoHyphenWidth(Item, this) <= XEnd
|
||
&& (FirstItemOnLine || PRS.checkHyphenationZone(X + SpaceLen))))
|
||
{
|
||
if (!isBreakAfter)
|
||
PRS.lastAutoHyphen = Item;
|
||
|
||
// Добавляем длину пробелов до слова и ширину самого слова.
|
||
X += SpaceLen + LetterLen;
|
||
|
||
Word = false;
|
||
FirstItemOnLine = false;
|
||
EmptyLine = false;
|
||
TextOnLine = true;
|
||
SpaceLen = 0;
|
||
WordLen = 0;
|
||
}
|
||
else
|
||
{
|
||
Word = true;
|
||
WordLen = LetterLen;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
|
||
let autoHyphenWidth = PRS.getAutoHyphenWidth(Item, this);
|
||
|
||
let fitOnLine = PRS.isFitOnLine(X, SpaceLen + WordLen + GraphemeLen + autoHyphenWidth);
|
||
if (!fitOnLine && !FirstItemOnLine)
|
||
{
|
||
MoveToLBP = true;
|
||
NewRange = true;
|
||
}
|
||
|
||
if (true !== NewRange)
|
||
{
|
||
// Мы убираемся в пределах данной строки. Прибавляем ширину буквы к ширине слова
|
||
WordLen += LetterLen;
|
||
|
||
if (isBreakAfter
|
||
|| (PRS.canPlaceAutoHyphenAfter(Item)
|
||
&& fitOnLine
|
||
&& (FirstItemOnLine || PRS.checkHyphenationZone(X + SpaceLen))))
|
||
{
|
||
if (!isBreakAfter)
|
||
PRS.lastAutoHyphen = Item;
|
||
|
||
// Добавляем длину пробелов до слова и ширину самого слова.
|
||
X += SpaceLen + WordLen;
|
||
|
||
Word = false;
|
||
FirstItemOnLine = false;
|
||
EmptyLine = false;
|
||
TextOnLine = true;
|
||
SpaceLen = 0;
|
||
WordLen = 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
break;
|
||
}
|
||
case para_Math_Text:
|
||
case para_Math_Ampersand:
|
||
case para_Math_Placeholder:
|
||
{
|
||
// Отмечаем, что началось слово
|
||
StartWord = true;
|
||
|
||
// При проверке, убирается ли слово, мы должны учитывать ширину предшествующих пробелов.
|
||
var LetterLen = Item.Get_Width2() / AscWord.TEXTWIDTH_DIVIDER;//var LetterLen = Item.GetWidth();
|
||
|
||
if (true !== Word)
|
||
{
|
||
// Если слово только началось, и до него на строке ничего не было, и в строке нет разрывов, тогда не надо проверять убирается ли оно на строке.
|
||
if (true !== FirstItemOnLine /*|| false === Para.IsSingleRangeOnLine(ParaLine, ParaRange)*/)
|
||
{
|
||
if (X + SpaceLen + LetterLen > XEnd)
|
||
{
|
||
NewRange = true;
|
||
RangeEndPos = Pos;
|
||
}
|
||
else if(bForcedBreak == true)
|
||
{
|
||
MoveToLBP = true;
|
||
NewRange = true;
|
||
PRS.Set_LineBreakPos(Pos, FirstItemOnLine);
|
||
}
|
||
}
|
||
|
||
if(true !== NewRange)
|
||
{
|
||
if(this.Parent.bRoot == true)
|
||
PRS.Set_LineBreakPos(Pos, FirstItemOnLine);
|
||
|
||
WordLen += LetterLen;
|
||
Word = true;
|
||
}
|
||
|
||
}
|
||
else
|
||
{
|
||
if(X + SpaceLen + WordLen + LetterLen > XEnd)
|
||
{
|
||
if(true === FirstItemOnLine /*&& true === Para.IsSingleRangeOnLine(ParaLine, ParaRange)*/)
|
||
{
|
||
// Слово оказалось единственным элементом в промежутке, и, все равно, не умещается целиком.
|
||
// для Формулы слово не разбиваем, перенос не делаем, пишем в одну строку (слово выйдет за границу как в Ворде)
|
||
|
||
bMathWordLarge = true;
|
||
|
||
}
|
||
else
|
||
{
|
||
// Слово не убирается в отрезке. Переносим слово в следующий отрезок
|
||
MoveToLBP = true;
|
||
NewRange = true;
|
||
}
|
||
}
|
||
|
||
if (true !== NewRange)
|
||
{
|
||
// Мы убираемся в пределах данной строки. Прибавляем ширину буквы к ширине слова
|
||
WordLen += LetterLen;
|
||
}
|
||
}
|
||
|
||
break;
|
||
}
|
||
case para_Space:
|
||
{
|
||
// TODO: Проверку Balanced перенести в Measure (и избавиться от WidthEn)
|
||
if (PRS.IsBalanceSingleByteDoubleByteWidth(this, Pos))
|
||
Item.BalanceSingleByteDoubleByteWidth();
|
||
else if (PRS.IsCondensedSpaces())
|
||
PRS.AddCondensedSpaceToRange(Item);
|
||
else
|
||
Item.ResetCondensedWidth();
|
||
|
||
if (Word && PRS.LastItem && para_Text === PRS.LastItem.Type && !PRS.LastItem.CanBeAtEndOfLine())
|
||
{
|
||
WordLen += Item.GetWidth();
|
||
break;
|
||
}
|
||
|
||
FirstItemOnLine = false;
|
||
|
||
if (true === Word)
|
||
{
|
||
// Добавляем длину пробелов до слова + длина самого слова. Не надо проверять
|
||
// убирается ли слово, мы это проверяем при добавленнии букв.
|
||
X += SpaceLen + WordLen;
|
||
|
||
Word = false;
|
||
EmptyLine = false;
|
||
TextOnLine = true;
|
||
SpaceLen = 0;
|
||
WordLen = 0;
|
||
}
|
||
|
||
// На пробеле не делаем перенос. Перенос строки или внутристрочный
|
||
// перенос делаем при добавлении любого непробельного символа
|
||
SpaceLen += Item.GetWidth();
|
||
|
||
break;
|
||
}
|
||
case para_Math_BreakOperator:
|
||
{
|
||
var BrkLen = Item.Get_Width2()/AscWord.TEXTWIDTH_DIVIDER;
|
||
|
||
var oFirstContent = (PRS.Word === false && this.Content.length > 0)
|
||
? this.Content[0]
|
||
: null;
|
||
var strFirstLetter = oFirstContent !== null
|
||
? String.fromCharCode(oFirstContent.value)
|
||
: "";
|
||
var isFirstOperator = PRS.Word === false && AscMath.MathLiterals.operator.SearchU(strFirstLetter);
|
||
|
||
var bCompareOper = Item.Is_CompareOperator();
|
||
var bOperBefore = isFirstOperator || this.ParaMath.Is_BrkBinBefore() == true;
|
||
|
||
var bOperInEndContent = bOperBefore === false && bEndRunToContent === true && Pos == ContentLen - 1 && Word == true, // необходимо для того, чтобы у контентов мат объектов (к-ые могут разбиваться на строки) не было отметки Set_LineBreakPos, иначе скобка (или GapLeft), перед которой стоит break_Operator, перенесется на следующую строку (без текста !)
|
||
bLowPriority = bCompareOper == false && bContainCompareOper == false;
|
||
|
||
if(Pos == 0 && true === this.IsForcedBreak()) // принудительный перенос срабатывает всегда
|
||
{
|
||
if(FirstItemOnLine === true && Word == false && bNoOneBreakOperator == true) // первый оператор в строке
|
||
{
|
||
WordLen += BrkLen;
|
||
}
|
||
else if(bOperBefore)
|
||
{
|
||
X += SpaceLen + WordLen;
|
||
WordLen = 0;
|
||
SpaceLen = 0;
|
||
NewRange = true;
|
||
RangeEndPos = Pos;
|
||
|
||
}
|
||
else
|
||
{
|
||
if(FirstItemOnLine == false && X + SpaceLen + WordLen + BrkLen > XEnd)
|
||
{
|
||
MoveToLBP = true;
|
||
NewRange = true;
|
||
}
|
||
else
|
||
{
|
||
X += SpaceLen + WordLen;
|
||
Word = false;
|
||
MoveToLBP = true;
|
||
NewRange = true;
|
||
PRS.Set_LineBreakPos(1, FirstItemOnLine);
|
||
}
|
||
}
|
||
}
|
||
else if(bOperInEndContent || bLowPriority) // у этого break Operator приоритет низкий(в контенте на данном уровне есть другие операторы с более высоким приоритетом) => по нему не разбиваем, обрабатываем как обычную букву
|
||
{
|
||
if(X + SpaceLen + WordLen + BrkLen > XEnd)
|
||
{
|
||
if(FirstItemOnLine == true)
|
||
{
|
||
bMathWordLarge = true;
|
||
}
|
||
else
|
||
{
|
||
// Слово не убирается в отрезке. Переносим слово в следующий отрезок
|
||
MoveToLBP = true;
|
||
NewRange = true;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
WordLen += BrkLen;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
var WorLenCompareOper = WordLen + X - XRange + (bOperBefore ? SpaceLen : BrkLen);
|
||
|
||
var bOverXEnd, bOverXEndMWordLarge;
|
||
var bNotUpdBreakOper = false;
|
||
|
||
var bCompareWrapIndent = PRS.bFirstLine == true ? WorLenCompareOper > PRS.WrapIndent : true;
|
||
|
||
if(PRS.bPriorityOper == true && bCompareOper == true && bContainCompareOper == true && bCompareWrapIndent == true && !(Word == false && FirstItemOnLine === true)) // (Word == true && FirstItemOnLine == true) - не первый элемент в строке
|
||
bContainCompareOper = false;
|
||
|
||
if(bOperBefore) // оператор "до" => оператор находится в начале строки
|
||
{
|
||
bOverXEnd = X + WordLen + SpaceLen + BrkLen > XEnd; // BrkLen прибавляем дла случая, если идут подряд Brk Operators в конце
|
||
bOverXEndMWordLarge = X + WordLen + SpaceLen > XEnd; // ширину самого оператора не учитываем при расчете bMathWordLarge, т.к. он будет находится на следующей строке
|
||
|
||
if(bOverXEnd && (true !== FirstItemOnLine || true === Word))
|
||
{
|
||
// если вышли за границы не обновляем параметр bInsideOper, т.к. если уже были breakOperator, то, соответственно, он уже выставлен в true
|
||
// а если на этом уровне не было breakOperator, то и обновлять его нне нужо
|
||
|
||
if(FirstItemOnLine === false)
|
||
{
|
||
MoveToLBP = true;
|
||
NewRange = true;
|
||
}
|
||
else
|
||
{
|
||
if(Word == true && bOverXEndMWordLarge == true)
|
||
{
|
||
bMathWordLarge = true;
|
||
}
|
||
|
||
X += SpaceLen + WordLen;
|
||
|
||
if(PRS.bBreakPosInLWord == true)
|
||
{
|
||
PRS.Set_LineBreakPos(Pos, FirstItemOnLine);
|
||
|
||
}
|
||
else
|
||
{
|
||
bNotUpdBreakOper = true;
|
||
}
|
||
|
||
RangeEndPos = Pos;
|
||
|
||
SpaceLen = 0;
|
||
WordLen = 0;
|
||
|
||
NewRange = true;
|
||
EmptyLine = false;
|
||
TextOnLine = true;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if(FirstItemOnLine === false)
|
||
bInsideOper = true;
|
||
|
||
|
||
if(Word == false && FirstItemOnLine == true )
|
||
{
|
||
SpaceLen += BrkLen;
|
||
}
|
||
else
|
||
{
|
||
// проверка на FirstItemOnLine == false нужна для случая, если иду подряд несколько breakOperator
|
||
// в этом случае Word == false && FirstItemOnLine == false, нужно также поставить отметку для потенциального переноса
|
||
|
||
X += SpaceLen + WordLen;
|
||
PRS.Set_LineBreakPos(Pos, FirstItemOnLine);
|
||
EmptyLine = false;
|
||
TextOnLine = true;
|
||
WordLen = BrkLen;
|
||
SpaceLen = 0;
|
||
|
||
}
|
||
|
||
// в первой строке может не быть ни одного break Operator, при этом слово не выходит за границы, т.о. обновляем FirstItemOnLine также и на Word = true
|
||
// т.к. оператор идет в начале строки, то соответственно слово в стоке не будет первым, если в строке больше одного оператора
|
||
if(bNoOneBreakOperator == false || Word == true)
|
||
FirstItemOnLine = false;
|
||
|
||
}
|
||
}
|
||
else // оператор "после" => оператор находится в конце строки
|
||
{
|
||
bOverXEnd = X + WordLen + BrkLen - Item.GapRight > XEnd;
|
||
bOverXEndMWordLarge = bOverXEnd;
|
||
|
||
if(bOverXEnd && FirstItemOnLine === false) // Слово не убирается в отрезке. Переносим слово в следующий отрезок
|
||
{
|
||
MoveToLBP = true;
|
||
NewRange = true;
|
||
|
||
if(Word == false)
|
||
PRS.Set_LineBreakPos(Pos, FirstItemOnLine);
|
||
}
|
||
else
|
||
{
|
||
bInsideOper = true;
|
||
|
||
// осуществляем здесь, чтобы не изменить GapRight в случае, когда новое слово не убирается на break_Operator
|
||
OperGapRight = Item.GapRight;
|
||
|
||
if(bOverXEndMWordLarge == true) // FirstItemOnLine == true
|
||
{
|
||
bMathWordLarge = true;
|
||
|
||
}
|
||
|
||
X += BrkLen + WordLen;
|
||
|
||
EmptyLine = false;
|
||
TextOnLine = true;
|
||
SpaceLen = 0;
|
||
WordLen = 0;
|
||
|
||
var bNotUpdate = bOverXEnd == true && PRS.bBreakPosInLWord == false;
|
||
|
||
// FirstItemOnLine == true
|
||
if(bNotUpdate == false) // LineBreakPos обновляем здесь, т.к. слово может начаться с мат объекта, а не с Run, в мат объекте нет соответствующей проверки
|
||
{
|
||
PRS.Set_LineBreakPos(Pos + 1, FirstItemOnLine);
|
||
}
|
||
else
|
||
{
|
||
bNotUpdBreakOper = true;
|
||
}
|
||
|
||
FirstItemOnLine = false;
|
||
|
||
Word = false;
|
||
}
|
||
}
|
||
}
|
||
|
||
if(bNotUpdBreakOper == false)
|
||
bNoOneBreakOperator = false;
|
||
|
||
break;
|
||
}
|
||
case para_Drawing:
|
||
{
|
||
if(oSectionPr === undefined)
|
||
{
|
||
oSectionPr = Para.Get_SectPr();
|
||
}
|
||
Item.CheckRecalcAutoFit(oSectionPr);
|
||
if (true === Item.Is_Inline() || true === Para.Parent.Is_DrawingShape())
|
||
{
|
||
// TODO: Нельзя что-то писать в историю во время пересчета, это действие надо делать при открытии
|
||
// if (true !== Item.Is_Inline())
|
||
// Item.Set_DrawingType(drawing_Inline);
|
||
|
||
if (true === StartWord)
|
||
FirstItemOnLine = false;
|
||
|
||
Item.YOffset = this.getYOffset();
|
||
|
||
// Если до этого было слово, тогда не надо проверять убирается ли оно, но если стояли пробелы,
|
||
// тогда мы их учитываем при проверке убирается ли данный элемент, и добавляем только если
|
||
// данный элемент убирается
|
||
if (true === Word || WordLen > 0)
|
||
{
|
||
// Добавляем длину пробелов до слова + длина самого слова. Не надо проверять
|
||
// убирается ли слово, мы это проверяем при добавленнии букв.
|
||
X += SpaceLen + WordLen;
|
||
|
||
Word = false;
|
||
EmptyLine = false;
|
||
TextOnLine = true;
|
||
SpaceLen = 0;
|
||
WordLen = 0;
|
||
}
|
||
|
||
var DrawingWidth = Item.GetWidth();
|
||
if (X + SpaceLen + DrawingWidth > XEnd && ( false === FirstItemOnLine || false === Para.IsSingleRangeOnLine(ParaLine, ParaRange) ))
|
||
{
|
||
// Автофигура не убирается, ставим перенос перед ней
|
||
NewRange = true;
|
||
RangeEndPos = Pos;
|
||
}
|
||
else
|
||
{
|
||
// Добавляем длину пробелов до автофигуры
|
||
X += SpaceLen + DrawingWidth;
|
||
|
||
FirstItemOnLine = false;
|
||
EmptyLine = false;
|
||
}
|
||
|
||
SpaceLen = 0;
|
||
}
|
||
else if (!Item.IsSkipOnRecalculate())
|
||
{
|
||
// Основная обработка происходит в Recalculate_Range_Spaces. Здесь обрабатывается единственный случай,
|
||
// когда после второго пересчета с уже добавленной картинкой оказывается, что место в параграфе, где
|
||
// идет картинка ушло на следующую страницу. В этом случае мы ставим перенос страницы перед картинкой.
|
||
|
||
var LogicDocument = Para.Parent;
|
||
var LDRecalcInfo = LogicDocument.RecalcInfo;
|
||
var DrawingObjects = LogicDocument.DrawingObjects;
|
||
var CurPage = PRS.Page;
|
||
|
||
if (true === LDRecalcInfo.Check_FlowObject(Item) && true === LDRecalcInfo.Is_PageBreakBefore())
|
||
{
|
||
LDRecalcInfo.Reset();
|
||
|
||
let continueCalc = false;
|
||
// Добавляем разрыв страницы. Если это первая страница, тогда ставим разрыв страницы в начале параграфа,
|
||
// если нет, тогда в начале текущей строки.
|
||
if (null != Para.Get_DocumentPrev() && true != Para.IsTableCellContent() && 0 === CurPage)
|
||
{
|
||
Para.Recalculate_Drawing_AddPageBreak(0, 0, true);
|
||
PRS.RecalcResult = recalcresult_NextPage | recalcresultflags_Page;
|
||
PRS.NewRange = true;
|
||
return;
|
||
}
|
||
else
|
||
{
|
||
if (ParaLine != Para.Pages[CurPage].FirstLine)
|
||
{
|
||
Para.Recalculate_Drawing_AddPageBreak(ParaLine, CurPage, false);
|
||
PRS.RecalcResult = recalcresult_NextPage | recalcresultflags_Page;
|
||
PRS.NewRange = true;
|
||
return;
|
||
}
|
||
else if (Para.IsStartFromNewPage())
|
||
{
|
||
// Делаем как MSWord перестаем учитывать обтекание данного объекта
|
||
continueCalc = true;
|
||
LDRecalcInfo.Set_FlowObject(Item, 0, recalcresult_NextElement, -1);
|
||
LDRecalcInfo.Set_PageBreakBefore(false);
|
||
LDRecalcInfo.SetForceNoWrap(true);
|
||
PRS.ForceNewPageAfter = true;
|
||
}
|
||
else
|
||
{
|
||
RangeEndPos = Pos;
|
||
NewRange = true;
|
||
ForceNewPage = true;
|
||
}
|
||
}
|
||
|
||
// Если до этого было слово, тогда не надо проверять убирается ли оно
|
||
if (!continueCalc && (true === Word || WordLen > 0))
|
||
{
|
||
// Добавляем длину пробелов до слова + длина самого слова. Не надо проверять
|
||
// убирается ли слово, мы это проверяем при добавленнии букв.
|
||
X += SpaceLen + WordLen;
|
||
|
||
Word = false;
|
||
SpaceLen = 0;
|
||
|
||
WordLen = 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
break;
|
||
}
|
||
case para_PageCount:
|
||
case para_PageNum:
|
||
{
|
||
if (para_PageCount === ItemType)
|
||
{
|
||
var oHdrFtr = Para.Parent.IsHdrFtr(true);
|
||
if (oHdrFtr)
|
||
oHdrFtr.Add_PageCountElement(Item);
|
||
}
|
||
else if (para_PageNum === ItemType)
|
||
{
|
||
let logicDocument = Para.LogicDocument;
|
||
let sectInfo = logicDocument.Get_SectionPageNumInfo2(Para.GetAbsolutePage(PRS.Page));
|
||
let sectPr = logicDocument.GetSections().GetSectPrByIndex(sectInfo.SectIndex);
|
||
Item.SetValue(sectInfo.CurPage, sectPr.GetPageNumFormat());
|
||
}
|
||
|
||
// Если до этого было слово, тогда не надо проверять убирается ли оно, но если стояли пробелы,
|
||
// тогда мы их учитываем при проверке убирается ли данный элемент, и добавляем только если
|
||
// данный элемент убирается
|
||
if (true === Word || WordLen > 0)
|
||
{
|
||
// Добавляем длину пробелов до слова + длина самого слова. Не надо проверять
|
||
// убирается ли слово, мы это проверяем при добавленнии букв.
|
||
X += SpaceLen + WordLen;
|
||
|
||
Word = false;
|
||
EmptyLine = false;
|
||
TextOnLine = true;
|
||
SpaceLen = 0;
|
||
WordLen = 0;
|
||
}
|
||
|
||
// Если на строке начиналось какое-то слово, тогда данная строка уже не пустая
|
||
if (true === StartWord)
|
||
FirstItemOnLine = false;
|
||
|
||
var PageNumWidth = Item.GetWidth();
|
||
if (X + SpaceLen + PageNumWidth > XEnd && ( false === FirstItemOnLine || false === Para.IsSingleRangeOnLine(ParaLine, ParaRange) ))
|
||
{
|
||
// Данный элемент не убирается, ставим перенос перед ним
|
||
NewRange = true;
|
||
RangeEndPos = Pos;
|
||
}
|
||
else
|
||
{
|
||
// Добавляем длину пробелов до слова и ширину данного элемента
|
||
X += SpaceLen + PageNumWidth;
|
||
|
||
FirstItemOnLine = false;
|
||
EmptyLine = false;
|
||
TextOnLine = true;
|
||
}
|
||
|
||
SpaceLen = 0;
|
||
|
||
break;
|
||
}
|
||
case para_Tab:
|
||
{
|
||
// Сначала проверяем, если у нас уже есть таб, которым мы должны рассчитать, тогда высчитываем
|
||
// его ширину.
|
||
|
||
var isLastTabToRightEdge = PRS.LastTab && -1 !== PRS.LastTab.Value ? PRS.LastTab.TabRightEdge : false;
|
||
|
||
X = this.private_RecalculateLastTab(PRS.LastTab, X, XEnd, Word, WordLen, SpaceLen);
|
||
|
||
// Добавляем длину пробелов до слова + длина самого слова. Не надо проверять
|
||
// убирается ли слово, мы это проверяем при добавленнии букв.
|
||
X += SpaceLen + WordLen;
|
||
Word = false;
|
||
SpaceLen = 0;
|
||
WordLen = 0;
|
||
|
||
var TabPos = Para.private_RecalculateGetTabPos(PRS, X, ParaPr, PRS.Page, false);
|
||
var NewX = X + TabPos.TabWidth;
|
||
var TabValue = TabPos.TabValue;
|
||
|
||
Item.SetLeader(TabPos.TabLeader, this.Get_CompiledPr(false));
|
||
|
||
PRS.LastTab.TabPos = NewX;
|
||
PRS.LastTab.Value = TabValue;
|
||
PRS.LastTab.X = X;
|
||
PRS.LastTab.Item = Item;
|
||
PRS.LastTab.TabRightEdge = TabPos.TabRightEdge;
|
||
|
||
var nCompatibilityMode = PRS.getCompatibilityMode();
|
||
|
||
// Если таб не левый, значит он не может быть сразу рассчитан, а если левый, тогда
|
||
// рассчитываем его сразу здесь
|
||
if (tab_Left !== TabValue)
|
||
{
|
||
Item.Width = 0;
|
||
|
||
// В Word2013 и раньше, если не левый таб заканчивается правее правой границы, тогда у параграфа
|
||
// правая граница имеет максимально возможное значение (55см)
|
||
if (AscCommon.MMToTwips(NewX) > AscCommon.MMToTwips(XEnd) && nCompatibilityMode <= AscCommon.document_compatibility_mode_Word14)
|
||
{
|
||
// TODO: Временно сделаем так. По-хорошему надо помечать промежуток, что в нем не учитывается границы при расчете переносов,
|
||
// а XEnd не менять
|
||
Para.Lines[PRS.Line].Ranges[PRS.Range].XEndOrigin = Para.Lines[PRS.Line].Ranges[PRS.Range].XEnd;
|
||
Para.Lines[PRS.Line].Ranges[PRS.Range].XEnd = 558.7;
|
||
XEnd = 558.7;
|
||
PRS.XEnd = XEnd;
|
||
PRS.BadLeftTab = true;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// TODO: Если таб расположен между правым полем страницы и правым отступом параграфа (отступ
|
||
// должен быть положительным), то начиная с версии AscCommon.document_compatibility_mode_Word15
|
||
// табы немного неправильно рассчитываются. Смотри файл "Табы. Рассчет табов рядом с правым краем(2016).docx"
|
||
|
||
var twX = AscCommon.MMToTwips(X);
|
||
var twXEnd = AscCommon.MMToTwips(XEnd);
|
||
var twNewX = AscCommon.MMToTwips(NewX);
|
||
|
||
if (nCompatibilityMode <= AscCommon.document_compatibility_mode_Word14
|
||
&& !isLastTabToRightEdge
|
||
&& true !== TabPos.DefaultTab
|
||
&& (twNewX >= twXEnd && XEnd < 558.7 && PRS.Range >= PRS.RangesCount - 1))
|
||
{
|
||
Para.Lines[PRS.Line].Ranges[PRS.Range].XEnd = 558.7;
|
||
XEnd = 558.7;
|
||
PRS.XEnd = XEnd;
|
||
PRS.BadLeftTab = true;
|
||
|
||
twXEnd = AscCommon.MMToTwips(XEnd);
|
||
}
|
||
|
||
if (!PRS.BadLeftTab
|
||
&& (false === FirstItemOnLine || false === Para.IsSingleRangeOnLine(ParaLine, ParaRange))
|
||
&& (((TabPos.DefaultTab || PRS.Range < PRS.RangesCount - 1) && twNewX > twXEnd)
|
||
|| (!TabPos.DefaultTab && twNewX > AscCommon.MMToTwips(TabPos.PageXLimit))))
|
||
{
|
||
WordLen = NewX - X;
|
||
RangeEndPos = Pos;
|
||
NewRange = true;
|
||
}
|
||
else
|
||
{
|
||
Item.Width = NewX - X;
|
||
|
||
X = NewX;
|
||
}
|
||
}
|
||
|
||
// Считаем, что с таба начинается слово
|
||
PRS.Set_LineBreakPos(Pos, FirstItemOnLine);
|
||
|
||
// Если перенос идет по строке, а не из-за обтекания, тогда разрываем перед табом, а если
|
||
// из-за обтекания, тогда разрываем перед последним словом, идущим перед табом
|
||
if (RangesCount === CurRange)
|
||
{
|
||
if (true === StartWord)
|
||
{
|
||
FirstItemOnLine = false;
|
||
EmptyLine = false;
|
||
TextOnLine = true;
|
||
}
|
||
}
|
||
|
||
|
||
StartWord = true;
|
||
Word = true;
|
||
|
||
break;
|
||
}
|
||
case para_NewLine:
|
||
{
|
||
// Сначала проверяем, если у нас уже есть таб, которым мы должны рассчитать, тогда высчитываем
|
||
// его ширину.
|
||
X = this.private_RecalculateLastTab(PRS.LastTab, X, XEnd, Word, WordLen, SpaceLen);
|
||
|
||
X += WordLen;
|
||
|
||
if (true === Word)
|
||
{
|
||
EmptyLine = false;
|
||
TextOnLine = true;
|
||
Word = false;
|
||
X += SpaceLen;
|
||
SpaceLen = 0;
|
||
}
|
||
|
||
let isLineBreak = Item.IsLineBreak();
|
||
if (Item.IsPageBreak() || Item.IsColumnBreak())
|
||
{
|
||
isLineBreak = false;
|
||
PRS.BreakPageLine = true;
|
||
if (Item.IsPageBreak())
|
||
PRS.BreakRealPageLine = true;
|
||
|
||
if (Para.IsTableCellContent() || !Para.IsInline())
|
||
{
|
||
Item.Flags.Use = false;
|
||
continue;
|
||
}
|
||
else if (!(PRS.GetTopDocument() instanceof CDocument))
|
||
{
|
||
// Везде кроме таблиц считаем такие разрывы обычными разрывами строки
|
||
isLineBreak = true;
|
||
}
|
||
else
|
||
{
|
||
if (Item.IsPageBreak() && !Para.CheckSplitPageOnPageBreak(Item))
|
||
continue;
|
||
|
||
Item.Flags.NewLine = true;
|
||
|
||
NewPage = true;
|
||
NewRange = true;
|
||
}
|
||
}
|
||
|
||
if (isLineBreak)
|
||
{
|
||
PRS.BreakLine = true;
|
||
|
||
NewRange = true;
|
||
EmptyLine = false;
|
||
TextOnLine = true;
|
||
|
||
// здесь оставляем проверку, т.к. в случае, если после неинлайновой формулы нах-ся инлайновая необходимо в любом случае сделать перенос (проверка в private_RecalculateRange(), где выставляется PRS.ForceNewLine = true не пройдет)
|
||
if (true === PRS.MathNotInline)
|
||
PRS.ForceNewLine = true;
|
||
}
|
||
|
||
PRS.onEndRecalculateLineRange();
|
||
RangeEndPos = Pos + 1;
|
||
|
||
break;
|
||
}
|
||
case para_End:
|
||
{
|
||
if (true === Word)
|
||
{
|
||
FirstItemOnLine = false;
|
||
EmptyLine = false;
|
||
TextOnLine = true;
|
||
}
|
||
|
||
X += WordLen;
|
||
|
||
if (true === Word)
|
||
{
|
||
X += SpaceLen;
|
||
SpaceLen = 0;
|
||
WordLen = 0;
|
||
}
|
||
|
||
X = this.private_RecalculateLastTab(PRS.LastTab, X, XEnd, Word, WordLen, SpaceLen);
|
||
|
||
NewRange = true;
|
||
End = true;
|
||
|
||
PRS.onEndRecalculateLineRange();
|
||
RangeEndPos = Pos + 1;
|
||
|
||
break;
|
||
}
|
||
case para_FieldChar:
|
||
{
|
||
if (PRS.IsFastRecalculate())
|
||
break;
|
||
|
||
Item.SetXY(X + SpaceLen + WordLen, PRS.Y);
|
||
Item.SetPage(Para.GetAbsolutePage(PRS.Page));
|
||
|
||
Item.SetRun(this);
|
||
PRS.ComplexFields.processFieldChar(Item);
|
||
|
||
isHiddenCFPart = PRS.ComplexFields.isHiddenComplexFieldPart();
|
||
|
||
if (Item.IsSeparate())
|
||
{
|
||
var oComplexField = Item.GetComplexField();
|
||
var oHdrFtr = Para.Parent.IsHdrFtr(true);
|
||
if (oHdrFtr && !oComplexField && this.Paragraph)
|
||
{
|
||
// Т.к. Recalculate_Width запускается после Recalculate_Range, то возможен случай, когда у нас
|
||
// поля еще не собраны, но в колонтитулах они нам нужны уже собранные
|
||
this.Paragraph.ProcessComplexFields();
|
||
oComplexField = Item.GetComplexField();
|
||
}
|
||
|
||
var oInstruction = oComplexField ? oComplexField.GetInstruction() : null;
|
||
|
||
let isHiddenValue = !!(oHdrFtr
|
||
&& oInstruction
|
||
&& (AscWord.fieldtype_NUMPAGES === oInstruction.GetType()
|
||
|| AscWord.fieldtype_PAGE === oInstruction.GetType()
|
||
|| AscWord.fieldtype_FORMULA === oInstruction.GetType()));
|
||
|
||
Item.SetHiddenValue(isHiddenValue);
|
||
}
|
||
else if (Item.IsEnd() && !isHiddenCFPart)
|
||
{
|
||
// Специальная ветка, для полей PAGE и NUMPAGES, находящихся в колонтитуле
|
||
var oComplexField = Item.GetComplexField();
|
||
var oHdrFtr = Para.Parent.IsHdrFtr(true);
|
||
|
||
// TODO: Ранее обработка была на Separate и поле могло быть не собрано, теперь оно на End
|
||
// и такого просиходить не должно
|
||
if (oHdrFtr && !oComplexField && this.Paragraph)
|
||
{
|
||
// Т.к. Recalculate_Width запускается после Recalculate_Range, то возможен случай, когда у нас
|
||
// поля еще не собраны, но в колонтитулах они нам нужны уже собранные
|
||
this.Paragraph.ProcessComplexFields();
|
||
oComplexField = Item.GetComplexField();
|
||
}
|
||
|
||
let isVisualFieldChar = false;
|
||
var oInstruction = oComplexField ? oComplexField.GetInstruction() : null;
|
||
|
||
if (oHdrFtr
|
||
&& oInstruction
|
||
&& (AscWord.fieldtype_NUMPAGES === oInstruction.GetType()
|
||
|| AscWord.fieldtype_PAGE === oInstruction.GetType()
|
||
|| AscWord.fieldtype_FORMULA === oInstruction.GetType()))
|
||
{
|
||
if (AscWord.fieldtype_NUMPAGES === oInstruction.GetType())
|
||
{
|
||
oHdrFtr.Add_PageCountElement(Item);
|
||
|
||
let logicDocument = Para.LogicDocument;
|
||
if (!Item.IsNumValue() && logicDocument && logicDocument.IsDocumentEditor())
|
||
{
|
||
let numFormat = oInstruction.haveNumericFormat() ? oInstruction.getNumericFormat() : Asc.c_oAscNumberingFormat.Decimal;
|
||
Item.SetNumValue(logicDocument.Pages.length, numFormat);
|
||
}
|
||
}
|
||
else if (AscWord.fieldtype_PAGE === oInstruction.GetType())
|
||
{
|
||
let logicDocument = Para.LogicDocument;
|
||
let sectInfo = logicDocument.Get_SectionPageNumInfo2(Para.GetAbsolutePage(PRS.Page));
|
||
let sectPr = logicDocument.GetSections().GetSectPrByIndex(sectInfo.SectIndex);
|
||
let numFormat = oInstruction.haveNumericFormat() ? oInstruction.getNumericFormat() : sectPr.GetPageNumFormat();
|
||
Item.SetNumValue(sectInfo.CurPage, numFormat);
|
||
}
|
||
else
|
||
{
|
||
if (oComplexField.IsHaveNestedNUMPAGES())
|
||
oHdrFtr.Add_PageCountElement(Item);
|
||
|
||
var sValue = oComplexField.CalculateValue();
|
||
var nValue = parseInt(sValue);
|
||
if (isNaN(nValue))
|
||
nValue = 0;
|
||
|
||
Item.SetFormulaValue(nValue);
|
||
}
|
||
isVisualFieldChar = true;
|
||
}
|
||
else if (oComplexField && oComplexField.IsFormCheckBox())
|
||
{
|
||
isVisualFieldChar = true;
|
||
Item.SetFormCheckBox(true);
|
||
}
|
||
else
|
||
{
|
||
Item.SetNumValue(null);
|
||
}
|
||
|
||
if (isVisualFieldChar)
|
||
{
|
||
var oParent = this.GetParent();
|
||
var nRunPos = this.private_GetPosInParent(oParent);
|
||
|
||
// Заглушка на случай, когда настройки текущего рана не совпадают с настройками рана,
|
||
// где расположено значение поля, либо начало поля
|
||
let numValueTextPr = this.Get_CompiledPr(false);
|
||
if (Pos <= 0 && oParent && nRunPos > 0 && oParent.Content[nRunPos - 1] instanceof AscWord.Run)
|
||
numValueTextPr = oParent.Content[nRunPos - 1].Get_CompiledPr(false);
|
||
|
||
g_oTextMeasurer.SetTextPr(numValueTextPr, this.Paragraph.Get_Theme());
|
||
Item.Measure(g_oTextMeasurer, numValueTextPr);
|
||
|
||
// Если до этого было слово, тогда не надо проверять убирается ли оно, но если стояли пробелы,
|
||
// тогда мы их учитываем при проверке убирается ли данный элемент, и добавляем только если
|
||
// данный элемент убирается
|
||
if (true === Word || WordLen > 0)
|
||
{
|
||
// Добавляем длину пробелов до слова + длина самого слова. Не надо проверять
|
||
// убирается ли слово, мы это проверяем при добавленнии букв.
|
||
X += SpaceLen + WordLen;
|
||
|
||
Word = false;
|
||
EmptyLine = false;
|
||
TextOnLine = true;
|
||
SpaceLen = 0;
|
||
WordLen = 0;
|
||
}
|
||
|
||
// Если на строке начиналось какое-то слово, тогда данная строка уже не пустая
|
||
if (true === StartWord)
|
||
FirstItemOnLine = false;
|
||
|
||
var PageNumWidth = Item.GetWidth();
|
||
if (X + SpaceLen + PageNumWidth > XEnd && ( false === FirstItemOnLine || false === Para.IsSingleRangeOnLine(ParaLine, ParaRange) ))
|
||
{
|
||
// Данный элемент не убирается, ставим перенос перед ним
|
||
NewRange = true;
|
||
RangeEndPos = Pos;
|
||
}
|
||
else
|
||
{
|
||
// Добавляем длину пробелов до слова и ширину данного элемента
|
||
X += SpaceLen + PageNumWidth;
|
||
|
||
FirstItemOnLine = false;
|
||
EmptyLine = false;
|
||
TextOnLine = true;
|
||
}
|
||
|
||
SpaceLen = 0;
|
||
}
|
||
}
|
||
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (para_Space !== ItemType)
|
||
{
|
||
PRS.LastItem = Item;
|
||
PRS.LastItemRun = this;
|
||
}
|
||
|
||
if (true === NewRange)
|
||
break;
|
||
}
|
||
}
|
||
|
||
|
||
PRS.MoveToLBP = MoveToLBP;
|
||
PRS.NewRange = NewRange;
|
||
PRS.ForceNewPage = ForceNewPage;
|
||
PRS.NewPage = NewPage;
|
||
PRS.End = End;
|
||
|
||
PRS.Word = Word;
|
||
PRS.StartWord = StartWord;
|
||
PRS.FirstItemOnLine = FirstItemOnLine;
|
||
PRS.EmptyLine = EmptyLine;
|
||
PRS.TextOnLine = TextOnLine;
|
||
|
||
PRS.SpaceLen = SpaceLen;
|
||
PRS.WordLen = WordLen;
|
||
PRS.bMathWordLarge = bMathWordLarge;
|
||
PRS.OperGapRight = OperGapRight;
|
||
PRS.OperGapLeft = OperGapLeft;
|
||
|
||
PRS.X = X;
|
||
PRS.XEnd = XEnd;
|
||
|
||
PRS.bInsideOper = bInsideOper;
|
||
PRS.bContainCompareOper = bContainCompareOper;
|
||
PRS.bEndRunToContent = bEndRunToContent;
|
||
PRS.bNoOneBreakOperator = bNoOneBreakOperator;
|
||
PRS.bForcedBreak = bForcedBreak;
|
||
|
||
|
||
if (this.Type == para_Math_Run)
|
||
{
|
||
if (true === NewRange)
|
||
{
|
||
var WidthLine = X - XRange;
|
||
|
||
if (this.ParaMath.Is_BrkBinBefore() == false)
|
||
WidthLine += SpaceLen;
|
||
|
||
this.ParaMath.UpdateWidthLine(PRS, WidthLine);
|
||
}
|
||
else
|
||
{
|
||
// для пустого Run, обновляем LineBreakPos на случай, если пустой Run находится между break_operator (мат. объект) и мат объектом
|
||
if (this.Content.length == 0)
|
||
{
|
||
if (PRS.bForcedBreak == true)
|
||
{
|
||
PRS.MoveToLBP = true;
|
||
PRS.NewRange = true;
|
||
PRS.Set_LineBreakPos(0, PRS.FirstItemOnLine);
|
||
}
|
||
else if (this.ParaMath.Is_BrkBinBefore() == false && Word == false && PRS.bBreakBox == true)
|
||
{
|
||
PRS.Set_LineBreakPos(Pos, PRS.FirstItemOnLine);
|
||
PRS.X += SpaceLen;
|
||
PRS.SpaceLen = 0;
|
||
}
|
||
}
|
||
|
||
// запоминаем конец Run
|
||
PRS.PosEndRun.Set(PRS.CurPos);
|
||
PRS.PosEndRun.Update2(this.Content.length, Depth);
|
||
}
|
||
}
|
||
|
||
if (!isSkipFillRange)
|
||
{
|
||
if (Pos >= ContentLen)
|
||
RangeEndPos = Pos;
|
||
|
||
this.protected_FillRange(CurLine, CurRange, RangeStartPos, RangeEndPos);
|
||
}
|
||
|
||
this.RecalcInfo.Recalc = false;
|
||
};
|
||
|
||
ParaRun.prototype.Recalculate_Set_RangeEndPos = function(PRS, PRP, Depth)
|
||
{
|
||
var CurLine = PRS.Line - this.StartLine;
|
||
var CurRange = ( 0 === CurLine ? PRS.Range - this.StartRange : PRS.Range );
|
||
var CurPos = PRP.Get(Depth);
|
||
|
||
this.protected_FillRangeEndPos(CurLine, CurRange, CurPos);
|
||
};
|
||
ParaRun.prototype.Recalculate_SetRangeBounds = function(_CurLine, _CurRange, oStartPos, oEndPos, nDepth)
|
||
{
|
||
let isStartPos = oStartPos && nDepth <= oStartPos.GetDepth();
|
||
let isEndPos = oEndPos && nDepth <= oEndPos.GetDepth();
|
||
|
||
let nStartPos = isStartPos ? oStartPos.Get(nDepth) : 0;
|
||
let nEndPos = isEndPos ? oEndPos.Get(nDepth) : this.Content.length;
|
||
|
||
var CurLine = _CurLine - this.StartLine;
|
||
var CurRange = 0 === CurLine ? _CurRange - this.StartRange : _CurRange;
|
||
|
||
|
||
if (isStartPos)
|
||
{
|
||
this.protected_FillRangeEndPos(CurLine, CurRange, nEndPos);
|
||
}
|
||
else
|
||
{
|
||
this.protected_AddRange(CurLine, CurRange);
|
||
this.protected_FillRange(CurLine, CurRange, nStartPos, nEndPos);
|
||
}
|
||
};
|
||
ParaRun.prototype.GetContentWidthInRange = function(oStartPos, oEndPos, nDepth)
|
||
{
|
||
let nWidth = 0;
|
||
|
||
let nStartPos = oStartPos && nDepth <= oStartPos.GetDepth() ? oStartPos.Get(nDepth) : 0;
|
||
let nEndPos = oEndPos && nDepth <= oEndPos.GetDepth() ? oEndPos.Get(nDepth) : this.Content.length;
|
||
|
||
for (let nPos = nStartPos; nPos < nEndPos; ++nPos)
|
||
{
|
||
nWidth += this.Content[nPos].GetInlineWidth();
|
||
}
|
||
|
||
return nWidth;
|
||
};
|
||
ParaRun.prototype.Recalculate_LineMetrics = function(PRS, ParaPr, _CurLine, _CurRange, ContentMetrics)
|
||
{
|
||
var Para = PRS.Paragraph;
|
||
|
||
// Если заданный отрезок пустой, тогда мы не должны учитывать метрики данного рана.
|
||
|
||
var CurLine = _CurLine - this.StartLine;
|
||
var CurRange = ( 0 === CurLine ? _CurRange - this.StartRange : _CurRange );
|
||
|
||
var StartPos = this.protected_GetRangeStartPos(CurLine, CurRange);
|
||
var EndPos = this.protected_GetRangeEndPos(CurLine, CurRange);
|
||
|
||
var UpdateLineMetricsText = false;
|
||
var LineRule = ParaPr.Spacing.LineRule;
|
||
|
||
let textPr = this.Get_CompiledPr(false);
|
||
if (this.IsUseAscFont(textPr))
|
||
{
|
||
textPr = textPr.Copy();
|
||
textPr.RFonts.SetAll("ASCW3");
|
||
}
|
||
// TODO: Пока для формул сделаем, чтобы работало по-старому, в дальнейшем надо будет переделать на fontslot
|
||
let fontSlot = this.IsMathRun() ? AscWord.fontslot_ASCII : AscWord.fontslot_None;
|
||
|
||
let fontMap = {};
|
||
|
||
for (var CurPos = StartPos; CurPos < EndPos; CurPos++)
|
||
{
|
||
var Item = this.private_CheckInstrText(this.Content[CurPos]);
|
||
if (Item === Para.Numbering.Item)
|
||
{
|
||
PRS.LineAscent = Para.Numbering.LineAscent;
|
||
}
|
||
|
||
if (para_Text === Item.Type)
|
||
{
|
||
let fontId = AscFonts.GetGraphemeFontId(Item.GetGrapheme());
|
||
if (fontId)
|
||
{
|
||
let fontSize = Item.GetFontSlot(textPr) === fontslot_CS ? textPr.FontSizeCS : textPr.FontSize;
|
||
if (undefined === fontMap[fontId])
|
||
fontMap[fontId] = fontSize;
|
||
else
|
||
fontMap[fontId] = Math.max(fontSize, fontMap[fontId]);
|
||
}
|
||
UpdateLineMetricsText = true;
|
||
continue;
|
||
}
|
||
|
||
fontSlot |= Item.GetFontSlot(textPr);
|
||
|
||
switch (Item.Type)
|
||
{
|
||
case para_Sym:
|
||
case para_Text:
|
||
case para_PageNum:
|
||
case para_PageCount:
|
||
case para_FootnoteReference:
|
||
case para_FootnoteRef:
|
||
case para_EndnoteReference:
|
||
case para_EndnoteRef:
|
||
case para_Separator:
|
||
case para_ContinuationSeparator:
|
||
{
|
||
UpdateLineMetricsText = true;
|
||
break;
|
||
}
|
||
case para_Math_Text:
|
||
case para_Math_Ampersand:
|
||
case para_Math_Placeholder:
|
||
case para_Math_BreakOperator:
|
||
{
|
||
ContentMetrics.UpdateMetrics(Item.size);
|
||
|
||
break;
|
||
}
|
||
case para_Space:
|
||
{
|
||
break;
|
||
}
|
||
case para_Drawing:
|
||
{
|
||
if (true === Item.Is_Inline() || true === Para.Parent.Is_DrawingShape())
|
||
{
|
||
// Обновим метрики строки
|
||
if (Asc.linerule_Exact === LineRule)
|
||
{
|
||
if (PRS.LineAscent < Item.getHeight())
|
||
PRS.LineAscent = Item.getHeight();
|
||
}
|
||
else
|
||
{
|
||
let yOffset = this.getYOffset();
|
||
if (PRS.LineAscent < Item.getHeight() + yOffset)
|
||
PRS.LineAscent = Item.getHeight() + yOffset;
|
||
|
||
if (PRS.LineDescent < -yOffset)
|
||
PRS.LineDescent = -yOffset;
|
||
}
|
||
}
|
||
|
||
break;
|
||
}
|
||
|
||
case para_End:
|
||
{
|
||
break;
|
||
}
|
||
case para_FieldChar:
|
||
{
|
||
if (Item.IsVisual())
|
||
UpdateLineMetricsText = true;
|
||
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (!UpdateLineMetricsText)
|
||
{
|
||
var oTextForm = this.GetTextForm();
|
||
if (oTextForm && oTextForm.IsComb())
|
||
UpdateLineMetricsText = true;
|
||
}
|
||
|
||
if (UpdateLineMetricsText)
|
||
{
|
||
if (AscWord.fontslot_Unknown === fontSlot)
|
||
fontSlot = textPr.CS || textPr.RTL ? AscWord.fontslot_CS : AscWord.fontslot_ASCII;
|
||
|
||
let metrics = textPr.GetTextMetrics(fontSlot, this.Paragraph.GetTheme());
|
||
|
||
for (let fontId in fontMap)
|
||
{
|
||
let fontName = AscFonts.GetFontNameByFontId(fontId);
|
||
let fontStyle = AscFonts.GetFontStyleByFontId(fontId);
|
||
metrics.Update(fontName, fontMap[fontId], fontStyle);
|
||
}
|
||
|
||
let textDescent = metrics.Descent;
|
||
let textAscent2 = metrics.Ascent;
|
||
let textAscent = textAscent2 + metrics.LineGap;
|
||
|
||
if (Asc.linerule_Exact === LineRule)
|
||
{
|
||
// Смещение не учитывается в метриках строки, когда расстояние между строк точное
|
||
if (PRS.LineAscent < textAscent)
|
||
PRS.LineAscent = textAscent;
|
||
|
||
if (PRS.LineDescent < textDescent)
|
||
PRS.LineDescent = textDescent;
|
||
}
|
||
else
|
||
{
|
||
let yOffset = this.getYOffset();
|
||
|
||
if (yOffset >= 0)
|
||
{
|
||
PRS.LineAscent = Math.max(PRS.LineAscent, textAscent + yOffset);
|
||
textDescent = Math.max(0, textDescent - yOffset);
|
||
}
|
||
else
|
||
{
|
||
PRS.LineDescent = Math.max(PRS.LineDescent, textDescent - yOffset);
|
||
textAscent2 = Math.max(0, textAscent2 + yOffset);
|
||
}
|
||
|
||
textAscent = textAscent2 + metrics.LineGap;
|
||
}
|
||
|
||
// Пересчитаем метрику строки относительно размера данного текста
|
||
if (PRS.LineTextAscent < textAscent)
|
||
PRS.LineTextAscent = textAscent;
|
||
|
||
if (PRS.LineTextAscent2 < textAscent2)
|
||
PRS.LineTextAscent2 = textAscent2;
|
||
|
||
if (PRS.LineTextDescent < textDescent)
|
||
PRS.LineTextDescent = textDescent;
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.Recalculate_Range_Width = function(PRSC, _CurLine, _CurRange)
|
||
{
|
||
var CurLine = _CurLine - this.StartLine;
|
||
var CurRange = ( 0 === CurLine ? _CurRange - this.StartRange : _CurRange );
|
||
|
||
var StartPos = this.protected_GetRangeStartPos(CurLine, CurRange);
|
||
var EndPos = this.protected_GetRangeEndPos(CurLine, CurRange);
|
||
|
||
let textPr = this.Get_CompiledPr(false);
|
||
|
||
// TODO: Сделать возможность показывать инструкцию
|
||
var isHiddenCFPart = PRSC.ComplexFields.isHiddenComplexFieldPart();
|
||
for ( var Pos = StartPos; Pos < EndPos; Pos++ )
|
||
{
|
||
var Item = this.private_CheckInstrText(this.Content[Pos]);
|
||
var ItemType = Item.Type;
|
||
|
||
if (PRSC.ComplexFields.isHiddenFieldContent() && para_End !== ItemType && para_FieldChar !== ItemType)
|
||
continue;
|
||
|
||
if (isHiddenCFPart && para_End !== ItemType && para_FieldChar !== ItemType && para_InstrText !== ItemType)
|
||
continue;
|
||
|
||
if (!isHiddenCFPart && para_InstrText === ItemType)
|
||
ItemType = para_Text;
|
||
|
||
switch( ItemType )
|
||
{
|
||
case para_Sym:
|
||
case para_Text:
|
||
case para_FootnoteReference:
|
||
case para_FootnoteRef:
|
||
case para_EndnoteReference:
|
||
case para_EndnoteRef:
|
||
case para_Separator:
|
||
case para_ContinuationSeparator:
|
||
{
|
||
PRSC.Letters++;
|
||
|
||
if ( true !== PRSC.Word )
|
||
{
|
||
PRSC.Word = true;
|
||
PRSC.Words++;
|
||
}
|
||
|
||
PRSC.Range.W += Item.GetWidth(textPr);
|
||
PRSC.Range.W += PRSC.SpaceLen;
|
||
|
||
PRSC.SpaceLen = 0;
|
||
|
||
// Пробелы перед первым словом в строке не считаем
|
||
if (PRSC.Words > 1)
|
||
PRSC.Spaces += PRSC.SpacesCount;
|
||
else
|
||
PRSC.SpacesSkip += PRSC.SpacesCount;
|
||
|
||
PRSC.SpacesCount = 0;
|
||
|
||
if (Item.IsSpaceAfter())
|
||
PRSC.Word = false;
|
||
|
||
break;
|
||
}
|
||
case para_Math_Text:
|
||
case para_Math_Placeholder:
|
||
case para_Math_Ampersand:
|
||
case para_Math_BreakOperator:
|
||
{
|
||
PRSC.Letters++;
|
||
|
||
PRSC.Range.W += Item.GetWidth() / AscWord.TEXTWIDTH_DIVIDER; // GetWidth рассчитываем ширину с учетом состояний Gaps
|
||
break;
|
||
}
|
||
case para_Space:
|
||
{
|
||
if ( true === PRSC.Word )
|
||
{
|
||
PRSC.Word = false;
|
||
PRSC.SpacesCount = 1;
|
||
PRSC.SpaceLen = Item.GetWidth();
|
||
}
|
||
else
|
||
{
|
||
PRSC.SpacesCount++;
|
||
PRSC.SpaceLen += Item.GetWidth();
|
||
}
|
||
|
||
break;
|
||
}
|
||
case para_Drawing:
|
||
{
|
||
if (!Item.IsInline() && !PRSC.Paragraph.Parent.Is_DrawingShape())
|
||
break;
|
||
|
||
PRSC.Words++;
|
||
PRSC.Range.W += PRSC.SpaceLen;
|
||
|
||
if (PRSC.Words > 1)
|
||
PRSC.Spaces += PRSC.SpacesCount;
|
||
else
|
||
PRSC.SpacesSkip += PRSC.SpacesCount;
|
||
|
||
PRSC.Word = false;
|
||
PRSC.SpacesCount = 0;
|
||
PRSC.SpaceLen = 0;
|
||
|
||
PRSC.Range.W += Item.GetWidth();
|
||
|
||
break;
|
||
}
|
||
case para_PageNum:
|
||
case para_PageCount:
|
||
{
|
||
PRSC.Words++;
|
||
PRSC.Range.W += PRSC.SpaceLen;
|
||
|
||
if (PRSC.Words > 1)
|
||
PRSC.Spaces += PRSC.SpacesCount;
|
||
else
|
||
PRSC.SpacesSkip += PRSC.SpacesCount;
|
||
|
||
PRSC.Word = false;
|
||
PRSC.SpacesCount = 0;
|
||
PRSC.SpaceLen = 0;
|
||
|
||
PRSC.Range.W += Item.GetWidth();
|
||
|
||
break;
|
||
}
|
||
case para_Tab:
|
||
{
|
||
PRSC.Range.W += Item.GetWidth();
|
||
PRSC.Range.W += PRSC.SpaceLen;
|
||
|
||
// Учитываем только слова и пробелы, идущие после последнего таба
|
||
|
||
PRSC.LettersSkip += PRSC.Letters;
|
||
PRSC.SpacesSkip += PRSC.Spaces;
|
||
|
||
PRSC.Words = 0;
|
||
PRSC.Spaces = 0;
|
||
PRSC.Letters = 0;
|
||
|
||
PRSC.SpaceLen = 0;
|
||
PRSC.SpacesCount = 0;
|
||
PRSC.Word = false;
|
||
|
||
break;
|
||
}
|
||
|
||
case para_NewLine:
|
||
{
|
||
if (true === PRSC.Word && PRSC.Words > 1)
|
||
PRSC.Spaces += PRSC.SpacesCount;
|
||
|
||
PRSC.SpacesCount = 0;
|
||
PRSC.Word = false;
|
||
PRSC.LineBreak = true;
|
||
|
||
break;
|
||
}
|
||
case para_End:
|
||
{
|
||
if ( true === PRSC.Word )
|
||
PRSC.Spaces += PRSC.SpacesCount;
|
||
|
||
PRSC.ParaEnd = true;
|
||
|
||
break;
|
||
}
|
||
case para_FieldChar:
|
||
{
|
||
if (PRSC.isFastRecalculation())
|
||
PRSC.ComplexFields.processFieldChar(Item);
|
||
else
|
||
PRSC.ComplexFields.processFieldCharAndCollectComplexField(Item);
|
||
|
||
isHiddenCFPart = PRSC.ComplexFields.isHiddenComplexFieldPart();
|
||
|
||
if (Item.IsVisual())
|
||
{
|
||
PRSC.Words++;
|
||
PRSC.Range.W += PRSC.SpaceLen;
|
||
|
||
if (PRSC.Words > 1)
|
||
PRSC.Spaces += PRSC.SpacesCount;
|
||
else
|
||
PRSC.SpacesSkip += PRSC.SpacesCount;
|
||
|
||
PRSC.Word = false;
|
||
PRSC.SpacesCount = 0;
|
||
PRSC.SpaceLen = 0;
|
||
|
||
PRSC.Range.W += Item.GetWidth();
|
||
}
|
||
|
||
break;
|
||
}
|
||
case para_InstrText:
|
||
{
|
||
if (PRSC.isFastRecalculation()
|
||
|| reviewtype_Remove === this.GetReviewType())
|
||
break;
|
||
|
||
PRSC.ComplexFields.processInstruction(Item);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.Recalculate_Range_Spaces = function(PRSA, _CurLine, _CurRange, CurPage)
|
||
{
|
||
var CurLine = _CurLine - this.StartLine;
|
||
var CurRange = ( 0 === CurLine ? _CurRange - this.StartRange : _CurRange );
|
||
|
||
var StartPos = this.protected_GetRangeStartPos(CurLine, CurRange);
|
||
var EndPos = this.protected_GetRangeEndPos(CurLine, CurRange);
|
||
|
||
// TODO: Сделать возможность показывать инструкцию
|
||
var isHiddenCFPart = PRSA.ComplexFields.isHiddenComplexFieldPart();
|
||
for ( var Pos = StartPos; Pos < EndPos; Pos++ )
|
||
{
|
||
var Item = this.private_CheckInstrText(this.Content[Pos]);
|
||
var ItemType = Item.Type;
|
||
|
||
if (PRSA.ComplexFields.isHiddenFieldContent() && para_End !== ItemType && para_FieldChar !== ItemType)
|
||
{
|
||
// Чтобы правильно позиционировался курсор и селект
|
||
Item.WidthVisible = 0;
|
||
continue;
|
||
}
|
||
|
||
if (isHiddenCFPart && para_End !== ItemType && para_FieldChar !== ItemType)
|
||
{
|
||
Item.WidthVisible = 0;
|
||
continue;
|
||
}
|
||
|
||
switch( ItemType )
|
||
{
|
||
case para_Sym:
|
||
case para_Text:
|
||
case para_FootnoteReference:
|
||
case para_FootnoteRef:
|
||
case para_EndnoteReference:
|
||
case para_EndnoteRef:
|
||
case para_Separator:
|
||
case para_ContinuationSeparator:
|
||
{
|
||
let WidthVisible = 0;
|
||
|
||
if ( 0 !== PRSA.LettersSkip )
|
||
{
|
||
WidthVisible = Item.GetWidth();
|
||
PRSA.LettersSkip--;
|
||
}
|
||
else
|
||
WidthVisible = Item.GetWidth() + PRSA.JustifyWord;
|
||
|
||
Item.SetWidthVisible(WidthVisible, this.Get_CompiledPr(false));
|
||
|
||
if (para_FootnoteReference === ItemType || para_EndnoteReference === ItemType)
|
||
{
|
||
var oFootnote = Item.GetFootnote();
|
||
oFootnote.UpdatePositionInfo(this.Paragraph, this, _CurLine, _CurRange, PRSA.X, WidthVisible);
|
||
}
|
||
|
||
PRSA.X += WidthVisible;
|
||
PRSA.LastW = WidthVisible;
|
||
|
||
break;
|
||
}
|
||
case para_Math_Text:
|
||
case para_Math_Placeholder:
|
||
case para_Math_BreakOperator:
|
||
case para_Math_Ampersand:
|
||
{
|
||
var WidthVisible = Item.GetWidth() / AscWord.TEXTWIDTH_DIVIDER; // GetWidth рассчитываем ширину с учетом состояний Gaps
|
||
Item.WidthVisible = (WidthVisible * AscWord.TEXTWIDTH_DIVIDER)| 0;//Item.SetWidthVisible(WidthVisible);
|
||
|
||
PRSA.X += WidthVisible;
|
||
PRSA.LastW = WidthVisible;
|
||
|
||
break;
|
||
}
|
||
case para_Space:
|
||
{
|
||
var WidthVisible = Item.GetWidth();
|
||
|
||
if ( 0 !== PRSA.SpacesSkip )
|
||
{
|
||
PRSA.SpacesSkip--;
|
||
}
|
||
else if ( 0 !== PRSA.SpacesCounter )
|
||
{
|
||
WidthVisible += PRSA.JustifySpace;
|
||
PRSA.SpacesCounter--;
|
||
}
|
||
|
||
Item.SetWidthVisible(WidthVisible);
|
||
|
||
PRSA.X += WidthVisible;
|
||
PRSA.LastW = WidthVisible;
|
||
|
||
break;
|
||
}
|
||
case para_Drawing:
|
||
{
|
||
Item.SetForceNoWrap(false);
|
||
|
||
var Para = PRSA.Paragraph;
|
||
var isInHdrFtr = Para.Parent.IsHdrFtr();
|
||
|
||
var PageAbs = Para.GetAbsolutePage(CurPage);
|
||
var PageRel = Para.GetRelativePage(CurPage);
|
||
var ColumnAbs = Para.GetAbsoluteColumn(CurPage);
|
||
|
||
var LogicDocument = PRSA.getLogicDocument();
|
||
var LD_PageLimits = LogicDocument.Get_PageLimits(PageAbs);
|
||
var LD_PageFields = LogicDocument.Get_PageFields(PageAbs, isInHdrFtr);
|
||
|
||
var Page_Width = LD_PageLimits.XLimit;
|
||
var Page_Height = LD_PageLimits.YLimit;
|
||
|
||
var DrawingObjects = Para.Parent.DrawingObjects;
|
||
var PageLimits = Para.Parent.Get_PageLimits(PageRel);
|
||
var PageFields = Para.Parent.Get_PageFields(PageRel, isInHdrFtr);
|
||
|
||
var X_Left_Field = PageFields.X;
|
||
var Y_Top_Field = PageFields.Y;
|
||
var X_Right_Field = PageFields.XLimit;
|
||
var Y_Bottom_Field = PageFields.YLimit;
|
||
|
||
var X_Left_Margin = PageFields.X - PageLimits.X;
|
||
var Y_Top_Margin = PageFields.Y - PageLimits.Y;
|
||
var X_Right_Margin = PageLimits.XLimit - PageFields.XLimit;
|
||
var Y_Bottom_Margin = PageLimits.YLimit - PageFields.YLimit;
|
||
|
||
var isTableCellContent = Para.IsTableCellContent();
|
||
var isUseWrap = Item.Use_TextWrap();
|
||
var isLayoutInCell = Item.IsLayoutInCell();
|
||
|
||
// TODO: Надо здесь почистить все, а то названия переменных путаются, и некоторые имеют неправильное значение
|
||
|
||
if (isTableCellContent && !isLayoutInCell)
|
||
{
|
||
X_Left_Field = LD_PageFields.X;
|
||
Y_Top_Field = LD_PageFields.Y;
|
||
X_Right_Field = LD_PageFields.XLimit;
|
||
Y_Bottom_Field = LD_PageFields.YLimit;
|
||
|
||
X_Left_Margin = X_Left_Field;
|
||
X_Right_Margin = Page_Width - X_Right_Field;
|
||
Y_Bottom_Margin = Page_Height - Y_Bottom_Field;
|
||
Y_Top_Margin = Y_Top_Field;
|
||
}
|
||
|
||
var _CurPage = 0;
|
||
if (0 !== PageAbs && CurPage > ColumnAbs)
|
||
_CurPage = CurPage - ColumnAbs;
|
||
|
||
var ColumnStartX, ColumnEndX;
|
||
if (0 === CurPage)
|
||
{
|
||
// Нужно обновлять, т.к. картинка могла быть внутри данного параграфа и она могла изменить
|
||
// позицию привязки, а при этом в функцию Para.Reset мы не зашли (баг #44739)
|
||
if (Para.Parent.RecalcInfo.Can_RecalcObject() && 0 === CurLine)
|
||
Para.private_RecalculateColumnLimits();
|
||
|
||
ColumnStartX = Para.X_ColumnStart;
|
||
ColumnEndX = Para.X_ColumnEnd;
|
||
}
|
||
else
|
||
{
|
||
ColumnStartX = Para.Pages[_CurPage].X;
|
||
ColumnEndX = Para.Pages[_CurPage].XLimit;
|
||
}
|
||
|
||
var Top_Margin = Y_Top_Margin;
|
||
var Bottom_Margin = Y_Bottom_Margin;
|
||
var Page_H = Page_Height;
|
||
|
||
if (isTableCellContent && isUseWrap)
|
||
{
|
||
Top_Margin = 0;
|
||
Bottom_Margin = 0;
|
||
Page_H = 0;
|
||
}
|
||
|
||
var PageLimitsOrigin = Para.Parent.Get_PageLimits(PageRel);
|
||
if (isTableCellContent && !isLayoutInCell)
|
||
{
|
||
PageLimitsOrigin = LogicDocument.Get_PageLimits(PageAbs);
|
||
var PageFieldsOrigin = LogicDocument.Get_PageFields(PageAbs, isInHdrFtr);
|
||
ColumnStartX = PageFieldsOrigin.X;
|
||
ColumnEndX = PageFieldsOrigin.XLimit;
|
||
}
|
||
|
||
let isInTable = isTableCellContent && isLayoutInCell;
|
||
|
||
if (!isUseWrap)
|
||
{
|
||
PageFields.X = X_Left_Field;
|
||
PageFields.Y = Y_Top_Field;
|
||
PageFields.XLimit = X_Right_Field;
|
||
PageFields.YLimit = Y_Bottom_Field;
|
||
|
||
if (!isTableCellContent || !isLayoutInCell)
|
||
{
|
||
PageLimits.X = 0;
|
||
PageLimits.Y = 0;
|
||
PageLimits.XLimit = Page_Width;
|
||
PageLimits.YLimit = Page_Height;
|
||
}
|
||
}
|
||
|
||
if ( true === Item.Is_Inline() || true === Para.Parent.Is_DrawingShape() )
|
||
{
|
||
if (linerule_Exact === Para.Get_CompiledPr2(false).ParaPr.Spacing.LineRule)
|
||
Item.SetVerticalClip(PRSA.getLineTop(), PRSA.getLineBottom());
|
||
else
|
||
Item.SetVerticalClip(null, null);
|
||
|
||
Item.Update_Position(PRSA.Paragraph, new CParagraphLayout( PRSA.X, PRSA.Y , PageAbs, PRSA.LastW, ColumnStartX, ColumnEndX, X_Left_Margin, X_Right_Margin, Page_Width, Top_Margin, Bottom_Margin, Page_H, PageFields.X, PageFields.Y, Para.Pages[CurPage].Y + Para.Lines[CurLine].Y - Para.Lines[CurLine].Metrics.Ascent, Para.Pages[CurPage].Y), PageLimits, PageLimitsOrigin, _CurLine, isInTable);
|
||
Item.Reset_SavedPosition();
|
||
|
||
PRSA.X += Item.WidthVisible;
|
||
PRSA.LastW = Item.WidthVisible;
|
||
}
|
||
else if (!Item.IsSkipOnRecalculate())
|
||
{
|
||
Para.Pages[CurPage].Add_Drawing(Item);
|
||
|
||
if ( true === PRSA.RecalcFast )
|
||
{
|
||
// Если у нас быстрый пересчет, тогда мы не трогаем плавающие картинки
|
||
// TODO: Если здесь привязка к символу, тогда быстрый пересчет надо отменить
|
||
break;
|
||
}
|
||
|
||
if (true === PRSA.RecalcFast2)
|
||
{
|
||
// Тут мы должны сравнить положение картинок
|
||
var oRecalcObj = Item.SaveRecalculateObject();
|
||
Item.Update_Position(PRSA.Paragraph, new CParagraphLayout( PRSA.X, PRSA.Y , PageAbs, PRSA.LastW, ColumnStartX, ColumnEndX, X_Left_Margin, X_Right_Margin, Page_Width, Top_Margin, Bottom_Margin, Page_H, PageFields.X, PageFields.Y, Para.Pages[CurPage].Y + Para.Lines[CurLine].Y - Para.Lines[CurLine].Metrics.Ascent, Para.Pages[_CurPage].Y), PageLimits, PageLimitsOrigin, _CurLine, isInTable);
|
||
|
||
if (Math.abs(Item.X - oRecalcObj.X) > 0.001 || Math.abs(Item.Y - oRecalcObj.Y) > 0.001 || Item.PageNum !== oRecalcObj.PageNum)
|
||
{
|
||
// Положение картинок не совпало, отправляем пересчет текущей страницы.
|
||
PRSA.RecalcResult = recalcresult_CurPage | recalcresultflags_Page;
|
||
return;
|
||
}
|
||
|
||
break;
|
||
}
|
||
|
||
// У нас Flow-объект. Если он с обтеканием, тогда мы останавливаем пересчет и
|
||
// запоминаем текущий объект. В функции Internal_Recalculate_2 пересчитываем
|
||
// его позицию и сообщаем ее внешнему классу.
|
||
|
||
// Не учитываем обтекание, если у нас на странице больше 100 объектов с обтеканием (баг 73462)
|
||
if (isUseWrap
|
||
&& DrawingObjects && DrawingObjects.graphicPages
|
||
&& DrawingObjects.graphicPages[PageAbs]
|
||
&& DrawingObjects.graphicPages[PageAbs].beforeTextObjects.length >= 100)
|
||
{
|
||
isUseWrap = false;
|
||
let LDRecalcInfo = Para.Parent.RecalcInfo;
|
||
if (LDRecalcInfo.FlowObject)
|
||
LDRecalcInfo.Reset();
|
||
}
|
||
|
||
if (isUseWrap)
|
||
{
|
||
var LogicDocument = Para.Parent;
|
||
var LDRecalcInfo = Para.Parent.RecalcInfo;
|
||
if ( true === LDRecalcInfo.Can_RecalcObject() )
|
||
{
|
||
// Обновляем позицию объекта
|
||
Item.Update_Position(PRSA.Paragraph, new CParagraphLayout( PRSA.X, PRSA.Y , PageAbs, PRSA.LastW, ColumnStartX, ColumnEndX, X_Left_Margin, X_Right_Margin, Page_Width, Top_Margin, Bottom_Margin, Page_H, PageFields.X, PageFields.Y, Para.Pages[CurPage].Y + Para.Lines[_CurLine].Y - Para.Lines[_CurLine].Metrics.Ascent, Para.Pages[_CurPage].Y), PageLimits, PageLimitsOrigin, _CurLine, isInTable);
|
||
|
||
// For headers we do not check for exceeding lower bound in this case
|
||
if (!isInHdrFtr
|
||
&& PRSA.getCompatibilityMode() >= AscCommon.document_compatibility_mode_Word15
|
||
&& 0 === CurPage
|
||
&& !PRSA.isParagraphStartFromNewPage()
|
||
&& Item.Get_Bounds().Bottom >= Y_Bottom_Field
|
||
&& Item.IsMoveWithTextVertically())
|
||
{
|
||
// TODO: По хорошему надо пересчитать заново всю текущую страницу с условием, что заданный параграф начинается с новой страницы
|
||
Para.StartFromNewPage();
|
||
PRSA.RecalcResult = recalcresult_NextPage;
|
||
}
|
||
else
|
||
{
|
||
LDRecalcInfo.Set_FlowObject(Item, 0, recalcresult_NextElement, -1);
|
||
|
||
// TODO: Добавить проверку на не попадание в предыдущие колонки
|
||
if (0 === PRSA.CurPage && Item.wrappingPolygon.top > PRSA.PageY + 0.001 && Item.wrappingPolygon.left > PRSA.PageX + 0.001)
|
||
PRSA.RecalcResult = recalcresult_CurPagePara;
|
||
else
|
||
PRSA.RecalcResult = recalcresult_CurPage | recalcresultflags_Page;
|
||
}
|
||
|
||
return;
|
||
}
|
||
else if ( true === LDRecalcInfo.Check_FlowObject(Item) )
|
||
{
|
||
// Если мы находимся с таблице, тогда делаем как Word, не пересчитываем предыдущую страницу,
|
||
// даже если это необходимо. Такое поведение нужно для точного определения рассчиталась ли
|
||
// данная страница окончательно или нет. Если у нас будет ветка с переходом на предыдущую страницу,
|
||
// тогда не рассчитав следующую страницу мы о конечном рассчете текущей страницы не узнаем.
|
||
|
||
// Если данный объект нашли, значит он уже был рассчитан и нам надо проверить номер страницы.
|
||
// Заметим, что даже если картинка привязана к колонке, и после пересчета место привязки картинки
|
||
// сдвигается в следующую колонку, мы проверяем все равно только реальную страницу (без
|
||
// учета колонок, так делает и Word).
|
||
if ( Item.PageNum === PageAbs )
|
||
{
|
||
if (LDRecalcInfo.IsForceNoWrap())
|
||
{
|
||
Item.SetForceNoWrap(true);
|
||
Item.Update_Position(PRSA.Paragraph, new CParagraphLayout( PRSA.X, PRSA.Y , PageAbs, PRSA.LastW, ColumnStartX, ColumnEndX, X_Left_Margin, X_Right_Margin, Page_Width, Top_Margin, Bottom_Margin, Page_H, PageFields.X, PageFields.Y, Para.Pages[CurPage].Y + Para.Lines[_CurLine].Y - Para.Lines[_CurLine].Metrics.Ascent, Para.Pages[_CurPage].Y), PageLimits, PageLimitsOrigin, _CurLine, isInTable);
|
||
}
|
||
|
||
// Все нормально, можно продолжить пересчет
|
||
LDRecalcInfo.Reset();
|
||
Item.Reset_SavedPosition();
|
||
}
|
||
else if (isTableCellContent)
|
||
{
|
||
// Картинка не на нужной странице, но так как это таблица
|
||
// мы пересчитываем заново текущую страницу, а не предыдущую
|
||
|
||
// Обновляем позицию объекта
|
||
Item.Update_Position(PRSA.Paragraph, new CParagraphLayout( PRSA.X, PRSA.Y, PageAbs, PRSA.LastW, ColumnStartX, ColumnEndX, X_Left_Margin, X_Right_Margin, Page_Width, Top_Margin, Bottom_Margin, Page_H, PageFields.X, PageFields.Y, Para.Pages[CurPage].Y + Para.Lines[CurLine].Y - Para.Lines[CurLine].Metrics.Ascent, Para.Pages[_CurPage].Y), PageLimits, PageLimitsOrigin, _CurLine, isInTable);
|
||
|
||
LDRecalcInfo.Set_FlowObject( Item, 0, recalcresult_NextElement, -1 );
|
||
LDRecalcInfo.Set_PageBreakBefore( false );
|
||
PRSA.RecalcResult = recalcresult_CurPage | recalcresultflags_Page;
|
||
return;
|
||
}
|
||
else
|
||
{
|
||
LDRecalcInfo.Set_PageBreakBefore( true );
|
||
DrawingObjects.removeById( Item.PageNum, Item.Get_Id() );
|
||
PRSA.RecalcResult = recalcresult_PrevPage | recalcresultflags_Page;
|
||
return;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// Либо данный элемент уже обработан, либо будет обработан в будущем
|
||
}
|
||
|
||
continue;
|
||
}
|
||
else
|
||
{
|
||
let nParaTop = Para.Pages[_CurPage].Y;
|
||
let nLineTop = Para.Pages[CurPage].Y + Para.Lines[CurLine].Y - Para.Lines[CurLine].Metrics.Ascent;
|
||
|
||
// ColumnStartX и ParaTop считаются по тексту, смотри баг #50253
|
||
let compatibilityMode = LogicDocument && LogicDocument.IsDocumentEditor() ? LogicDocument.GetCompatibilityMode() : AscCommon.document_compatibility_mode_Current;
|
||
if (compatibilityMode <= AscCommon.document_compatibility_mode_Word14)
|
||
{
|
||
let nPageStartLine = Para.Pages[_CurPage].StartLine;
|
||
nParaTop = Para.Pages[_CurPage].Y + Para.Lines[nPageStartLine].Top;
|
||
if (Para.Lines[nPageStartLine].Ranges.length > 1)
|
||
{
|
||
var arrTempRanges = Para.Lines[nPageStartLine].Ranges;
|
||
for (var nTempCurRange = 0, nTempRangesCount = arrTempRanges.length; nTempCurRange < nTempRangesCount; ++nTempCurRange)
|
||
{
|
||
if (arrTempRanges[nTempCurRange].W > 0.001 || arrTempRanges[nTempCurRange].WEnd > 0.001)
|
||
{
|
||
ColumnStartX = arrTempRanges[nTempCurRange].X;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// Картинка ложится на или под текст, в данном случае пересчет можно спокойно продолжать
|
||
Item.Update_Position(PRSA.Paragraph, new CParagraphLayout(PRSA.X, PRSA.Y, PageAbs, PRSA.LastW, ColumnStartX, ColumnEndX, X_Left_Margin, X_Right_Margin, Page_Width, Top_Margin, Bottom_Margin, Page_H, PageFields.X, PageFields.Y, nLineTop, nParaTop), PageLimits, PageLimitsOrigin, _CurLine, isInTable);
|
||
Item.Reset_SavedPosition();
|
||
}
|
||
}
|
||
|
||
|
||
break;
|
||
}
|
||
case para_PageNum:
|
||
case para_PageCount:
|
||
{
|
||
PRSA.X += Item.WidthVisible;
|
||
PRSA.LastW = Item.WidthVisible;
|
||
|
||
break;
|
||
}
|
||
case para_Tab:
|
||
{
|
||
PRSA.X += Item.GetWidthVisible();
|
||
|
||
break;
|
||
}
|
||
case para_End:
|
||
{
|
||
Item.CheckMark(PRSA.Paragraph, PRSA.RTL ? PRSA.LeftSpace : PRSA.XEnd - PRSA.X);
|
||
let paraEndW = Item.GetWidthVisible();
|
||
PRSA.Range.WEnd = paraEndW;
|
||
PRSA.X += paraEndW;
|
||
|
||
break;
|
||
}
|
||
case para_NewLine:
|
||
{
|
||
if (Item.IsPageBreak() || Item.IsColumnBreak())
|
||
Item.Update_String(PRSA.RTL ? PRSA.LeftSpace : PRSA.XEnd - PRSA.X);
|
||
|
||
let breakW = Item.GetWidthVisible();
|
||
PRSA.Range.WBreak = breakW;
|
||
PRSA.X += breakW;
|
||
|
||
break;
|
||
}
|
||
case para_FieldChar:
|
||
{
|
||
PRSA.ComplexFields.processFieldChar(Item);
|
||
isHiddenCFPart = PRSA.ComplexFields.isHiddenComplexFieldPart();
|
||
|
||
if (Item.IsVisual())
|
||
{
|
||
PRSA.X += Item.GetWidthVisible();
|
||
PRSA.LastW = Item.GetWidthVisible();
|
||
}
|
||
|
||
break;
|
||
}
|
||
|
||
}
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.Recalculate_PageEndInfo = function(PRSI, _CurLine, _CurRange)
|
||
{
|
||
var CurLine = _CurLine - this.StartLine;
|
||
var CurRange = ( 0 === CurLine ? _CurRange - this.StartRange : _CurRange );
|
||
|
||
var StartPos = this.protected_GetRangeStartPos(CurLine, CurRange);
|
||
var EndPos = this.protected_GetRangeEndPos(CurLine, CurRange);
|
||
|
||
for (var Pos = StartPos; Pos < EndPos; ++Pos)
|
||
{
|
||
var Item = this.Content[Pos];
|
||
if (para_FieldChar === Item.Type)
|
||
{
|
||
PRSI.processFieldChar(Item);
|
||
}
|
||
}
|
||
};
|
||
ParaRun.prototype.RecalculateEndInfo = function(PRSI)
|
||
{
|
||
var isRemovedInReview = (reviewtype_Remove === this.GetReviewType());
|
||
|
||
if (PRSI.isFastRecalculation() || (this.Paragraph && this.Paragraph.bFromDocument === false))
|
||
return;
|
||
|
||
for (var nCurPos = 0, nCount = this.Content.length; nCurPos < nCount; ++nCurPos)
|
||
{
|
||
var oItem = this.Content[nCurPos];
|
||
if (para_FieldChar === oItem.Type)
|
||
{
|
||
PRSI.processFieldCharAndCollectComplexField(oItem);
|
||
}
|
||
else if (para_InstrText === oItem.Type && !isRemovedInReview)
|
||
{
|
||
PRSI.processInstruction(oItem);
|
||
}
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.private_RecalculateNumbering = function(PRS, Item, ParaPr, _X)
|
||
{
|
||
var X = PRS.Recalculate_Numbering(Item, this, ParaPr, _X);
|
||
|
||
// Запоминаем, что на данном элементе была добавлена нумерация
|
||
this.RecalcInfo.NumberingAdd = false;
|
||
this.RecalcInfo.NumberingUse = true;
|
||
this.RecalcInfo.NumberingItem = PRS.Paragraph.Numbering;
|
||
|
||
return X;
|
||
};
|
||
|
||
ParaRun.prototype.private_RecalculateLastTab = function(LastTab, X, XEnd, Word, WordLen, SpaceLen)
|
||
{
|
||
if (tab_Left === LastTab.Value)
|
||
{
|
||
LastTab.Reset();
|
||
}
|
||
else if ( -1 !== LastTab.Value )
|
||
{
|
||
var TempXPos = X;
|
||
|
||
if ( true === Word || WordLen > 0 )
|
||
TempXPos += SpaceLen + WordLen;
|
||
|
||
var TabItem = LastTab.Item;
|
||
var TabStartX = LastTab.X;
|
||
var TabRangeW = TempXPos - TabStartX;
|
||
var TabValue = LastTab.Value;
|
||
var TabPos = LastTab.TabPos;
|
||
|
||
var oLogicDocument = this.Paragraph ? this.Paragraph.LogicDocument : null;
|
||
var nCompatibilityMode = oLogicDocument && oLogicDocument.GetCompatibilityMode ? oLogicDocument.GetCompatibilityMode() : AscCommon.document_compatibility_mode_Current;
|
||
|
||
if (AscCommon.MMToTwips(TabPos) > AscCommon.MMToTwips(XEnd) && nCompatibilityMode >= AscCommon.document_compatibility_mode_Word15)
|
||
{
|
||
TabValue = tab_Right;
|
||
TabPos = XEnd;
|
||
}
|
||
|
||
var TabCalcW = 0;
|
||
if ( tab_Right === TabValue )
|
||
TabCalcW = Math.max( TabPos - (TabStartX + TabRangeW), 0 );
|
||
else if ( tab_Center === TabValue )
|
||
TabCalcW = Math.max( TabPos - (TabStartX + TabRangeW / 2), 0 );
|
||
|
||
if ( X + TabCalcW > LastTab.PageXLimit )
|
||
TabCalcW = LastTab.PageXLimit - X;
|
||
|
||
TabItem.Width = TabCalcW;
|
||
TabItem.WidthVisible = TabCalcW;
|
||
|
||
LastTab.Reset();
|
||
|
||
return X + TabCalcW;
|
||
}
|
||
|
||
return X;
|
||
};
|
||
/**
|
||
* Специальная функия для проверки InstrText. Если InstrText идет не между Begin и Separate сложного поля, тогда
|
||
* мы заменяем его обычным текстовым элементом.
|
||
* @param oItem
|
||
*/
|
||
ParaRun.prototype.private_CheckInstrText = function(oItem)
|
||
{
|
||
if (!oItem)
|
||
return oItem;
|
||
|
||
if (para_InstrText !== oItem.Type)
|
||
return oItem;
|
||
|
||
var oReplacement = oItem.GetReplacementItem();
|
||
return (oReplacement ? oReplacement : oItem);
|
||
};
|
||
|
||
ParaRun.prototype.Refresh_RecalcData = function(oData)
|
||
{
|
||
let oPara = this.GetParagraph();
|
||
if (this.IsMathRun())
|
||
{
|
||
if (this.Parent !== null && this.Parent !== undefined)
|
||
{
|
||
this.Parent.Refresh_RecalcData();
|
||
}
|
||
}
|
||
else if (-1 !== this.StartLine && oPara)
|
||
{
|
||
var nCurLine = this.StartLine;
|
||
|
||
if (oData instanceof CChangesRunAddItem || oData instanceof CChangesRunRemoveItem)
|
||
{
|
||
nCurLine = -1;
|
||
var nChangePos = oData.GetMinPos();
|
||
for (var nLine = 0, nLinesCount = this.protected_GetLinesCount(); nLine < nLinesCount; ++nLine)
|
||
{
|
||
for (var nRange = 0, nRangesCount = this.protected_GetRangesCount(nLine); nRange < nRangesCount; ++nRange)
|
||
{
|
||
var nStartPos = this.protected_GetRangeStartPos(nLine, nRange);
|
||
var nEndPos = this.protected_GetRangeEndPos(nLine, nRange);
|
||
|
||
if (nStartPos <= nChangePos && nChangePos < nEndPos)
|
||
{
|
||
nCurLine = nLine + this.StartLine;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (-1 !== nCurLine)
|
||
break;
|
||
}
|
||
|
||
if (-1 === nCurLine)
|
||
nCurLine = this.StartLine + this.protected_GetLinesCount() - 1;
|
||
}
|
||
|
||
for (var nCurPage = 0, nPagesCount = oPara.GetPagesCount(); nCurPage < nPagesCount; ++nCurPage)
|
||
{
|
||
var oPage = oPara.Pages[nCurPage];
|
||
if (oPage.StartLine <= nCurLine && nCurLine <= oPage.EndLine)
|
||
{
|
||
oPara.Refresh_RecalcData2(nCurPage);
|
||
return;
|
||
}
|
||
}
|
||
|
||
oPara.Refresh_RecalcData2(0);
|
||
}
|
||
else if (oPara)
|
||
{
|
||
oPara.Refresh_RecalcData2();
|
||
}
|
||
};
|
||
ParaRun.prototype.Refresh_RecalcData2 = function()
|
||
{
|
||
this.Refresh_RecalcData();
|
||
};
|
||
ParaRun.prototype.SaveRecalculateObject = function(Copy)
|
||
{
|
||
var RecalcObj = new CRunRecalculateObject(this.StartLine, this.StartRange);
|
||
RecalcObj.Save_Lines( this, Copy );
|
||
RecalcObj.SaveRunContent(this, Copy);
|
||
return RecalcObj;
|
||
};
|
||
ParaRun.prototype.LoadRecalculateObject = function(RecalcObj)
|
||
{
|
||
RecalcObj.Load_Lines(this);
|
||
RecalcObj.LoadRunContent(this);
|
||
};
|
||
ParaRun.prototype.PrepareRecalculateObject = function()
|
||
{
|
||
this.protected_ClearLines();
|
||
|
||
var Count = this.Content.length;
|
||
for (var Index = 0; Index < Count; Index++)
|
||
{
|
||
var Item = this.Content[Index];
|
||
var ItemType = Item.Type;
|
||
|
||
if (para_PageNum === ItemType || para_Drawing === ItemType)
|
||
Item.PrepareRecalculateObject();
|
||
}
|
||
};
|
||
ParaRun.prototype.IsEmptyRange = function(_CurLine, _CurRange)
|
||
{
|
||
var CurLine = _CurLine - this.StartLine;
|
||
var CurRange = ( 0 === CurLine ? _CurRange - this.StartRange : _CurRange );
|
||
|
||
var StartPos = this.protected_GetRangeStartPos(CurLine, CurRange);
|
||
var EndPos = this.protected_GetRangeEndPos(CurLine, CurRange);
|
||
|
||
if (EndPos <= StartPos)
|
||
return true;
|
||
|
||
return false;
|
||
};
|
||
|
||
ParaRun.prototype.Check_Range_OnlyMath = function(Checker, _CurRange, _CurLine)
|
||
{
|
||
var CurLine = _CurLine - this.StartLine;
|
||
var CurRange = ( 0 === CurLine ? _CurRange - this.StartRange : _CurRange );
|
||
|
||
var StartPos = this.protected_GetRangeStartPos(CurLine, CurRange);
|
||
var EndPos = this.protected_GetRangeEndPos(CurLine, CurRange);
|
||
|
||
for (var Pos = StartPos; Pos < EndPos; Pos++)
|
||
{
|
||
var Item = this.Content[Pos];
|
||
var ItemType = Item.Type;
|
||
|
||
if (para_End === ItemType || para_NewLine === ItemType || (para_Drawing === ItemType && true !== Item.Is_Inline()))
|
||
continue;
|
||
else
|
||
{
|
||
Checker.Result = false;
|
||
Checker.Math = null;
|
||
break;
|
||
}
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.ProcessNotInlineObjectCheck = function(oChecker)
|
||
{
|
||
var Count = this.Content.length;
|
||
if (Count <= 0)
|
||
return;
|
||
|
||
var Item = oChecker.Direction > 0 ? this.Content[0] : this.Content[Count - 1];
|
||
var ItemType = Item.Type;
|
||
|
||
if (para_End === ItemType || para_NewLine === ItemType)
|
||
{
|
||
oChecker.Result = true;
|
||
oChecker.Found = true;
|
||
}
|
||
else
|
||
{
|
||
oChecker.Result = false;
|
||
oChecker.Found = true;
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.Check_PageBreak = function()
|
||
{
|
||
var Count = this.Content.length;
|
||
for (var Pos = 0; Pos < Count; Pos++)
|
||
{
|
||
var Item = this.Content[Pos];
|
||
if (Item.IsBreak() && (Item.IsPageBreak() || Item.IsColumnBreak()))
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
};
|
||
|
||
ParaRun.prototype.CheckSplitPageOnPageBreak = function(oChecker)
|
||
{
|
||
for (var nPos = 0, nCount = this.Content.length; nPos < nCount; ++nPos)
|
||
{
|
||
var oItem = this.Content[nPos];
|
||
|
||
if (oChecker.IsFindPageBreak())
|
||
{
|
||
oChecker.CheckPageBreakItem(oItem);
|
||
}
|
||
else
|
||
{
|
||
var nItemType = oItem.Type;
|
||
|
||
if (para_End === nItemType && !oChecker.IsSplitPageBreakAndParaMark())
|
||
return false;
|
||
else if (para_Drawing !== nItemType || drawing_Anchor !== oItem.Get_DrawingType())
|
||
return true;
|
||
}
|
||
}
|
||
|
||
return false;
|
||
};
|
||
|
||
ParaRun.prototype.RecalculateMinMaxContentWidth = function(MinMax)
|
||
{
|
||
this.Recalculate_MeasureContent();
|
||
|
||
var bWord = MinMax.bWord;
|
||
var nWordLen = MinMax.nWordLen;
|
||
var nSpaceLen = MinMax.nSpaceLen;
|
||
var nMinWidth = MinMax.nMinWidth;
|
||
var nMaxWidth = MinMax.nMaxWidth;
|
||
var nCurMaxWidth = MinMax.nCurMaxWidth;
|
||
var nMaxHeight = MinMax.nMaxHeight;
|
||
|
||
var bCheckTextHeight = false;
|
||
var Count = this.Content.length;
|
||
for ( var Pos = 0; Pos < Count; Pos++ )
|
||
{
|
||
var Item = this.private_CheckInstrText(this.Content[Pos]);
|
||
var ItemType = Item.Type;
|
||
|
||
switch( ItemType )
|
||
{
|
||
case para_Text:
|
||
{
|
||
var ItemWidth = Item.GetWidth();
|
||
if ( false === bWord )
|
||
{
|
||
bWord = true;
|
||
nWordLen = ItemWidth;
|
||
}
|
||
else
|
||
{
|
||
nWordLen += ItemWidth;
|
||
|
||
if (Item.IsSpaceAfter())
|
||
{
|
||
if ( nMinWidth < nWordLen )
|
||
nMinWidth = nWordLen;
|
||
|
||
bWord = false;
|
||
nWordLen = 0;
|
||
}
|
||
}
|
||
|
||
if ( nSpaceLen > 0 )
|
||
{
|
||
nCurMaxWidth += nSpaceLen;
|
||
nSpaceLen = 0;
|
||
}
|
||
|
||
nCurMaxWidth += ItemWidth;
|
||
bCheckTextHeight = true;
|
||
|
||
// Если текущий символ с переносом, например, дефис, тогда на нем заканчивается слово
|
||
if (Item.IsSpaceAfter())
|
||
{
|
||
if (nMinWidth < nWordLen)
|
||
nMinWidth = nWordLen;
|
||
|
||
bWord = false;
|
||
nWordLen = 0;
|
||
nSpaceLen = 0;
|
||
}
|
||
|
||
break;
|
||
}
|
||
case para_Math_Text:
|
||
case para_Math_Ampersand:
|
||
case para_Math_Placeholder:
|
||
{
|
||
var ItemWidth = Item.GetWidth() / AscWord.TEXTWIDTH_DIVIDER;
|
||
if ( false === bWord )
|
||
{
|
||
bWord = true;
|
||
nWordLen = ItemWidth;
|
||
}
|
||
else
|
||
{
|
||
nWordLen += ItemWidth;
|
||
}
|
||
|
||
nCurMaxWidth += ItemWidth;
|
||
bCheckTextHeight = true;
|
||
break;
|
||
}
|
||
case para_Space:
|
||
{
|
||
if ( true === bWord )
|
||
{
|
||
if ( nMinWidth < nWordLen )
|
||
nMinWidth = nWordLen;
|
||
|
||
bWord = false;
|
||
nWordLen = 0;
|
||
}
|
||
|
||
// Мы сразу не добавляем ширину пробелов к максимальной ширине, потому что
|
||
// пробелы, идущие в конце параграфа или перед переносом строки(явным), не
|
||
// должны учитываться.
|
||
nSpaceLen += Item.GetWidth();
|
||
bCheckTextHeight = true;
|
||
break;
|
||
}
|
||
case para_Math_BreakOperator:
|
||
{
|
||
let itemWidth = Item.GetWidth() / AscWord.TEXTWIDTH_DIVIDER;
|
||
if (!bWord)
|
||
nWordLen = itemWidth;
|
||
else
|
||
nWordLen += itemWidth;
|
||
|
||
if (nMinWidth < nWordLen)
|
||
nMinWidth = nWordLen;
|
||
|
||
bWord = false;
|
||
nWordLen = 0;
|
||
|
||
nCurMaxWidth += itemWidth;
|
||
bCheckTextHeight = true;
|
||
break;
|
||
}
|
||
|
||
case para_Drawing:
|
||
{
|
||
if ( true === bWord )
|
||
{
|
||
if ( nMinWidth < nWordLen )
|
||
nMinWidth = nWordLen;
|
||
|
||
bWord = false;
|
||
nWordLen = 0;
|
||
}
|
||
|
||
if ((true === Item.Is_Inline() || true === this.Paragraph.Parent.Is_DrawingShape()) && Item.Width > nMinWidth)
|
||
{
|
||
nMinWidth = Item.Width;
|
||
}
|
||
else if (true === Item.Use_TextWrap())
|
||
{
|
||
nMinWidth = Math.max(nMinWidth, Item.getExtX());
|
||
}
|
||
|
||
if ((true === Item.Is_Inline() || true === this.Paragraph.Parent.Is_DrawingShape()) && Item.getHeight() > nMaxHeight)
|
||
{
|
||
nMaxHeight = Item.getHeight();
|
||
}
|
||
else if (true === Item.Use_TextWrap())
|
||
{
|
||
nMaxHeight = Math.max(nMaxHeight, Item.getExtY());
|
||
}
|
||
|
||
if ( nSpaceLen > 0 )
|
||
{
|
||
nCurMaxWidth += nSpaceLen;
|
||
nSpaceLen = 0;
|
||
}
|
||
|
||
if ( true === Item.Is_Inline() || true === this.Paragraph.Parent.Is_DrawingShape() )
|
||
nCurMaxWidth += Item.Width;
|
||
|
||
break;
|
||
}
|
||
|
||
case para_PageNum:
|
||
case para_PageCount:
|
||
{
|
||
if ( true === bWord )
|
||
{
|
||
if ( nMinWidth < nWordLen )
|
||
nMinWidth = nWordLen;
|
||
|
||
bWord = false;
|
||
nWordLen = 0;
|
||
}
|
||
|
||
if ( Item.Width > nMinWidth )
|
||
nMinWidth = Item.GetWidth();
|
||
|
||
if ( nSpaceLen > 0 )
|
||
{
|
||
nCurMaxWidth += nSpaceLen;
|
||
nSpaceLen = 0;
|
||
}
|
||
|
||
nCurMaxWidth += Item.GetWidth();
|
||
bCheckTextHeight = true;
|
||
break;
|
||
}
|
||
|
||
case para_Tab:
|
||
{
|
||
nWordLen += Item.Width;
|
||
|
||
if ( nMinWidth < nWordLen )
|
||
nMinWidth = nWordLen;
|
||
|
||
bWord = false;
|
||
nWordLen = 0;
|
||
|
||
if ( nSpaceLen > 0 )
|
||
{
|
||
nCurMaxWidth += nSpaceLen;
|
||
nSpaceLen = 0;
|
||
}
|
||
|
||
nCurMaxWidth += Item.Width;
|
||
bCheckTextHeight = true;
|
||
break;
|
||
}
|
||
|
||
case para_NewLine:
|
||
{
|
||
if ( nMinWidth < nWordLen )
|
||
nMinWidth = nWordLen;
|
||
|
||
bWord = false;
|
||
nWordLen = 0;
|
||
|
||
nSpaceLen = 0;
|
||
|
||
if ( nCurMaxWidth > nMaxWidth )
|
||
nMaxWidth = nCurMaxWidth;
|
||
|
||
nCurMaxWidth = 0;
|
||
bCheckTextHeight = true;
|
||
break;
|
||
}
|
||
|
||
case para_End:
|
||
{
|
||
if ( nMinWidth < nWordLen )
|
||
nMinWidth = nWordLen;
|
||
|
||
if ( nCurMaxWidth > nMaxWidth )
|
||
nMaxWidth = nCurMaxWidth;
|
||
|
||
if (nMaxHeight < 0.001)
|
||
bCheckTextHeight = true;
|
||
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
let textMetrics = this.getTextMetrics();
|
||
let textHeight = textMetrics.Ascent + textMetrics.LineGap + textMetrics.Descent;
|
||
if (true === bCheckTextHeight && nMaxHeight < textHeight)
|
||
nMaxHeight = textHeight;
|
||
|
||
MinMax.bWord = bWord;
|
||
MinMax.nWordLen = nWordLen;
|
||
MinMax.nSpaceLen = nSpaceLen;
|
||
MinMax.nMinWidth = nMinWidth;
|
||
MinMax.nMaxWidth = nMaxWidth;
|
||
MinMax.nCurMaxWidth = nCurMaxWidth;
|
||
MinMax.nMaxHeight = nMaxHeight;
|
||
};
|
||
|
||
ParaRun.prototype.Get_Range_VisibleWidth = function(RangeW, _CurLine, _CurRange)
|
||
{
|
||
var CurLine = _CurLine - this.StartLine;
|
||
var CurRange = ( 0 === CurLine ? _CurRange - this.StartRange : _CurRange );
|
||
|
||
var StartPos = this.protected_GetRangeStartPos(CurLine, CurRange);
|
||
var EndPos = this.protected_GetRangeEndPos(CurLine, CurRange);
|
||
|
||
for ( var Pos = StartPos; Pos < EndPos; Pos++ )
|
||
{
|
||
var Item = this.private_CheckInstrText(this.Content[Pos]);
|
||
var ItemType = Item.Type;
|
||
|
||
switch( ItemType )
|
||
{
|
||
case para_Sym:
|
||
case para_Text:
|
||
case para_Space:
|
||
case para_Math_Text:
|
||
case para_Math_Ampersand:
|
||
case para_Math_Placeholder:
|
||
case para_Math_BreakOperator:
|
||
{
|
||
RangeW.W += Item.GetWidthVisible();
|
||
break;
|
||
}
|
||
case para_Drawing:
|
||
{
|
||
if ( true === Item.Is_Inline() )
|
||
RangeW.W += Item.Width;
|
||
|
||
break;
|
||
}
|
||
case para_PageNum:
|
||
case para_PageCount:
|
||
case para_Tab:
|
||
{
|
||
RangeW.W += Item.Width;
|
||
break;
|
||
}
|
||
case para_NewLine:
|
||
{
|
||
RangeW.W += Item.WidthVisible;
|
||
|
||
break;
|
||
}
|
||
case para_End:
|
||
{
|
||
RangeW.W += Item.GetWidthVisible();
|
||
RangeW.End = true;
|
||
|
||
break;
|
||
}
|
||
default:
|
||
{
|
||
RangeW.W += Item.GetWidthVisible();
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.Shift_Range = function(Dx, Dy, _CurLine, _CurRange, _CurPage)
|
||
{
|
||
var CurLine = _CurLine - this.StartLine;
|
||
var CurRange = (0 === CurLine ? _CurRange - this.StartRange : _CurRange);
|
||
|
||
var StartPos = this.protected_GetRangeStartPos(CurLine, CurRange);
|
||
var EndPos = this.protected_GetRangeEndPos(CurLine, CurRange);
|
||
|
||
var nPageAbs = undefined;
|
||
var oParagraph = this.GetParagraph();
|
||
if (oParagraph)
|
||
nPageAbs = oParagraph.GetAbsolutePage(_CurPage);
|
||
|
||
for (var CurPos = StartPos; CurPos < EndPos; CurPos++)
|
||
{
|
||
var Item = this.Content[CurPos];
|
||
|
||
if (para_Drawing === Item.Type)
|
||
{
|
||
if (!Item.IsInline())
|
||
{
|
||
if (!Item.IsMoveWithTextVertically())
|
||
Dy = 0;
|
||
|
||
if (!Item.IsMoveWithTextHorizontally())
|
||
Dx = 0;
|
||
}
|
||
|
||
Item.Shift(Dx, Dy, nPageAbs);
|
||
}
|
||
}
|
||
};
|
||
//-----------------------------------------------------------------------------------
|
||
// Функции отрисовки
|
||
//-----------------------------------------------------------------------------------
|
||
ParaRun.prototype.Draw_HighLights = function(drawState)
|
||
{
|
||
let rangePos = this.getRangePos(drawState.Line, drawState.Range);
|
||
let startPos = rangePos[0];
|
||
let endPos = rangePos[1];
|
||
if (startPos >= endPos)
|
||
return;
|
||
|
||
this.CollaborativeMarks.Init_Drawing();
|
||
for (let pos = startPos; pos < endPos; ++pos)
|
||
{
|
||
let item = this.private_CheckInstrText(this.Content[pos]);
|
||
|
||
for (let iMark = 0, nMarks = this.SearchMarks.length; iMark < nMarks; ++iMark)
|
||
{
|
||
let mark = this.SearchMarks[iMark];
|
||
let markPos = mark.SearchResult.StartPos.Get(mark.Depth);
|
||
|
||
if (pos === markPos && mark.Start)
|
||
drawState.increaseSearchCounter();
|
||
}
|
||
|
||
let collaborationColor = this.CollaborativeMarks.Check(pos);
|
||
drawState.handleRunElement(item, this, collaborationColor);
|
||
|
||
for (let iMark = 0, nMarks = this.SearchMarks.length; iMark < nMarks; ++iMark)
|
||
{
|
||
let mark = this.SearchMarks[iMark];
|
||
let markPos = mark.SearchResult.EndPos.Get(mark.Depth);
|
||
|
||
if (pos + 1 === markPos && !mark.Start)
|
||
drawState.decreaseSearchCounter();
|
||
}
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.Draw_Elements = function(drawState)
|
||
{
|
||
let rangePos = this.getRangePos(drawState.Line, drawState.Range);
|
||
let startPos = rangePos[0];
|
||
let endPos = rangePos[1];
|
||
if (startPos >= endPos)
|
||
return;
|
||
|
||
for (let pos = startPos; pos < endPos; ++pos)
|
||
{
|
||
let item = this.private_CheckInstrText(this.Content[pos]);
|
||
drawState.handleRunElement(item, this);
|
||
}
|
||
};
|
||
ParaRun.prototype.Draw_Lines = function(lineDrawState)
|
||
{
|
||
let rangePos = this.getRangePos(lineDrawState.Line, lineDrawState.Range);
|
||
let startPos = rangePos[0];
|
||
let endPos = rangePos[1];
|
||
if (startPos >= endPos)
|
||
return;
|
||
|
||
lineDrawState.CurPos.Update(startPos, lineDrawState.CurDepth);
|
||
var nSpellingErrorsCounter = lineDrawState.GetSpellingErrorsCounter();
|
||
|
||
var SpellDataLen = endPos + 1;
|
||
var SpellData = g_oSpellCheckerMarks.Check(SpellDataLen);
|
||
for (var iMark = 0, nMarks = this.SpellingMarks.length; iMark < nMarks; ++iMark)
|
||
{
|
||
let mark = this.SpellingMarks[iMark];
|
||
if (!mark.isMisspelled())
|
||
continue;
|
||
|
||
let markPos = mark.getPos();
|
||
if (markPos >= SpellDataLen)
|
||
continue;
|
||
|
||
if (mark.isStart())
|
||
SpellData[markPos] += 1;
|
||
else
|
||
SpellData[markPos] -= 1;
|
||
}
|
||
|
||
lineDrawState.initCustomMarks(this, startPos);
|
||
for (let pos = startPos; pos < endPos; ++pos)
|
||
{
|
||
if (SpellData[pos])
|
||
nSpellingErrorsCounter += SpellData[pos];
|
||
|
||
let item = this.private_CheckInstrText(this.Content[pos]);
|
||
lineDrawState.handleRunElement(item, this, pos, nSpellingErrorsCounter > 0);
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.SkipDraw = function(PDS)
|
||
{
|
||
var CurLine = PDS.Line - this.StartLine;
|
||
var CurRange = (0 === CurLine ? PDS.Range - this.StartRange : PDS.Range);
|
||
|
||
var StartPos = this.protected_GetRangeStartPos(CurLine, CurRange);
|
||
var EndPos = this.protected_GetRangeEndPos(CurLine, CurRange);
|
||
|
||
|
||
var X = PDS.X;
|
||
|
||
for (var Pos = StartPos; Pos < EndPos; Pos++)
|
||
{
|
||
var oItem = this.private_CheckInstrText(this.Content[Pos]);
|
||
var nItemType = oItem.Type;
|
||
|
||
if (para_End === nItemType)
|
||
X += oItem.GetWidth();
|
||
else if (para_Drawing !== nItemType || oItem.Is_Inline())
|
||
X += oItem.GetWidthVisible();
|
||
}
|
||
|
||
// Обновим позицию X
|
||
PDS.X = X;
|
||
};
|
||
//-----------------------------------------------------------------------------------
|
||
// Функции для работы с курсором
|
||
//-----------------------------------------------------------------------------------
|
||
// Находится ли курсор в начале рана
|
||
ParaRun.prototype.IsCursorPlaceable = function()
|
||
{
|
||
return true;
|
||
};
|
||
|
||
ParaRun.prototype.Cursor_Is_Start = function()
|
||
{
|
||
if ( this.State.ContentPos <= 0 )
|
||
return true;
|
||
|
||
return false;
|
||
};
|
||
|
||
// Проверяем нужно ли поправить позицию курсора
|
||
ParaRun.prototype.Cursor_Is_NeededCorrectPos = function()
|
||
{
|
||
if ( true === this.Is_Empty(false) )
|
||
return true;
|
||
|
||
var NewRangeStart = false;
|
||
var RangeEnd = false;
|
||
|
||
var Pos = this.State.ContentPos;
|
||
|
||
var LinesLen = this.protected_GetLinesCount();
|
||
for ( var CurLine = 0; CurLine < LinesLen; CurLine++ )
|
||
{
|
||
var RangesLen = this.protected_GetRangesCount(CurLine);
|
||
for ( var CurRange = 0; CurRange < RangesLen; CurRange++ )
|
||
{
|
||
var StartPos = this.protected_GetRangeStartPos(CurLine, CurRange);
|
||
var EndPos = this.protected_GetRangeEndPos(CurLine, CurRange);
|
||
|
||
if (0 !== CurLine || 0 !== CurRange)
|
||
{
|
||
if (Pos === StartPos)
|
||
{
|
||
NewRangeStart = true;
|
||
}
|
||
}
|
||
|
||
if (Pos === EndPos)
|
||
{
|
||
RangeEnd = true;
|
||
}
|
||
}
|
||
|
||
if ( true === NewRangeStart )
|
||
break;
|
||
}
|
||
|
||
if ( true !== NewRangeStart && true !== RangeEnd && true === this.Cursor_Is_Start() )
|
||
return true;
|
||
|
||
return false;
|
||
};
|
||
|
||
ParaRun.prototype.Cursor_Is_End = function()
|
||
{
|
||
if ( this.State.ContentPos >= this.Content.length )
|
||
return true;
|
||
|
||
return false;
|
||
};
|
||
ParaRun.prototype.IsStartPos = function(contentPos, depth)
|
||
{
|
||
if (depth >= contentPos.Depth)
|
||
return true;
|
||
|
||
return 0 === contentPos.Get(depth);
|
||
};
|
||
ParaRun.prototype.IsEndPos = function(contentPos, depth)
|
||
{
|
||
if (depth >= contentPos.Depth)
|
||
return true;
|
||
|
||
return contentPos.Get(depth) >= this.Content.length;
|
||
};
|
||
/**
|
||
* Проверяем находится ли курсор в начале рана
|
||
* @returns {boolean}
|
||
*/
|
||
ParaRun.prototype.IsCursorAtBegin = function()
|
||
{
|
||
return this.Cursor_Is_Start();
|
||
};
|
||
/**
|
||
* Проверяем находится ли курсор в конце рана
|
||
* @returns {boolean}
|
||
*/
|
||
ParaRun.prototype.IsCursorAtEnd = function()
|
||
{
|
||
return this.Cursor_Is_End();
|
||
};
|
||
|
||
ParaRun.prototype.MoveCursorToStartPos = function()
|
||
{
|
||
this.State.ContentPos = 0;
|
||
};
|
||
|
||
ParaRun.prototype.MoveCursorToEndPos = function(SelectFromEnd)
|
||
{
|
||
if ( true === SelectFromEnd )
|
||
{
|
||
var Selection = this.State.Selection;
|
||
Selection.Use = true;
|
||
Selection.StartPos = this.Content.length;
|
||
Selection.EndPos = this.Content.length;
|
||
}
|
||
else
|
||
{
|
||
var CurPos = this.Content.length;
|
||
|
||
while ( CurPos > 0 )
|
||
{
|
||
if ( para_End === this.Content[CurPos - 1].Type )
|
||
CurPos--;
|
||
else
|
||
break;
|
||
}
|
||
|
||
this.State.ContentPos = CurPos;
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.getParagraphContentPosByXY = function(searchState)
|
||
{
|
||
let rangePos = this.getRangePos(searchState.line, searchState.range);
|
||
let startPos = rangePos[0];
|
||
let endPos = rangePos[1];
|
||
|
||
if (startPos > endPos)
|
||
return;
|
||
|
||
for (let pos = startPos; pos < endPos; ++pos)
|
||
{
|
||
let item = this.private_CheckInstrText(this.Content[pos]);
|
||
searchState.handleRunElement(item, this, pos);
|
||
}
|
||
|
||
searchState.handleRun(this);
|
||
};
|
||
|
||
ParaRun.prototype.Get_ParaContentPos = function(bSelection, bStart, ContentPos, bUseCorrection)
|
||
{
|
||
var Pos = ( true !== bSelection ? this.State.ContentPos : ( false !== bStart ? this.State.Selection.StartPos : this.State.Selection.EndPos ) );
|
||
|
||
if (Pos < 0)
|
||
Pos = 0;
|
||
|
||
if (Pos > this.Content.length)
|
||
Pos = this.Content.length;
|
||
|
||
ContentPos.Add(Pos);
|
||
};
|
||
|
||
ParaRun.prototype.Set_ParaContentPos = function(ContentPos, Depth)
|
||
{
|
||
var Pos = ContentPos.Get(Depth);
|
||
|
||
var Count = this.Content.length;
|
||
if ( Pos > Count )
|
||
Pos = Count;
|
||
|
||
// TODO: Как только переделаем работу c Para_End переделать здесь
|
||
for ( var TempPos = 0; TempPos < Pos; TempPos++ )
|
||
{
|
||
if ( para_End === this.Content[TempPos].Type )
|
||
{
|
||
Pos = TempPos;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if ( Pos < 0 )
|
||
Pos = 0;
|
||
|
||
this.State.ContentPos = Pos;
|
||
};
|
||
/**
|
||
* Функция для перевода позиции внутри параграфа в специальную позицию используемую в ApiRange
|
||
* @param {AscWord.CParagraphContentPos} oContentPos - если null -> возвращает количество символов в элементе.
|
||
* @param {number} nDepth
|
||
* @return {number}
|
||
*/
|
||
ParaRun.prototype.ConvertParaContentPosToRangePos = function(oContentPos, nDepth)
|
||
{
|
||
var nRangePos = 0;
|
||
|
||
var nCurPos = oContentPos ? Math.max(0, Math.min(this.Content.length, oContentPos.Get(nDepth))) : this.Content.length;
|
||
for (var nPos = 0; nPos < nCurPos; ++nPos)
|
||
{
|
||
nRangePos++;
|
||
}
|
||
|
||
return nRangePos;
|
||
};
|
||
ParaRun.prototype.Get_PosByElement = function(Class, ContentPos, Depth, UseRange, Range, Line)
|
||
{
|
||
if ( this === Class )
|
||
return true;
|
||
|
||
return false;
|
||
};
|
||
|
||
ParaRun.prototype.Get_ElementByPos = function(ContentPos, Depth)
|
||
{
|
||
return this;
|
||
};
|
||
|
||
ParaRun.prototype.GetPosByDrawing = function(Id, ContentPos, Depth)
|
||
{
|
||
var Count = this.Content.length;
|
||
for ( var CurPos = 0; CurPos < Count; CurPos++ )
|
||
{
|
||
var Item = this.Content[CurPos];
|
||
if ( para_Drawing === Item.Type && Id === Item.Get_Id() )
|
||
{
|
||
ContentPos.Update( CurPos, Depth );
|
||
return true;
|
||
}
|
||
}
|
||
|
||
return false;
|
||
};
|
||
|
||
ParaRun.prototype.Get_RunElementByPos = function(ContentPos, Depth)
|
||
{
|
||
if ( undefined !== ContentPos )
|
||
{
|
||
var CurPos = ContentPos.Get(Depth);
|
||
var ContentLen = this.Content.length;
|
||
|
||
if ( CurPos >= this.Content.length || CurPos < 0 )
|
||
return null;
|
||
|
||
return this.Content[CurPos];
|
||
}
|
||
else
|
||
{
|
||
if ( this.Content.length > 0 )
|
||
return this.Content[0];
|
||
else
|
||
return null;
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.Get_LastRunInRange = function(_CurLine, _CurRange)
|
||
{
|
||
var CurLine = _CurLine - this.StartLine;
|
||
var CurRange = ( 0 === CurLine ? _CurRange - this.StartRange : _CurRange );
|
||
|
||
return this;
|
||
};
|
||
|
||
ParaRun.prototype.Get_LeftPos = function(SearchPos, ContentPos, Depth, UseContentPos)
|
||
{
|
||
var CurPos = true === UseContentPos ? ContentPos.Get(Depth) : this.Content.length;
|
||
|
||
var isHiddenPart = SearchPos.isHiddenComplexFieldPart();
|
||
var isFieldValue = SearchPos.isComplexFieldValue();
|
||
var isHiddenCF = SearchPos.isHiddenComplexField();
|
||
|
||
while (true)
|
||
{
|
||
CurPos--;
|
||
|
||
var Item = this.private_CheckInstrText(this.Content[CurPos]);
|
||
|
||
if (CurPos >= 0 && para_FieldChar === Item.Type)
|
||
{
|
||
SearchPos.ProcessComplexFieldChar(-1, Item);
|
||
isHiddenPart = SearchPos.isComplexFieldCode();
|
||
isFieldValue = SearchPos.isComplexFieldValue();
|
||
isHiddenCF = SearchPos.isHiddenComplexField();
|
||
}
|
||
|
||
if (CurPos >= 0 && (isHiddenPart || isHiddenCF))
|
||
continue;
|
||
|
||
if (CurPos < 0 || (!(para_Drawing === Item.Type && false === Item.Is_Inline() && false === SearchPos.IsCheckAnchors()) && !((para_FootnoteReference === Item.Type || para_EndnoteReference === Item.Type) && true === Item.IsCustomMarkFollows())))
|
||
break;
|
||
}
|
||
|
||
if (CurPos >= 0)
|
||
{
|
||
SearchPos.Found = true;
|
||
SearchPos.Pos.Update(CurPos, Depth);
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.Get_RightPos = function(SearchPos, ContentPos, Depth, UseContentPos, StepEnd)
|
||
{
|
||
var CurPos = ( true === UseContentPos ? ContentPos.Get(Depth) : 0 );
|
||
|
||
var isHiddenPart = SearchPos.isHiddenComplexFieldPart();
|
||
var isFieldValue = SearchPos.isComplexFieldValue();
|
||
var isHiddenCF = SearchPos.isHiddenComplexField();
|
||
|
||
var Count = this.Content.length;
|
||
while (true)
|
||
{
|
||
CurPos++;
|
||
|
||
// Мы встали в конец рана:
|
||
// Если мы перешагнули para_End или para_Drawing Anchor, тогда возвращаем false
|
||
// В противном случае true
|
||
if (Count === CurPos)
|
||
{
|
||
if (CurPos === 0)
|
||
return;
|
||
|
||
var PrevItem = this.private_CheckInstrText(this.Content[CurPos - 1]);
|
||
var PrevItemType = PrevItem.Type;
|
||
|
||
if (para_FieldChar === PrevItem.Type)
|
||
{
|
||
SearchPos.ProcessComplexFieldChar(1, PrevItem);
|
||
isHiddenPart = SearchPos.isHiddenComplexFieldPart();
|
||
isFieldValue = SearchPos.isComplexFieldValue();
|
||
isHiddenCF = SearchPos.isHiddenComplexField();
|
||
}
|
||
|
||
if (isHiddenPart || isHiddenCF)
|
||
return;
|
||
|
||
if ((true !== StepEnd && para_End === PrevItemType) || (para_Drawing === PrevItemType && false === PrevItem.Is_Inline() && false === SearchPos.IsCheckAnchors()) || ((para_FootnoteReference === PrevItemType || para_EndnoteReference === PrevItemType) && true === PrevItem.IsCustomMarkFollows()))
|
||
return;
|
||
|
||
break;
|
||
}
|
||
|
||
if (CurPos > Count)
|
||
break;
|
||
|
||
// Минимальное значение CurPos = 1, т.к. мы начинаем со значния >= 0 и добавляем 1
|
||
var Item = this.private_CheckInstrText(this.Content[CurPos - 1]);
|
||
var ItemType = Item.Type;
|
||
|
||
if (para_FieldChar === Item.Type)
|
||
{
|
||
SearchPos.ProcessComplexFieldChar(1, Item);
|
||
isHiddenPart = SearchPos.isHiddenComplexFieldPart();
|
||
isFieldValue = SearchPos.isComplexFieldValue();
|
||
isHiddenCF = SearchPos.isHiddenComplexField();
|
||
}
|
||
|
||
if (isHiddenPart || isHiddenCF)
|
||
continue;
|
||
|
||
if (!(true !== StepEnd && para_End === ItemType)
|
||
&& !(para_Drawing === Item.Type && false === Item.Is_Inline())
|
||
&& !((para_FootnoteReference === Item.Type || para_EndnoteReference === Item.Type) && true === Item.IsCustomMarkFollows()))
|
||
break;
|
||
}
|
||
|
||
if (CurPos <= Count)
|
||
{
|
||
SearchPos.Found = true;
|
||
SearchPos.Pos.Update(CurPos, Depth);
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.Get_WordStartPos = function(SearchPos, ContentPos, Depth, UseContentPos)
|
||
{
|
||
var CurPos = ( true === UseContentPos ? ContentPos.Get(Depth) - 1 : this.Content.length - 1 );
|
||
|
||
SearchPos.UpdatePos = false;
|
||
if (CurPos < 0 || this.Content.length <= 0)
|
||
return;
|
||
|
||
SearchPos.Shift = true;
|
||
|
||
var isHiddenPart = SearchPos.isHiddenComplexFieldPart();
|
||
var isFieldValue = SearchPos.isComplexFieldValue();
|
||
var isHiddenCF = SearchPos.isHiddenComplexField();
|
||
|
||
// На первом этапе ищем позицию первого непробельного элемента
|
||
if ( 0 === SearchPos.Stage )
|
||
{
|
||
while ( true )
|
||
{
|
||
var Item = this.private_CheckInstrText(this.Content[CurPos]);
|
||
var Type = Item.Type;
|
||
|
||
var bSpace = false;
|
||
|
||
if (para_FieldChar === Type)
|
||
{
|
||
SearchPos.ProcessComplexFieldChar(-1, Item);
|
||
isHiddenPart = SearchPos.isHiddenComplexFieldPart();
|
||
isFieldValue = SearchPos.isComplexFieldValue();
|
||
isHiddenCF = SearchPos.isHiddenComplexField();
|
||
}
|
||
|
||
if ( para_Space === Type || para_Tab === Type || ( para_Text === Type && true === Item.IsNBSP() ) || ( para_Drawing === Type && true !== Item.Is_Inline() ) )
|
||
bSpace = true;
|
||
|
||
if (true === bSpace || isHiddenPart || isHiddenCF)
|
||
{
|
||
CurPos--;
|
||
|
||
if (CurPos < 0)
|
||
{
|
||
SearchPos.Pos.Update(0, Depth);
|
||
SearchPos.UpdatePos = true;
|
||
return;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// Если мы остановились на нетекстовом элементе, тогда его и возвращаем
|
||
if ( para_Text !== this.Content[CurPos].Type && para_Math_Text !== this.Content[CurPos].Type)
|
||
{
|
||
SearchPos.Pos.Update( CurPos, Depth );
|
||
SearchPos.Found = true;
|
||
SearchPos.UpdatePos = true;
|
||
return;
|
||
}
|
||
|
||
SearchPos.Pos.Update( CurPos, Depth );
|
||
SearchPos.Stage = 1;
|
||
SearchPos.Punctuation = this.Content[CurPos].IsPunctuation();
|
||
SearchPos.UpdatePos = true;
|
||
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
CurPos = ( true === UseContentPos ? ContentPos.Get(Depth) : this.Content.length );
|
||
}
|
||
|
||
// На втором этапе мы смотрим на каком элементе мы встали: если текст - пунктуация, тогда сдвигаемся
|
||
// до конца всех знаков пунктуации
|
||
|
||
while ( CurPos > 0 )
|
||
{
|
||
CurPos--;
|
||
var Item = this.private_CheckInstrText(this.Content[CurPos]);
|
||
var TempType = Item.Type;
|
||
|
||
if (para_FieldChar === Item.Type)
|
||
{
|
||
SearchPos.ProcessComplexFieldChar(-1, Item);
|
||
isHiddenPart = SearchPos.isHiddenComplexFieldPart();
|
||
isFieldValue = SearchPos.isComplexFieldValue();
|
||
isHiddenCF = SearchPos.isHiddenComplexField();
|
||
}
|
||
|
||
if (isHiddenPart || isHiddenCF)
|
||
continue;
|
||
|
||
if ( (para_Text !== TempType && para_Math_Text !== TempType) || true === Item.IsNBSP() || ( true === SearchPos.Punctuation && true !== Item.IsPunctuation() ) || ( false === SearchPos.Punctuation && false !== Item.IsPunctuation() ) )
|
||
{
|
||
SearchPos.Found = true;
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
SearchPos.Pos.Update(CurPos, Depth);
|
||
SearchPos.UpdatePos = true;
|
||
}
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.Get_WordEndPos = function(SearchPos, ContentPos, Depth, UseContentPos, StepEnd)
|
||
{
|
||
var CurPos = ( true === UseContentPos ? ContentPos.Get(Depth) : 0 );
|
||
|
||
SearchPos.UpdatePos = false;
|
||
|
||
var ContentLen = this.Content.length;
|
||
if (CurPos >= ContentLen || ContentLen <= 0)
|
||
return;
|
||
|
||
var isHiddenPart = SearchPos.isHiddenComplexFieldPart();
|
||
var isFieldValue = SearchPos.isComplexFieldValue();
|
||
var isHiddenCF = SearchPos.isHiddenComplexField();
|
||
|
||
if ( 0 === SearchPos.Stage )
|
||
{
|
||
// На первом этапе ищем первый нетекстовый ( и не таб ) элемент
|
||
while ( true )
|
||
{
|
||
var Item = this.private_CheckInstrText(this.Content[CurPos]);
|
||
var Type = Item.Type;
|
||
var bText = false;
|
||
|
||
if (para_FieldChar === Type)
|
||
{
|
||
SearchPos.ProcessComplexFieldChar(1, Item);
|
||
isHiddenPart = SearchPos.isHiddenComplexFieldPart();
|
||
isFieldValue = SearchPos.isComplexFieldValue();
|
||
isHiddenCF = SearchPos.isHiddenComplexField();
|
||
}
|
||
|
||
if ( (para_Text === Type || para_Math_Text === Type) && true != Item.IsNBSP() && ( true === SearchPos.First || ( SearchPos.Punctuation === Item.IsPunctuation() ) ) )
|
||
bText = true;
|
||
|
||
if (true === bText || isHiddenPart || isHiddenCF)
|
||
{
|
||
if (!isHiddenPart && !isHiddenCF)
|
||
{
|
||
if (true === SearchPos.First)
|
||
{
|
||
SearchPos.First = false;
|
||
SearchPos.Punctuation = Item.IsPunctuation();
|
||
}
|
||
|
||
// Отмечаем, что сдвиг уже произошел
|
||
SearchPos.Shift = true;
|
||
}
|
||
|
||
CurPos++;
|
||
|
||
if (CurPos >= ContentLen)
|
||
{
|
||
SearchPos.Pos.Update(CurPos, Depth);
|
||
SearchPos.UpdatePos = true;
|
||
return;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
SearchPos.Stage = 1;
|
||
|
||
// Первый найденный элемент не текстовый, смещаемся вперед
|
||
if ( true === SearchPos.First )
|
||
{
|
||
// Если первый найденный элемент - конец параграфа, тогда выходим из поиска
|
||
if ( para_End === Type )
|
||
{
|
||
if ( true === StepEnd )
|
||
{
|
||
SearchPos.Pos.Update( CurPos + 1, Depth );
|
||
SearchPos.Found = true;
|
||
SearchPos.UpdatePos = true;
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
CurPos++;
|
||
|
||
// Отмечаем, что сдвиг уже произошел
|
||
SearchPos.Shift = true;
|
||
}
|
||
|
||
if (SearchPos.IsTrimSpaces())
|
||
{
|
||
SearchPos.Pos.Update(CurPos, Depth);
|
||
SearchPos.Found = true;
|
||
SearchPos.UpdatePos = true;
|
||
return;
|
||
}
|
||
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (CurPos >= ContentLen)
|
||
{
|
||
SearchPos.Pos.Update(CurPos, Depth);
|
||
SearchPos.UpdatePos = true;
|
||
return;
|
||
}
|
||
|
||
|
||
// На втором этапе мы смотрим на каком элементе мы встали: если это не пробел, тогда
|
||
// останавливаемся здесь. В противном случае сдвигаемся вперед, пока не попали на первый
|
||
// не пробельный элемент.
|
||
if ( !(para_Space === this.Content[CurPos].Type || ( para_Text === this.Content[CurPos].Type && true === this.Content[CurPos].IsNBSP() ) ) )
|
||
{
|
||
SearchPos.Pos.Update( CurPos, Depth );
|
||
SearchPos.Found = true;
|
||
SearchPos.UpdatePos = true;
|
||
}
|
||
else
|
||
{
|
||
while ( CurPos < ContentLen - 1 )
|
||
{
|
||
CurPos++;
|
||
var Item = this.private_CheckInstrText(this.Content[CurPos]);
|
||
var TempType = Item.Type;
|
||
|
||
if (para_FieldChar === Item.Type)
|
||
{
|
||
SearchPos.ProcessComplexFieldChar(1, Item);
|
||
isHiddenPart = SearchPos.isHiddenComplexFieldPart();
|
||
isFieldValue = SearchPos.isComplexFieldValue();
|
||
isHiddenCF = SearchPos.isHiddenComplexField();
|
||
}
|
||
|
||
if (isHiddenPart || isHiddenCF)
|
||
continue;
|
||
|
||
if ( (true !== StepEnd && para_End === TempType) || !( para_Space === TempType || ( para_Text === TempType && true === Item.IsNBSP() ) ) )
|
||
{
|
||
SearchPos.Found = true;
|
||
break;
|
||
}
|
||
}
|
||
|
||
// Обновляем позицию в конце каждого рана (хуже от этого не будет)
|
||
SearchPos.Pos.Update(CurPos, Depth);
|
||
SearchPos.UpdatePos = true;
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.Get_EndRangePos = function(_CurLine, _CurRange, SearchPos, Depth)
|
||
{
|
||
var CurLine = _CurLine - this.StartLine;
|
||
var CurRange = ( 0 === CurLine ? _CurRange - this.StartRange : _CurRange );
|
||
|
||
var StartPos = this.protected_GetRangeStartPos(CurLine, CurRange);
|
||
var EndPos = this.protected_GetRangeEndPos(CurLine, CurRange);
|
||
|
||
var LastPos = -1;
|
||
for ( var CurPos = StartPos; CurPos < EndPos; CurPos++ )
|
||
{
|
||
var Item = this.Content[CurPos];
|
||
var ItemType = Item.Type;
|
||
if ( !((para_Drawing === ItemType && true !== Item.Is_Inline()) || para_End === ItemType || (Item.IsBreak() && Item.IsLineBreak())))
|
||
LastPos = CurPos + 1;
|
||
}
|
||
|
||
// Проверяем, попал ли хоть один элемент в данный отрезок, если нет, тогда не регистрируем такой ран
|
||
if ( -1 !== LastPos )
|
||
{
|
||
SearchPos.Pos.Update( LastPos, Depth );
|
||
return true;
|
||
}
|
||
else
|
||
return false;
|
||
};
|
||
|
||
ParaRun.prototype.Get_StartRangePos = function(_CurLine, _CurRange, SearchPos, Depth)
|
||
{
|
||
var CurLine = _CurLine - this.StartLine;
|
||
var CurRange = ( 0 === CurLine ? _CurRange - this.StartRange : _CurRange );
|
||
|
||
var StartPos = this.protected_GetRangeStartPos(CurLine, CurRange);
|
||
var EndPos = this.protected_GetRangeEndPos(CurLine, CurRange);
|
||
|
||
var FirstPos = -1;
|
||
for ( var CurPos = EndPos - 1; CurPos >= StartPos; CurPos-- )
|
||
{
|
||
var Item = this.Content[CurPos];
|
||
if ( !(para_Drawing === Item.Type && true !== Item.Is_Inline()) )
|
||
FirstPos = CurPos;
|
||
}
|
||
|
||
// Проверяем, попал ли хоть один элемент в данный отрезок, если нет, тогда не регистрируем такой ран
|
||
if ( -1 !== FirstPos )
|
||
{
|
||
SearchPos.Pos.Update( FirstPos, Depth );
|
||
return true;
|
||
}
|
||
else
|
||
return false;
|
||
};
|
||
|
||
ParaRun.prototype.Get_StartRangePos2 = function(_CurLine, _CurRange, ContentPos, Depth)
|
||
{
|
||
var CurLine = _CurLine - this.StartLine;
|
||
var CurRange = ( 0 === CurLine ? _CurRange - this.StartRange : _CurRange );
|
||
|
||
var Pos = this.protected_GetRangeStartPos(CurLine, CurRange);
|
||
ContentPos.Update( Pos, Depth );
|
||
};
|
||
|
||
ParaRun.prototype.Get_EndRangePos2 = function(_CurLine, _CurRange, ContentPos, Depth)
|
||
{
|
||
var CurLine = _CurLine - this.StartLine;
|
||
var CurRange = (0 === CurLine ? _CurRange - this.StartRange : _CurRange);
|
||
var Pos = this.protected_GetRangeEndPos(CurLine, CurRange);
|
||
ContentPos.Update(Pos, Depth);
|
||
};
|
||
|
||
ParaRun.prototype.Get_StartPos = function(ContentPos, Depth)
|
||
{
|
||
ContentPos.Update( 0, Depth );
|
||
};
|
||
|
||
ParaRun.prototype.Get_EndPos = function(BehindEnd, ContentPos, Depth)
|
||
{
|
||
var ContentLen = this.Content.length;
|
||
|
||
if ( true === BehindEnd )
|
||
ContentPos.Update( ContentLen, Depth );
|
||
else
|
||
{
|
||
for ( var CurPos = 0; CurPos < ContentLen; CurPos++ )
|
||
{
|
||
if ( para_End === this.Content[CurPos].Type )
|
||
{
|
||
ContentPos.Update( CurPos, Depth );
|
||
return;
|
||
}
|
||
}
|
||
|
||
// Не нашли para_End
|
||
ContentPos.Update( ContentLen, Depth );
|
||
}
|
||
};
|
||
//-----------------------------------------------------------------------------------
|
||
// Функции для работы с селектом
|
||
//-----------------------------------------------------------------------------------
|
||
ParaRun.prototype.Set_SelectionContentPos = function(StartContentPos, EndContentPos, Depth, StartFlag, EndFlag)
|
||
{
|
||
var StartPos = 0;
|
||
switch (StartFlag)
|
||
{
|
||
case 1: StartPos = 0; break;
|
||
case -1: StartPos = this.Content.length; break;
|
||
case 0: StartPos = StartContentPos.Get(Depth); break;
|
||
}
|
||
|
||
var EndPos = 0;
|
||
switch (EndFlag)
|
||
{
|
||
case 1: EndPos = 0; break;
|
||
case -1: EndPos = this.Content.length; break;
|
||
case 0: EndPos = EndContentPos.Get(Depth); break;
|
||
}
|
||
|
||
var Selection = this.State.Selection;
|
||
Selection.StartPos = StartPos;
|
||
Selection.EndPos = EndPos;
|
||
Selection.Use = true;
|
||
};
|
||
ParaRun.prototype.SetContentSelection = function(StartDocPos, EndDocPos, Depth, StartFlag, EndFlag)
|
||
{
|
||
var StartPos = 0;
|
||
switch (StartFlag)
|
||
{
|
||
case 1: StartPos = 0; break;
|
||
case -1: StartPos = this.Content.length; break;
|
||
case 0: StartPos = StartDocPos[Depth].Position; break;
|
||
}
|
||
|
||
var EndPos = 0;
|
||
switch (EndFlag)
|
||
{
|
||
case 1: EndPos = 0; break;
|
||
case -1: EndPos = this.Content.length; break;
|
||
case 0: EndPos = EndDocPos[Depth].Position; break;
|
||
}
|
||
|
||
var Selection = this.State.Selection;
|
||
Selection.StartPos = StartPos;
|
||
Selection.EndPos = EndPos;
|
||
Selection.Use = true;
|
||
};
|
||
ParaRun.prototype.SetContentPosition = function(DocPos, Depth, Flag)
|
||
{
|
||
var Pos = 0;
|
||
switch (Flag)
|
||
{
|
||
case 1: Pos = 0; break;
|
||
case -1: Pos = this.Content.length; break;
|
||
case 0: Pos = DocPos[Depth].Position; break;
|
||
}
|
||
|
||
var nLen = this.Content.length;
|
||
if (nLen > 0 && Pos >= nLen && para_End === this.Content[nLen - 1].Type)
|
||
Pos = nLen - 1;
|
||
|
||
this.State.ContentPos = Pos;
|
||
};
|
||
ParaRun.prototype.Set_SelectionAtEndPos = function()
|
||
{
|
||
this.Set_SelectionContentPos(null, null, 0, -1, -1);
|
||
};
|
||
|
||
ParaRun.prototype.Set_SelectionAtStartPos = function()
|
||
{
|
||
this.Set_SelectionContentPos(null, null, 0, 1, 1);
|
||
};
|
||
|
||
ParaRun.prototype.IsSelectionUse = function()
|
||
{
|
||
return this.State.Selection.Use;
|
||
};
|
||
ParaRun.prototype.IsSelectedAll = function(Props)
|
||
{
|
||
var Selection = this.State.Selection;
|
||
if ( false === Selection.Use && true !== this.Is_Empty( Props ) )
|
||
return false;
|
||
|
||
var SkipAnchor = Props ? Props.SkipAnchor : false;
|
||
var SkipEnd = Props ? Props.SkipEnd : false;
|
||
|
||
var StartPos = Selection.StartPos;
|
||
var EndPos = Selection.EndPos;
|
||
|
||
if ( EndPos < StartPos )
|
||
{
|
||
StartPos = Selection.EndPos;
|
||
EndPos = Selection.StartPos;
|
||
}
|
||
|
||
for ( var Pos = 0; Pos < StartPos; Pos++ )
|
||
{
|
||
var Item = this.Content[Pos];
|
||
var ItemType = Item.Type;
|
||
|
||
if ( !( ( true === SkipAnchor && ( para_Drawing === ItemType && true !== Item.Is_Inline() ) ) || ( true === SkipEnd && para_End === ItemType ) ) )
|
||
return false;
|
||
}
|
||
|
||
var Count = this.Content.length;
|
||
for ( var Pos = EndPos; Pos < Count; Pos++ )
|
||
{
|
||
var Item = this.Content[Pos];
|
||
var ItemType = Item.Type;
|
||
|
||
if ( !( ( true === SkipAnchor && ( para_Drawing === ItemType && true !== Item.Is_Inline() ) ) || ( true === SkipEnd && para_End === ItemType ) ) )
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
};
|
||
ParaRun.prototype.IsSelectedFromStart = function()
|
||
{
|
||
if (!this.Selection.Use && !this.IsEmpty())
|
||
return false;
|
||
|
||
return (Math.min(this.Selection.StartPos, this.Selection.EndPos) === 0);
|
||
};
|
||
ParaRun.prototype.IsSelectedToEnd = function()
|
||
{
|
||
if (!this.Selection.Use && !this.IsEmpty())
|
||
return false;
|
||
|
||
return (Math.max(this.Selection.StartPos, this.Selection.EndPos) === this.Content.length);
|
||
};
|
||
ParaRun.prototype.GetSelectionStartPos = function()
|
||
{
|
||
return (this.Selection.StartPos > this.Selection.EndPos ? this.Selection.EndPos : this.Selection.StartPos);
|
||
};
|
||
ParaRun.prototype.GetSelectionEndPos = function()
|
||
{
|
||
return (this.Selection.StartPos > this.Selection.EndPos ? this.Selection.StartPos : this.Selection.EndPos);
|
||
};
|
||
|
||
ParaRun.prototype.SkipAnchorsAtSelectionStart = function(Direction)
|
||
{
|
||
if (false === this.Selection.Use || true === this.IsEmpty({SkipAnchor : true}))
|
||
return true;
|
||
|
||
var oSelection = this.State.Selection;
|
||
var nStartPos = Math.min(oSelection.StartPos, oSelection.EndPos);
|
||
var nEndPos = Math.max(oSelection.StartPos, oSelection.EndPos);
|
||
|
||
for (var nPos = 0; nPos < nStartPos; ++nPos)
|
||
{
|
||
var oItem = this.Content[nPos];
|
||
if (para_Drawing !== oItem.Type || true === oItem.Is_Inline())
|
||
return false;
|
||
}
|
||
|
||
for (var nPos = nStartPos; nPos < nEndPos; ++nPos)
|
||
{
|
||
var oItem = this.Content[nPos];
|
||
if (para_Drawing === oItem.Type && true !== oItem.Is_Inline())
|
||
{
|
||
if (1 === Direction)
|
||
oSelection.StartPos = nPos + 1;
|
||
else
|
||
oSelection.EndPos = nPos + 1;
|
||
}
|
||
else
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
|
||
if (nEndPos < this.Content.length)
|
||
return false;
|
||
|
||
return true;
|
||
};
|
||
|
||
ParaRun.prototype.RemoveSelection = function()
|
||
{
|
||
if (this.Selection.Use)
|
||
this.State.ContentPos = Math.min(this.Content.length, Math.max(0, this.Selection.EndPos));
|
||
|
||
this.Selection.Use = false;
|
||
this.Selection.StartPos = 0;
|
||
this.Selection.EndPos = 0;
|
||
};
|
||
ParaRun.prototype.SelectAll = function(nDirection)
|
||
{
|
||
this.Selection.Use = true;
|
||
if (nDirection < 0)
|
||
{
|
||
this.Selection.StartPos = this.Content.length;
|
||
this.Selection.EndPos = 0;
|
||
}
|
||
else
|
||
{
|
||
this.Selection.StartPos = 0;
|
||
this.Selection.EndPos = this.Content.length;
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.drawSelectionInRange = function(line, range, drawSelectionState)
|
||
{
|
||
let rangeInfo = this.getRangePos(line, range);
|
||
let rangeStart = rangeInfo[0];
|
||
let rangeEnd = rangeInfo[1];
|
||
if (rangeStart >= rangeEnd)
|
||
return;
|
||
|
||
let selectionStart = this.State.Selection.StartPos;
|
||
let selectionEnd = this.State.Selection.EndPos;
|
||
|
||
if (!this.State.Selection.Use)
|
||
{
|
||
selectionStart = -1;
|
||
selectionEnd = -1;
|
||
}
|
||
else if (selectionStart > selectionEnd)
|
||
{
|
||
selectionStart = this.State.Selection.EndPos;
|
||
selectionEnd = this.State.Selection.StartPos;
|
||
}
|
||
|
||
for (let pos = rangeStart; pos < rangeEnd; ++pos)
|
||
{
|
||
let item = this.private_CheckInstrText(this.Content[pos]);
|
||
drawSelectionState.handleRunElement(item, selectionStart <= pos && pos < selectionEnd);
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.IsSelectionEmpty = function(CheckEnd)
|
||
{
|
||
var Selection = this.State.Selection;
|
||
if (true !== Selection.Use)
|
||
return true;
|
||
|
||
if (this.IsMathRun() && this.IsPlaceholder())
|
||
return false;
|
||
|
||
var StartPos = Selection.StartPos;
|
||
var EndPos = Selection.EndPos;
|
||
|
||
if ( StartPos > EndPos )
|
||
{
|
||
StartPos = Selection.EndPos;
|
||
EndPos = Selection.StartPos;
|
||
}
|
||
|
||
if ( true === CheckEnd )
|
||
return ( EndPos > StartPos ? false : true );
|
||
else if(this.Type == para_Math_Run && this.Is_Empty())
|
||
{
|
||
return false;
|
||
}
|
||
else
|
||
{
|
||
for ( var CurPos = StartPos; CurPos < EndPos; CurPos++ )
|
||
{
|
||
var ItemType = this.Content[CurPos].Type;
|
||
if (para_End !== ItemType)
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return true;
|
||
};
|
||
|
||
ParaRun.prototype.Selection_CheckParaEnd = function()
|
||
{
|
||
var Selection = this.State.Selection;
|
||
if ( true !== Selection.Use )
|
||
return false;
|
||
|
||
var StartPos = Selection.StartPos;
|
||
var EndPos = Selection.EndPos;
|
||
|
||
if ( StartPos > EndPos )
|
||
{
|
||
StartPos = Selection.EndPos;
|
||
EndPos = Selection.StartPos;
|
||
}
|
||
|
||
for ( var CurPos = StartPos; CurPos < EndPos; CurPos++ )
|
||
{
|
||
var Item = this.Content[CurPos];
|
||
|
||
if ( para_End === Item.Type )
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
};
|
||
|
||
ParaRun.prototype.Selection_CheckParaContentPos = function(ContentPos, Depth, bStart, bEnd)
|
||
{
|
||
var CurPos = ContentPos.Get(Depth);
|
||
|
||
if (this.Selection.StartPos <= this.Selection.EndPos && this.Selection.StartPos <= CurPos && CurPos <= this.Selection.EndPos)
|
||
{
|
||
if ((true !== bEnd) || (true === bEnd && CurPos !== this.Selection.EndPos))
|
||
return true;
|
||
}
|
||
else if (this.Selection.StartPos > this.Selection.EndPos && this.Selection.EndPos <= CurPos && CurPos <= this.Selection.StartPos)
|
||
{
|
||
if ((true !== bEnd) || (true === bEnd && CurPos !== this.Selection.StartPos))
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
};
|
||
//-----------------------------------------------------------------------------------
|
||
// Функции для работы с настройками текста свойств
|
||
//-----------------------------------------------------------------------------------
|
||
ParaRun.prototype.Clear_TextFormatting = function(DefHyper, bHighlight)
|
||
{
|
||
// Highlight и Lang не сбрасываются при очистке текстовых настроек
|
||
|
||
this.SetBold(undefined);
|
||
this.SetBoldCS(undefined);
|
||
this.SetItalic(undefined);
|
||
this.SetItalicCS(undefined);
|
||
this.SetStrikeout(undefined);
|
||
this.SetUnderline(undefined);
|
||
this.SetFontSize(undefined);
|
||
this.SetFontSizeCS(undefined);
|
||
this.Set_Color(undefined);
|
||
this.Set_Unifill(undefined);
|
||
this.Set_VertAlign(undefined);
|
||
this.Set_Spacing(undefined);
|
||
this.Set_DStrikeout(undefined);
|
||
this.Set_Caps(undefined);
|
||
this.Set_SmallCaps(undefined);
|
||
this.Set_Position(undefined);
|
||
this.Set_RFonts2(undefined);
|
||
this.Set_RStyle(undefined);
|
||
this.Set_Shd(undefined);
|
||
this.Set_TextFill(undefined);
|
||
this.Set_TextOutline(undefined);
|
||
|
||
if(bHighlight)
|
||
{
|
||
this.Set_HighLight(undefined);
|
||
this.SetHighlightColor(undefined);
|
||
}
|
||
|
||
// Насильно заставим пересчитать стиль, т.к. как данная функция вызывается у параграфа, у которого мог смениться стиль
|
||
this.Recalc_CompiledPr(true);
|
||
};
|
||
|
||
ParaRun.prototype.Get_TextPr = function()
|
||
{
|
||
return this.Pr.Copy();
|
||
};
|
||
ParaRun.prototype.GetTextPr = function()
|
||
{
|
||
return this.Pr.Copy();
|
||
};
|
||
|
||
ParaRun.prototype.Get_FirstTextPr = function()
|
||
{
|
||
return this.Pr;
|
||
};
|
||
|
||
ParaRun.prototype.Get_CompiledTextPr = function(Copy)
|
||
{
|
||
if (true === this.State.Selection.Use && true === this.Selection_CheckParaEnd())
|
||
{
|
||
var oRunTextPr = this.Get_CompiledPr(true);
|
||
var oEndTextPr = this.Paragraph.GetParaEndCompiledPr();
|
||
|
||
oRunTextPr = oRunTextPr.Compare(oEndTextPr);
|
||
|
||
return oRunTextPr;
|
||
}
|
||
else
|
||
{
|
||
return this.Get_CompiledPr(Copy);
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.GetDirectTextPr = function()
|
||
{
|
||
return this.Pr;
|
||
};
|
||
|
||
ParaRun.prototype.Recalc_CompiledPr = function(RecalcMeasure)
|
||
{
|
||
this.RecalcInfo.TextPr = true;
|
||
|
||
if (RecalcMeasure)
|
||
this.RecalcMeasure();
|
||
|
||
// Если мы в формуле, тогда ее надо пересчитывать
|
||
this.private_RecalcCtrPrp();
|
||
this.OnTextPrChange();
|
||
};
|
||
ParaRun.prototype.RecalcMeasure = function()
|
||
{
|
||
this.RecalcInfo.Measure = true;
|
||
this.private_UpdateShapeText();
|
||
};
|
||
ParaRun.prototype.Recalc_RunsCompiledPr = function()
|
||
{
|
||
this.Recalc_CompiledPr(true);
|
||
};
|
||
/**
|
||
* @param bCopy {boolean} return a duplicate or reference to the compiled textPr object
|
||
* @returns {CTextPr}
|
||
*/
|
||
ParaRun.prototype.Get_CompiledPr = function(bCopy)
|
||
{
|
||
if (this.IsStyleHyperlink() && this.IsInHyperlinkInTOC())
|
||
this.RecalcInfo.TextPr = true;
|
||
|
||
if (this.RecalcInfo.TextPr)
|
||
{
|
||
AscWord.g_textPrCache.remove(this.CompiledPr);
|
||
|
||
// Пока настройки параграфа не считаются скомпилированными, мы не можем считать скомпилированными настройки рана
|
||
this.RecalcInfo.TextPr = !!(this.Paragraph && !this.Paragraph.IsParaPrCompiled());
|
||
|
||
let textPr = this.Internal_Compile_Pr();
|
||
this.CompiledPr = AscWord.g_textPrCache.add(textPr);
|
||
}
|
||
|
||
|
||
if ( false === bCopy )
|
||
return this.CompiledPr;
|
||
else
|
||
return this.CompiledPr.Copy(); // Отдаем копию объекта, чтобы никто не поменял извне настройки стиля
|
||
};
|
||
/**
|
||
* Return a reference to the compiled textPr object
|
||
* @returns {AscWord.CTextPr}
|
||
*/
|
||
ParaRun.prototype.getCompiledPr = function()
|
||
{
|
||
return this.Get_CompiledPr(false);
|
||
};
|
||
|
||
ParaRun.prototype.Internal_Compile_Pr = function ()
|
||
{
|
||
if (undefined === this.Paragraph || null === this.Paragraph)
|
||
{
|
||
// Сюда мы никогда не должны попадать, но на всякий случай,
|
||
// чтобы не выпадало ошибок сгенерим дефолтовые настройки
|
||
var TextPr = new CTextPr();
|
||
TextPr.InitDefault();
|
||
this.RecalcInfo.TextPr = true;
|
||
return TextPr;
|
||
}
|
||
|
||
// Получим настройки текста, для данного параграфа
|
||
var TextPr = this.Paragraph.Get_CompiledPr2(false).TextPr.Copy();
|
||
|
||
let paraParent = this.Paragraph.GetParent();
|
||
let Styles = paraParent && paraParent.Get_Styles() ? paraParent.Get_Styles() : null;
|
||
|
||
// Мержим настройки стиля.
|
||
// Одно исключение, когда задан стиль Hyperlink внутри класса Hyperlink внутри поля TOC, то стиль
|
||
// мержить не надо и, более того, цвет и подчеркивание из прямых настроек тоже не используется.
|
||
if (Styles
|
||
&& Styles instanceof AscWord.CStyles
|
||
&& this.Pr.RStyle
|
||
&& (!this.IsStyleHyperlink() || !this.IsInHyperlinkInTOC()))
|
||
{
|
||
var StyleTextPr = Styles.Get_Pr(this.Pr.RStyle, styletype_Character).TextPr;
|
||
TextPr.Merge(StyleTextPr);
|
||
}
|
||
|
||
if (this.Type === para_Math_Run)
|
||
{
|
||
if (undefined === this.Parent || null === this.Parent)
|
||
{
|
||
// Сюда мы никогда не должны попадать, но на всякий случай,
|
||
// чтобы не выпадало ошибок сгенерим дефолтовые настройки
|
||
var TextPr = new CTextPr();
|
||
TextPr.InitDefault();
|
||
this.RecalcInfo.TextPr = true;
|
||
return TextPr;
|
||
}
|
||
|
||
if (!this.IsNormalText() && Styles) // math text
|
||
{
|
||
// выставим дефолтные текстовые настройки для математических Run
|
||
var StyleId = this.Paragraph.Style_Get();
|
||
// скопируем текстовые настройки прежде чем подменим на пустые
|
||
|
||
var MathFont = {Name : "Cambria Math", Index : -1};
|
||
var oShapeStyle = null, oShapeTextPr = null;
|
||
|
||
if (Styles && typeof Styles.lastId === "string")
|
||
{
|
||
StyleId = Styles.lastId;
|
||
Styles = Styles.styles;
|
||
oShapeStyle = Styles.Get(StyleId);
|
||
oShapeTextPr = oShapeStyle.TextPr.Copy();
|
||
oShapeStyle.TextPr.RFonts.Merge({Ascii : MathFont});
|
||
}
|
||
var StyleDefaultTextPr = Styles.Default.TextPr.Copy();
|
||
|
||
|
||
// Ascii - по умолчанию шрифт Cambria Math
|
||
// hAnsi, eastAsia, cs - по умолчанию шрифты не Cambria Math, а те, которые компилируются в документе
|
||
Styles.Default.TextPr.RFonts.Merge({Ascii : MathFont});
|
||
|
||
|
||
var Pr = Styles.Get_Pr(StyleId, styletype_Paragraph, null, null);
|
||
|
||
TextPr.RFonts.Set_FromObject(Pr.TextPr.RFonts);
|
||
|
||
// подменяем обратно
|
||
Styles.Default.TextPr = StyleDefaultTextPr;
|
||
if (oShapeStyle && oShapeTextPr)
|
||
{
|
||
oShapeStyle.TextPr = oShapeTextPr;
|
||
}
|
||
}
|
||
|
||
|
||
if (this.IsPlaceholder())
|
||
{
|
||
|
||
TextPr.Merge(this.Parent.GetCtrPrp());
|
||
TextPr.Merge(this.Pr); // Мержим прямые настройки данного рана
|
||
}
|
||
else
|
||
{
|
||
TextPr.Merge(this.Pr); // Мержим прямые настройки данного рана
|
||
|
||
if (!this.IsNormalText()) // math text
|
||
{
|
||
var MPrp = this.MathPrp.GetTxtPrp();
|
||
TextPr.Merge(MPrp); // bold, italic
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
var FontScale = TextPr.FontScale;
|
||
TextPr.Merge(this.Pr); // Мержим прямые настройки данного рана
|
||
TextPr.FontScale = FontScale;
|
||
if (this.Pr.Color && !this.Pr.Unifill)
|
||
{
|
||
TextPr.Unifill = undefined;
|
||
}
|
||
}
|
||
|
||
var oTheme = this.Paragraph.Get_Theme();
|
||
var oColorMap = this.Paragraph.Get_ColorMap()
|
||
|
||
if (oTheme && oColorMap)
|
||
{
|
||
if (TextPr.TextFill)
|
||
TextPr.TextFill.check(oTheme, oColorMap);
|
||
else if (TextPr.Unifill)
|
||
TextPr.Unifill.check(oTheme, oColorMap);
|
||
|
||
TextPr.ReplaceThemeFonts(oTheme.themeElements.fontScheme);
|
||
}
|
||
|
||
if(this.Paragraph.bFromDocument === false)
|
||
{
|
||
TextPr.BoldCS = TextPr.Bold;
|
||
TextPr.ItalicCS = TextPr.Italic;
|
||
TextPr.FontSizeCS = TextPr.FontSize;
|
||
}
|
||
TextPr.CheckFontScale();
|
||
|
||
// Для совместимости со старыми версиями запишем FontFamily
|
||
TextPr.FontFamily.Name = TextPr.RFonts.Ascii.Name;
|
||
TextPr.FontFamily.Index = TextPr.RFonts.Ascii.Index;
|
||
|
||
if (this.Paragraph.IsInFixedForm())
|
||
TextPr.Position = 0;
|
||
|
||
let layoutCoeff = this.Paragraph.getLayoutFontSizeCoefficient();
|
||
TextPr.FontSize *= layoutCoeff;
|
||
TextPr.FontSizeCS *= layoutCoeff;
|
||
|
||
return TextPr;
|
||
};
|
||
|
||
ParaRun.prototype.IsStyleHyperlink = function()
|
||
{
|
||
if (!this.Paragraph || !this.Paragraph.bFromDocument || !this.Paragraph.LogicDocument || !this.Paragraph.LogicDocument.Get_Styles() || !this.Paragraph.LogicDocument.Get_Styles().GetDefaultHyperlink)
|
||
return false;
|
||
|
||
return (this.Pr.RStyle === this.Paragraph.LogicDocument.Get_Styles().GetDefaultHyperlink() ? true : false);
|
||
};
|
||
ParaRun.prototype.IsInHyperlinkInTOC = function()
|
||
{
|
||
var oParagraph = this.GetParagraph();
|
||
if (!oParagraph || !oParagraph.bFromDocument)
|
||
return false;
|
||
|
||
var oPos = oParagraph.Get_PosByElement(this);
|
||
if (!oPos)
|
||
return false;
|
||
|
||
var isHyperlink = false;
|
||
var arrClasses = oParagraph.Get_ClassesByPos(oPos);
|
||
for (var nIndex = 0, nCount = arrClasses.length; nIndex < nCount; ++nIndex)
|
||
{
|
||
if (arrClasses[nIndex] instanceof ParaHyperlink)
|
||
{
|
||
isHyperlink = true;
|
||
break;
|
||
}
|
||
}
|
||
|
||
var arrComplexFields = oParagraph.GetComplexFieldsByPos(oPos);
|
||
|
||
if (!isHyperlink)
|
||
{
|
||
for (var nIndex = 0, nCount = arrComplexFields.length; nIndex < nCount; ++nIndex)
|
||
{
|
||
var oInstruction = arrComplexFields[nIndex].GetInstruction();
|
||
if (oInstruction && AscWord.fieldtype_HYPERLINK === oInstruction.GetType())
|
||
{
|
||
isHyperlink = true;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (!isHyperlink)
|
||
return false;
|
||
}
|
||
|
||
for (var nIndex = 0, nCount = arrComplexFields.length; nIndex < nCount; ++nIndex)
|
||
{
|
||
var oInstruction = arrComplexFields[nIndex].GetInstruction();
|
||
if (oInstruction && AscWord.fieldtype_TOC === oInstruction.GetType())
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
};
|
||
|
||
ParaRun.prototype.Set_Pr = function(TextPr)
|
||
{
|
||
return this.SetPr(TextPr);
|
||
};
|
||
/**
|
||
* Жестко меняем настройки на заданные
|
||
* @param {CTextPr} oTextPr
|
||
*/
|
||
ParaRun.prototype.SetPr = function(oTextPr)
|
||
{
|
||
AscCommon.History.Add(new CChangesRunTextPr(this, this.Pr, oTextPr, this.private_IsCollPrChangeMine()));
|
||
this.Pr = oTextPr;
|
||
this.Recalc_CompiledPr(true);
|
||
|
||
this.private_UpdateSpellChecking();
|
||
this.private_UpdateTrackRevisionOnChangeTextPr(true);
|
||
};
|
||
ParaRun.prototype.Apply_TextPr = function(TextPr, IncFontSize, ApplyToAll)
|
||
{
|
||
if (undefined === IncFontSize && this.Pr.Is_Equal(TextPr) && (!this.IsParaEndRun() || !this.Paragraph || this.Paragraph.TextPr.Value.Is_Equal(TextPr)))
|
||
return [null, this, null];
|
||
|
||
var bReview = false;
|
||
if (this.Paragraph && this.Paragraph.LogicDocument && this.Paragraph.bFromDocument && true === this.Paragraph.LogicDocument.IsTrackRevisions())
|
||
bReview = true;
|
||
|
||
var ReviewType = this.GetReviewType();
|
||
var IsPrChange = this.HavePrChange();
|
||
if ( true === ApplyToAll )
|
||
{
|
||
if (true === bReview && true !== this.HavePrChange())
|
||
this.AddPrChange();
|
||
|
||
if (undefined === IncFontSize)
|
||
this.Apply_Pr(TextPr);
|
||
else
|
||
this.IncreaseDecreaseFontSize(IncFontSize);
|
||
|
||
// TODO: Возможно, стоит на этапе пересчета запонимать, лежит ли para_End в данном ране. Чтобы в каждом
|
||
// ране потом не бегать каждый раз по всему массиву в поисках para_End.
|
||
if (this.IsParaEndRun())
|
||
{
|
||
if (undefined === IncFontSize)
|
||
{
|
||
if (!TextPr.AscFill && !TextPr.AscLine && !TextPr.AscUnifill)
|
||
{
|
||
this.Paragraph.TextPr.Apply_TextPr(TextPr);
|
||
}
|
||
else
|
||
{
|
||
var oEndTextPr = this.Paragraph.GetParaEndCompiledPr();
|
||
if (TextPr.AscFill)
|
||
{
|
||
this.Paragraph.TextPr.Set_TextFill(AscFormat.CorrectUniFill(TextPr.AscFill, oEndTextPr.TextFill, 1));
|
||
}
|
||
if (TextPr.AscUnifill)
|
||
{
|
||
this.Paragraph.TextPr.Set_Unifill(AscFormat.CorrectUniFill(TextPr.AscUnifill, oEndTextPr.Unifill, 0));
|
||
}
|
||
if (TextPr.AscLine)
|
||
{
|
||
this.Paragraph.TextPr.Set_TextOutline(AscFormat.CorrectUniStroke(TextPr.AscLine, oEndTextPr.TextOutline, 0));
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// TODO: Как только перенесем историю изменений TextPr в сам класс CTextPr, переделать тут
|
||
this.Paragraph.TextPr.IncreaseDecreaseFontSize(IncFontSize);
|
||
}
|
||
}
|
||
|
||
this.OnTextPrChange();
|
||
}
|
||
else
|
||
{
|
||
var Result = [];
|
||
var LRun = this, CRun = null, RRun = null;
|
||
|
||
if ( true === this.State.Selection.Use )
|
||
{
|
||
var StartPos = this.State.Selection.StartPos;
|
||
var EndPos = this.State.Selection.EndPos;
|
||
|
||
if (StartPos === EndPos && 0 !== this.Content.length)
|
||
{
|
||
CRun = this;
|
||
LRun = null;
|
||
RRun = null;
|
||
}
|
||
else
|
||
{
|
||
var Direction = 1;
|
||
if (StartPos > EndPos)
|
||
{
|
||
var Temp = StartPos;
|
||
StartPos = EndPos;
|
||
EndPos = Temp;
|
||
Direction = -1;
|
||
}
|
||
|
||
// Если выделено не до конца, тогда разделяем по последней точке
|
||
if (EndPos < this.Content.length)
|
||
{
|
||
RRun = LRun.Split_Run(EndPos);
|
||
RRun.SetReviewType(ReviewType);
|
||
if (IsPrChange)
|
||
RRun.AddPrChange();
|
||
}
|
||
|
||
// Если выделено не с начала, тогда делим по начальной точке
|
||
if (StartPos > 0)
|
||
{
|
||
CRun = LRun.Split_Run(StartPos);
|
||
CRun.SetReviewType(ReviewType);
|
||
if (IsPrChange)
|
||
CRun.AddPrChange();
|
||
}
|
||
else
|
||
{
|
||
CRun = LRun;
|
||
LRun = null;
|
||
}
|
||
|
||
if (null !== LRun)
|
||
{
|
||
LRun.Selection.Use = true;
|
||
LRun.Selection.StartPos = LRun.Content.length;
|
||
LRun.Selection.EndPos = LRun.Content.length;
|
||
}
|
||
|
||
CRun.SelectAll(Direction);
|
||
|
||
if (true === bReview && true !== CRun.HavePrChange())
|
||
CRun.AddPrChange();
|
||
|
||
if (undefined === IncFontSize)
|
||
CRun.Apply_Pr(TextPr);
|
||
else
|
||
CRun.IncreaseDecreaseFontSize(IncFontSize);
|
||
|
||
if (null !== RRun)
|
||
{
|
||
RRun.Selection.Use = true;
|
||
RRun.Selection.StartPos = 0;
|
||
RRun.Selection.EndPos = 0;
|
||
}
|
||
|
||
// Дополнительно проверим, если у нас para_End лежит в данном ране и попадает в выделение, тогда
|
||
// применим заданные настроки к символу конца параграфа
|
||
|
||
// TODO: Возможно, стоит на этапе пересчета запонимать, лежит ли para_End в данном ране. Чтобы в каждом
|
||
// ране потом не бегать каждый раз по всему массиву в поисках para_End.
|
||
|
||
if (true === this.Selection_CheckParaEnd())
|
||
{
|
||
if (undefined === IncFontSize)
|
||
{
|
||
if (!TextPr.AscFill && !TextPr.AscLine && !TextPr.AscUnifill)
|
||
{
|
||
this.Paragraph.TextPr.Apply_TextPr(TextPr);
|
||
}
|
||
else
|
||
{
|
||
var oEndTextPr = this.Paragraph.GetParaEndCompiledPr();
|
||
if (TextPr.AscFill)
|
||
{
|
||
this.Paragraph.TextPr.Set_TextFill(AscFormat.CorrectUniFill(TextPr.AscFill, oEndTextPr.TextFill, 1));
|
||
}
|
||
if (TextPr.AscUnifill)
|
||
{
|
||
this.Paragraph.TextPr.Set_Unifill(AscFormat.CorrectUniFill(TextPr.AscUnifill, oEndTextPr.Unifill, 0));
|
||
}
|
||
if (TextPr.AscLine)
|
||
{
|
||
this.Paragraph.TextPr.Set_TextOutline(AscFormat.CorrectUniStroke(TextPr.AscLine, oEndTextPr.TextOutline, 0));
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// TODO: Как только перенесем историю изменений TextPr в сам класс CTextPr, переделать тут
|
||
this.Paragraph.TextPr.IncreaseDecreaseFontSize(IncFontSize);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
var CurPos = this.State.ContentPos;
|
||
|
||
// Если выделено не до конца, тогда разделяем по последней точке
|
||
if ( CurPos < this.Content.length )
|
||
{
|
||
RRun = LRun.Split_Run(CurPos);
|
||
RRun.SetReviewType(ReviewType);
|
||
if (IsPrChange)
|
||
RRun.AddPrChange();
|
||
}
|
||
|
||
if ( CurPos > 0 )
|
||
{
|
||
CRun = LRun.Split_Run(CurPos);
|
||
CRun.SetReviewType(ReviewType);
|
||
if (IsPrChange)
|
||
CRun.AddPrChange();
|
||
}
|
||
else
|
||
{
|
||
CRun = LRun;
|
||
LRun = null;
|
||
}
|
||
|
||
if ( null !== LRun )
|
||
LRun.RemoveSelection();
|
||
|
||
CRun.RemoveSelection();
|
||
CRun.MoveCursorToStartPos();
|
||
|
||
if (true === bReview && true !== CRun.HavePrChange())
|
||
CRun.AddPrChange();
|
||
|
||
if (undefined === IncFontSize)
|
||
CRun.Apply_Pr(TextPr);
|
||
else
|
||
CRun.IncreaseDecreaseFontSize(IncFontSize);
|
||
|
||
|
||
if ( null !== RRun )
|
||
RRun.RemoveSelection();
|
||
}
|
||
|
||
Result.push( LRun );
|
||
Result.push( CRun );
|
||
Result.push( RRun );
|
||
|
||
this.OnTextPrChange();
|
||
return Result;
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.Split_Run = function(Pos)
|
||
{
|
||
// Создаем новый ран
|
||
var bMathRun = this.Type == para_Math_Run;
|
||
var NewRun = new ParaRun(this.Paragraph, bMathRun);
|
||
|
||
AscCommon.History.Add(new CChangesRunOnStartSplit(this, Pos, NewRun));
|
||
AscCommon.CollaborativeEditing.OnStart_SplitRun(this, Pos);
|
||
|
||
// Копируем настройки
|
||
NewRun.Set_Pr(this.Pr.Copy(true));
|
||
|
||
if(bMathRun)
|
||
NewRun.Set_MathPr(this.MathPrp.Copy());
|
||
|
||
|
||
var OldCrPos = this.State.ContentPos;
|
||
var OldSSPos = this.State.Selection.StartPos;
|
||
var OldSEPos = this.State.Selection.EndPos;
|
||
|
||
// Разделяем содержимое по ранам
|
||
NewRun.ConcatToContent( this.Content.slice(Pos) );
|
||
|
||
// Если были точки орфографии, тогда переместим их в новый ран
|
||
for (let iMark = 0, nMarks = this.SpellingMarks.length; iMark < nMarks; ++iMark)
|
||
{
|
||
let mark = this.SpellingMarks[iMark];
|
||
if (mark.getPos() >= Pos)
|
||
{
|
||
mark.movePos(-Pos);
|
||
NewRun.SpellingMarks.push(mark);
|
||
this.SpellingMarks.splice(iMark, 1);
|
||
--nMarks;
|
||
--iMark;
|
||
}
|
||
}
|
||
this.private_UpdateCustomMarksOnSplit(Pos, NewRun);
|
||
|
||
this.Remove_FromContent( Pos, this.Content.length - Pos, true );
|
||
|
||
// Подправим точки селекта и текущей позиции
|
||
if ( OldCrPos >= Pos )
|
||
{
|
||
NewRun.State.ContentPos = OldCrPos - Pos;
|
||
this.State.ContentPos = this.Content.length;
|
||
}
|
||
else
|
||
{
|
||
NewRun.State.ContentPos = 0;
|
||
}
|
||
|
||
if ( OldSSPos >= Pos )
|
||
{
|
||
NewRun.State.Selection.StartPos = OldSSPos - Pos;
|
||
this.State.Selection.StartPos = this.Content.length;
|
||
}
|
||
else
|
||
{
|
||
NewRun.State.Selection.StartPos = 0;
|
||
}
|
||
|
||
if ( OldSEPos >= Pos )
|
||
{
|
||
NewRun.State.Selection.EndPos = OldSEPos - Pos;
|
||
this.State.Selection.EndPos = this.Content.length;
|
||
}
|
||
else
|
||
{
|
||
NewRun.State.Selection.EndPos = 0;
|
||
}
|
||
|
||
AscCommon.History.Add(new CChangesRunOnEndSplit(this, Pos, NewRun));
|
||
AscCommon.CollaborativeEditing.OnEnd_SplitRun(NewRun);
|
||
return NewRun;
|
||
};
|
||
|
||
ParaRun.prototype.Clear_TextPr = function()
|
||
{
|
||
// Данная функция вызывается пока только при изменении стиля параграфа. Оставляем в этой ситуации язык неизмененным,
|
||
// а также не трогаем highlight.
|
||
var NewTextPr = new CTextPr();
|
||
NewTextPr.Lang = this.Pr.Lang.Copy();
|
||
NewTextPr.HighLight = this.Pr.Copy_HighLight();
|
||
this.Set_Pr( NewTextPr );
|
||
};
|
||
|
||
/**
|
||
* В данной функции мы применяем приходящие настройки поверх старых. Если значение undefined, то старое значение
|
||
* не меняем, а если null, то удаляем его из прямых настроек.
|
||
* @param {CTextPr} TextPr
|
||
*/
|
||
ParaRun.prototype.Apply_Pr = function(TextPr)
|
||
{
|
||
this.private_AddCollPrChangeMine();
|
||
|
||
if (this.Type == para_Math_Run && false === this.IsNormalText())
|
||
{
|
||
if (null === TextPr.Bold && null === TextPr.Italic)
|
||
this.Math_Apply_Style(undefined);
|
||
else
|
||
{
|
||
if (undefined != TextPr.Bold)
|
||
{
|
||
if (TextPr.Bold == true)
|
||
{
|
||
if (this.MathPrp.sty == STY_ITALIC || this.MathPrp.sty == undefined)
|
||
this.Math_Apply_Style(STY_BI);
|
||
else if (this.MathPrp.sty == STY_PLAIN)
|
||
this.Math_Apply_Style(STY_BOLD);
|
||
|
||
}
|
||
else if (TextPr.Bold == false || TextPr.Bold == null)
|
||
{
|
||
if (this.MathPrp.sty == STY_BI || this.MathPrp.sty == undefined)
|
||
this.Math_Apply_Style(STY_ITALIC);
|
||
else if (this.MathPrp.sty == STY_BOLD)
|
||
this.Math_Apply_Style(STY_PLAIN);
|
||
}
|
||
}
|
||
|
||
if (undefined != TextPr.Italic)
|
||
{
|
||
if (TextPr.Italic == true)
|
||
{
|
||
if (this.MathPrp.sty == STY_BOLD)
|
||
this.Math_Apply_Style(STY_BI);
|
||
else if (this.MathPrp.sty == STY_PLAIN || this.MathPrp.sty == undefined)
|
||
this.Math_Apply_Style(STY_ITALIC);
|
||
}
|
||
else if (TextPr.Italic == false || TextPr.Italic == null)
|
||
{
|
||
if (this.MathPrp.sty == STY_BI)
|
||
this.Math_Apply_Style(STY_BOLD);
|
||
else if (this.MathPrp.sty == STY_ITALIC || this.MathPrp.sty == undefined)
|
||
this.Math_Apply_Style(STY_PLAIN);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (undefined !== TextPr.Bold)
|
||
{
|
||
this.SetBold(null === TextPr.Bold ? undefined : TextPr.Bold);
|
||
this.SetBoldCS(null === TextPr.Bold ? undefined : TextPr.Bold);
|
||
}
|
||
|
||
if (undefined !== TextPr.Italic)
|
||
{
|
||
this.SetItalic(null === TextPr.Italic ? undefined : TextPr.Italic);
|
||
this.SetItalicCS(null === TextPr.Italic ? undefined : TextPr.Italic);
|
||
}
|
||
}
|
||
|
||
if (undefined !== TextPr.Strikeout)
|
||
this.SetStrikeout(null === TextPr.Strikeout ? undefined : TextPr.Strikeout);
|
||
|
||
if (undefined !== TextPr.Underline)
|
||
this.SetUnderline(null === TextPr.Underline ? undefined : TextPr.Underline);
|
||
|
||
if (undefined !== TextPr.FontSize)
|
||
{
|
||
this.SetFontSize(null === TextPr.FontSize ? undefined : TextPr.FontSize);
|
||
this.SetFontSizeCS(null === TextPr.FontSize ? undefined : TextPr.FontSize);
|
||
}
|
||
|
||
|
||
var oCompiledPr;
|
||
if (undefined !== TextPr.AscUnifill && null !== TextPr.AscUnifill)
|
||
{
|
||
if(this.Paragraph && !this.Paragraph.bFromDocument)
|
||
{
|
||
oCompiledPr = this.Get_CompiledPr(true);
|
||
this.Set_Unifill(AscFormat.CorrectUniFill(TextPr.AscUnifill, oCompiledPr.Unifill, 0), AscCommon.isRealObject(TextPr.AscUnifill) && TextPr.AscUnifill.asc_CheckForseSet());
|
||
this.Set_Color(undefined);
|
||
this.Set_TextFill(undefined);
|
||
}
|
||
}
|
||
else if (undefined !== TextPr.AscFill && null !== TextPr.AscFill)
|
||
{
|
||
var oMergeUnifill, oColor;
|
||
if (this.Paragraph && this.Paragraph.bFromDocument)
|
||
{
|
||
oCompiledPr = this.Get_CompiledPr(true);
|
||
if (oCompiledPr.TextFill)
|
||
{
|
||
oMergeUnifill = oCompiledPr.TextFill;
|
||
}
|
||
else if (oCompiledPr.Unifill)
|
||
{
|
||
oMergeUnifill = oCompiledPr.Unifill;
|
||
}
|
||
else if (oCompiledPr.Color)
|
||
{
|
||
oColor = oCompiledPr.Color;
|
||
oMergeUnifill = AscFormat.CreateUnfilFromRGB(oColor.r, oColor.g, oColor.b);
|
||
}
|
||
this.Set_Unifill(undefined);
|
||
this.Set_Color(undefined);
|
||
this.Set_TextFill(AscFormat.CorrectUniFill(TextPr.AscFill, oMergeUnifill, 1), AscCommon.isRealObject(TextPr.AscFill) && TextPr.AscFill.asc_CheckForseSet());
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (undefined !== TextPr.Color)
|
||
{
|
||
this.Set_Color(null === TextPr.Color ? undefined : TextPr.Color);
|
||
if(null !== TextPr.Color)
|
||
{
|
||
this.Set_Unifill(undefined);
|
||
this.Set_TextFill(undefined);
|
||
}
|
||
}
|
||
if (undefined !== TextPr.Unifill)
|
||
{
|
||
this.Set_Unifill(null === TextPr.Unifill ? undefined : TextPr.Unifill);
|
||
if(null !== TextPr.Unifill)
|
||
{
|
||
this.Set_Color(undefined);
|
||
this.Set_TextFill(undefined);
|
||
}
|
||
}
|
||
if (undefined !== TextPr.TextFill)
|
||
{
|
||
this.Set_TextFill(null === TextPr.TextFill ? undefined : TextPr.TextFill);
|
||
if(null !== TextPr.TextFill)
|
||
{
|
||
this.Set_Unifill(undefined);
|
||
this.Set_Color(undefined);
|
||
}
|
||
}
|
||
}
|
||
if (undefined !== TextPr.AscLine && null !== TextPr.AscLine)
|
||
{
|
||
if(this.Paragraph)
|
||
{
|
||
oCompiledPr = this.Get_CompiledPr(true);
|
||
this.Set_TextOutline(AscFormat.CorrectUniStroke(TextPr.AscLine, oCompiledPr.TextOutline, 0));
|
||
}
|
||
}
|
||
else if (undefined !== TextPr.TextOutline)
|
||
{
|
||
this.Set_TextOutline(null === TextPr.TextOutline ? undefined : TextPr.TextOutline);
|
||
}
|
||
|
||
if (undefined !== TextPr.VertAlign)
|
||
this.Set_VertAlign(null === TextPr.VertAlign ? undefined : TextPr.VertAlign);
|
||
|
||
if (undefined !== TextPr.HighLight)
|
||
this.Set_HighLight(null === TextPr.HighLight ? undefined : TextPr.HighLight);
|
||
if(undefined !== TextPr.HighlightColor)
|
||
this.SetHighlightColor(null === TextPr.HighlightColor ? undefined : TextPr.HighlightColor);
|
||
|
||
if (undefined !== TextPr.RStyle)
|
||
this.Set_RStyle(null === TextPr.RStyle ? undefined : TextPr.RStyle);
|
||
|
||
if (undefined !== TextPr.Spacing)
|
||
this.Set_Spacing(null === TextPr.Spacing ? undefined : TextPr.Spacing);
|
||
|
||
if (undefined !== TextPr.DStrikeout)
|
||
this.Set_DStrikeout(null === TextPr.DStrikeout ? undefined : TextPr.DStrikeout);
|
||
|
||
if (undefined !== TextPr.Caps)
|
||
this.Set_Caps(null === TextPr.Caps ? undefined : TextPr.Caps);
|
||
|
||
if (undefined !== TextPr.SmallCaps)
|
||
this.Set_SmallCaps(null === TextPr.SmallCaps ? undefined : TextPr.SmallCaps);
|
||
|
||
if (undefined !== TextPr.Position)
|
||
this.Set_Position(null === TextPr.Position ? undefined : TextPr.Position);
|
||
|
||
if (TextPr.RFonts && !this.IsInCheckBox())
|
||
{
|
||
if (para_Math_Run === this.Type && !this.IsNormalText()) // при смене Font в этом случае (даже на Cambria Math) cs, eastAsia не меняются
|
||
{
|
||
// только для редактирования
|
||
// делаем так для проверки действительно ли нужно сменить Font, чтобы при смене других текстовых настроек не выставился Cambria Math (TextPr.RFonts приходит всегда в виде объекта)
|
||
if (TextPr.RFonts.Ascii !== undefined || TextPr.RFonts.HAnsi !== undefined)
|
||
{
|
||
var RFonts = new CRFonts();
|
||
RFonts.SetAll("Cambria Math", -1);
|
||
|
||
this.Set_RFonts2(RFonts);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (TextPr.FontFamily)
|
||
this.ApplyFontFamily(TextPr.FontFamily.Name);
|
||
else
|
||
this.Set_RFonts2(TextPr.RFonts);
|
||
}
|
||
}
|
||
|
||
|
||
if (undefined !== TextPr.Lang && undefined !== TextPr.Lang.Val)
|
||
{
|
||
let lcid = TextPr.Lang.Val;
|
||
let dirFlag = this.GetDirectionFlagInRange(0, this.Content.length);
|
||
if (AscBidi.DIRECTION_FLAG.None === dirFlag)
|
||
{
|
||
this.Set_Lang_Bidi(lcid);
|
||
this.Set_Lang_Val(lcid);
|
||
}
|
||
else
|
||
{
|
||
if (AscBidi.DIRECTION_FLAG.LTR & dirFlag)
|
||
this.Set_Lang_Val(lcid);
|
||
if (AscBidi.DIRECTION_FLAG.RTL & dirFlag)
|
||
this.Set_Lang_Bidi(lcid);
|
||
|
||
let paragraph = this.GetParagraph();
|
||
if (AscBidi.DIRECTION_FLAG.Other === dirFlag && paragraph)
|
||
{
|
||
if (paragraph.isRtlDirection())
|
||
this.Set_Lang_Bidi(lcid);
|
||
else
|
||
this.Set_Lang_Val(lcid);
|
||
}
|
||
}
|
||
}
|
||
|
||
if (undefined !== TextPr.Shd)
|
||
this.Set_Shd(null === TextPr.Shd ? undefined : TextPr.Shd);
|
||
|
||
if (undefined !== TextPr.Ligatures)
|
||
this.SetLigatures(null === TextPr.Ligatures ? undefined : TextPr.Ligatures);
|
||
|
||
for (var nPos = 0, nCount = this.Content.length; nPos < nCount; ++nPos)
|
||
{
|
||
if (para_End === this.Content[nPos].Type)
|
||
return this.Paragraph.TextPr.Apply_TextPr(TextPr);
|
||
}
|
||
};
|
||
ParaRun.prototype.ApplyPr = function(oTextPr)
|
||
{
|
||
return this.Apply_Pr(oTextPr);
|
||
};
|
||
|
||
ParaRun.prototype.HavePrChange = function()
|
||
{
|
||
return this.Pr.HavePrChange();
|
||
};
|
||
|
||
ParaRun.prototype.GetPrReviewColor = function()
|
||
{
|
||
if (this.Pr.ReviewInfo)
|
||
return this.Pr.ReviewInfo.Get_Color();
|
||
|
||
return REVIEW_COLOR;
|
||
};
|
||
|
||
ParaRun.prototype.AddPrChange = function()
|
||
{
|
||
if (false === this.HavePrChange())
|
||
{
|
||
this.Pr.AddPrChange();
|
||
AscCommon.History.Add(new CChangesRunPrChange(this,
|
||
{
|
||
PrChange : undefined,
|
||
ReviewInfo : undefined
|
||
},
|
||
{
|
||
PrChange : this.Pr.PrChange,
|
||
ReviewInfo : this.Pr.ReviewInfo
|
||
}));
|
||
this.updateTrackRevisions();
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.SetPrChange = function(PrChange, ReviewInfo)
|
||
{
|
||
AscCommon.History.Add(new CChangesRunPrChange(this,
|
||
{
|
||
PrChange : this.Pr.PrChange,
|
||
ReviewInfo : this.Pr.ReviewInfo ? this.Pr.ReviewInfo.Copy() : undefined
|
||
},
|
||
{
|
||
PrChange : PrChange,
|
||
ReviewInfo : ReviewInfo ? ReviewInfo.Copy() : undefined
|
||
}));
|
||
this.Pr.SetPrChange(PrChange, ReviewInfo);
|
||
this.updateTrackRevisions();
|
||
};
|
||
|
||
ParaRun.prototype.RemovePrChange = function()
|
||
{
|
||
if (true === this.HavePrChange())
|
||
{
|
||
AscCommon.History.Add(new CChangesRunPrChange(this,
|
||
{
|
||
PrChange : this.Pr.PrChange,
|
||
ReviewInfo : this.Pr.ReviewInfo
|
||
},
|
||
{
|
||
PrChange : undefined,
|
||
ReviewInfo : undefined
|
||
}));
|
||
this.Pr.RemovePrChange();
|
||
this.updateTrackRevisions();
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.RejectPrChange = function()
|
||
{
|
||
if (true === this.HavePrChange())
|
||
{
|
||
if (this.GetParaEnd())
|
||
this.Paragraph.TextPr.SetPr(this.Pr.PrChange);
|
||
|
||
this.Set_Pr(this.Pr.PrChange);
|
||
|
||
this.RemovePrChange();
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.AcceptPrChange = function()
|
||
{
|
||
this.RemovePrChange();
|
||
};
|
||
|
||
ParaRun.prototype.GetDiffPrChange = function()
|
||
{
|
||
return this.Pr.GetDiffPrChange();
|
||
};
|
||
ParaRun.prototype.SetBold = function(isBold)
|
||
{
|
||
if (isBold !== this.Pr.Bold)
|
||
{
|
||
AscCommon.History.Add(new CChangesRunBold(this, this.Pr.Bold, isBold, this.private_IsCollPrChangeMine()));
|
||
this.Pr.Bold = isBold;
|
||
|
||
this.Recalc_CompiledPr(true);
|
||
this.private_UpdateTrackRevisionOnChangeTextPr(true);
|
||
}
|
||
};
|
||
ParaRun.prototype.Get_Bold = function()
|
||
{
|
||
return this.Get_CompiledPr(false).Bold;
|
||
};
|
||
ParaRun.prototype.SetBoldCS = function(isBold)
|
||
{
|
||
if (isBold !== this.Pr.BoldCS)
|
||
{
|
||
AscCommon.History.Add(new CChangesRunBoldCS(this, this.Pr.BoldCS, isBold, this.private_IsCollPrChangeMine()));
|
||
this.Pr.BoldCS = isBold;
|
||
this.Recalc_CompiledPr(true);
|
||
this.private_UpdateTrackRevisionOnChangeTextPr(true);
|
||
}
|
||
};
|
||
ParaRun.prototype.GetBoldCS = function()
|
||
{
|
||
return this.Get_CompiledPr(false).BoldCS;
|
||
};
|
||
ParaRun.prototype.SetItalic = function(isItalic)
|
||
{
|
||
if (isItalic !== this.Pr.Italic)
|
||
{
|
||
AscCommon.History.Add(new CChangesRunItalic(this, this.Pr.Italic, isItalic, this.private_IsCollPrChangeMine()));
|
||
this.Pr.Italic = isItalic;
|
||
this.Recalc_CompiledPr(true);
|
||
this.private_UpdateTrackRevisionOnChangeTextPr(true);
|
||
}
|
||
};
|
||
ParaRun.prototype.Get_Italic = function()
|
||
{
|
||
return this.Get_CompiledPr(false).Italic;
|
||
};
|
||
ParaRun.prototype.SetItalicCS = function(isItalic)
|
||
{
|
||
if (isItalic !== this.Pr.ItalicCS)
|
||
{
|
||
AscCommon.History.Add(new CChangesRunItalicCS(this, this.Pr.ItalicCS, isItalic, this.private_IsCollPrChangeMine()));
|
||
this.Pr.ItalicCS = isItalic;
|
||
this.Recalc_CompiledPr(true);
|
||
this.private_UpdateTrackRevisionOnChangeTextPr(true);
|
||
}
|
||
};
|
||
ParaRun.prototype.GetItalicCS = function()
|
||
{
|
||
return this.Get_CompiledPr(false).ItalicCS;
|
||
};
|
||
ParaRun.prototype.SetStrikeout = function(Value)
|
||
{
|
||
if ( Value !== this.Pr.Strikeout )
|
||
{
|
||
var OldValue = this.Pr.Strikeout;
|
||
this.Pr.Strikeout = Value;
|
||
|
||
AscCommon.History.Add(new CChangesRunStrikeout(this, OldValue, Value, this.private_IsCollPrChangeMine()));
|
||
|
||
this.Recalc_CompiledPr(false);
|
||
this.private_UpdateTrackRevisionOnChangeTextPr(true);
|
||
}
|
||
};
|
||
ParaRun.prototype.Get_Strikeout = function()
|
||
{
|
||
return this.Get_CompiledPr(false).Strikeout;
|
||
};
|
||
ParaRun.prototype.SetUnderline = function(Value)
|
||
{
|
||
if ( Value !== this.Pr.Underline )
|
||
{
|
||
var OldValue = this.Pr.Underline;
|
||
this.Pr.Underline = Value;
|
||
|
||
AscCommon.History.Add(new CChangesRunUnderline(this, OldValue, Value, this.private_IsCollPrChangeMine()));
|
||
|
||
this.Recalc_CompiledPr(false);
|
||
this.private_UpdateTrackRevisionOnChangeTextPr(true);
|
||
}
|
||
};
|
||
ParaRun.prototype.Get_Underline = function()
|
||
{
|
||
return this.Get_CompiledPr(false).Underline;
|
||
};
|
||
ParaRun.prototype.SetFontSize = function(nFontSize)
|
||
{
|
||
if (nFontSize !== this.Pr.FontSize)
|
||
{
|
||
AscCommon.History.Add(new CChangesRunFontSize(this, this.Pr.FontSize, nFontSize, this.private_IsCollPrChangeMine()));
|
||
this.Pr.FontSize = nFontSize;
|
||
this.Recalc_CompiledPr(true);
|
||
this.private_UpdateTrackRevisionOnChangeTextPr(true);
|
||
}
|
||
};
|
||
ParaRun.prototype.Get_FontSize = function()
|
||
{
|
||
return this.Get_CompiledPr(false).FontSize;
|
||
};
|
||
ParaRun.prototype.SetFontSizeCS = function(nFontSize)
|
||
{
|
||
if (nFontSize !== this.Pr.FontSizeCS)
|
||
{
|
||
AscCommon.History.Add(new CChangesRunFontSizeCS(this, this.Pr.FontSizeCS, nFontSize, this.private_IsCollPrChangeMine()));
|
||
this.Pr.FontSizeCS = nFontSize;
|
||
this.Recalc_CompiledPr(true);
|
||
this.private_UpdateTrackRevisionOnChangeTextPr(true);
|
||
}
|
||
};
|
||
ParaRun.prototype.GetFontSizeCS = function()
|
||
{
|
||
return this.Get_CompiledPr(false).FontSizeCS;
|
||
};
|
||
|
||
ParaRun.prototype.Set_Color = function(Value)
|
||
{
|
||
if ( ( undefined === Value && undefined !== this.Pr.Color ) || ( Value instanceof CDocumentColor && ( undefined === this.Pr.Color || false === Value.Compare(this.Pr.Color) ) ) )
|
||
{
|
||
var OldValue = this.Pr.Color;
|
||
this.Pr.Color = Value;
|
||
|
||
AscCommon.History.Add(new CChangesRunColor(this, OldValue, Value, this.private_IsCollPrChangeMine()));
|
||
|
||
this.Recalc_CompiledPr(false);
|
||
this.private_UpdateTrackRevisionOnChangeTextPr(true);
|
||
}
|
||
};
|
||
ParaRun.prototype.SetColor = function(color)
|
||
{
|
||
return this.Set_Color(color);
|
||
};
|
||
|
||
ParaRun.prototype.Set_Unifill = function(Value, bForce)
|
||
{
|
||
if ( ( undefined === Value && undefined !== this.Pr.Unifill ) || ( Value instanceof AscFormat.CUniFill && ( undefined === this.Pr.Unifill || false === AscFormat.CompareUnifillBool(this.Pr.Unifill, Value) ) ) || bForce )
|
||
{
|
||
var OldValue = this.Pr.Unifill;
|
||
this.Pr.Unifill = Value;
|
||
|
||
AscCommon.History.Add(new CChangesRunUnifill(this, OldValue, Value, this.private_IsCollPrChangeMine()));
|
||
|
||
this.Recalc_CompiledPr(false);
|
||
this.private_UpdateTrackRevisionOnChangeTextPr(true);
|
||
}
|
||
};
|
||
ParaRun.prototype.Set_TextFill = function(Value, bForce)
|
||
{
|
||
if ( ( undefined === Value && undefined !== this.Pr.TextFill ) || ( Value instanceof AscFormat.CUniFill && ( undefined === this.Pr.TextFill || false === AscFormat.CompareUnifillBool(this.Pr.TextFill.IsIdentical, Value) ) ) || bForce )
|
||
{
|
||
var OldValue = this.Pr.TextFill;
|
||
this.Pr.TextFill = Value;
|
||
|
||
AscCommon.History.Add(new CChangesRunTextFill(this, OldValue, Value, this.private_IsCollPrChangeMine()));
|
||
|
||
this.Recalc_CompiledPr(false);
|
||
this.private_UpdateTrackRevisionOnChangeTextPr(true);
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.Set_TextOutline = function(Value)
|
||
{
|
||
if ( ( undefined === Value && undefined !== this.Pr.TextOutline ) || ( Value instanceof AscFormat.CLn && ( undefined === this.Pr.TextOutline || false === this.Pr.TextOutline.IsIdentical(Value) ) ) )
|
||
{
|
||
var OldValue = this.Pr.TextOutline;
|
||
this.Pr.TextOutline = Value;
|
||
|
||
AscCommon.History.Add(new CChangesRunTextOutline(this, OldValue, Value, this.private_IsCollPrChangeMine()));
|
||
|
||
this.Recalc_CompiledPr(false);
|
||
this.private_UpdateTrackRevisionOnChangeTextPr(true);
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.Get_Color = function()
|
||
{
|
||
return this.Get_CompiledPr(false).Color;
|
||
};
|
||
|
||
ParaRun.prototype.Set_VertAlign = function(Value)
|
||
{
|
||
if ( Value !== this.Pr.VertAlign )
|
||
{
|
||
var OldValue = this.Pr.VertAlign;
|
||
this.Pr.VertAlign = Value;
|
||
|
||
AscCommon.History.Add(new CChangesRunVertAlign(this, OldValue, Value, this.private_IsCollPrChangeMine()));
|
||
|
||
this.Recalc_CompiledPr(true);
|
||
this.private_UpdateTrackRevisionOnChangeTextPr(true);
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.Get_VertAlign = function()
|
||
{
|
||
return this.Get_CompiledPr(false).VertAlign;
|
||
};
|
||
ParaRun.prototype.SetVertAlign = function(nAlign)
|
||
{
|
||
this.Set_VertAlign(nAlign);
|
||
};
|
||
ParaRun.prototype.GetVertAlign = function()
|
||
{
|
||
return this.Get_VertAlign();
|
||
};
|
||
|
||
ParaRun.prototype.Set_HighLight = function(Value)
|
||
{
|
||
var OldValue = this.Pr.HighLight;
|
||
if ( (undefined === Value && undefined !== OldValue) || ( highlight_None === Value && highlight_None !== OldValue ) || ( Value instanceof CDocumentColor && ( undefined === OldValue || highlight_None === OldValue || false === Value.Compare(OldValue) ) ) )
|
||
{
|
||
this.Pr.HighLight = Value;
|
||
AscCommon.History.Add(new CChangesRunHighLight(this, OldValue, Value, this.private_IsCollPrChangeMine()));
|
||
|
||
this.Recalc_CompiledPr(false);
|
||
this.private_UpdateTrackRevisionOnChangeTextPr(true);
|
||
}
|
||
};
|
||
ParaRun.prototype.SetHighlightColor = function(Value)
|
||
{
|
||
var OldValue = this.Pr.HighlightColor;
|
||
if ( OldValue && !OldValue.IsIdentical(Value) || Value && !Value.IsIdentical(OldValue) )
|
||
{
|
||
this.Pr.HighlightColor = Value;
|
||
AscCommon.History.Add(new CChangesRunHighlightColor(this, OldValue, Value, this.private_IsCollPrChangeMine()));
|
||
this.Recalc_CompiledPr(false);
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.Get_HighLight = function()
|
||
{
|
||
return this.Get_CompiledPr(false).HighLight;
|
||
};
|
||
|
||
|
||
ParaRun.prototype.Set_RStyle = function(styleId)
|
||
{
|
||
if (!styleId)
|
||
styleId = undefined;
|
||
|
||
if (styleId === this.Pr.RStyle)
|
||
return;
|
||
|
||
let oldStyleId = this.Pr.RStyle;
|
||
this.Pr.RStyle = styleId;
|
||
|
||
AscCommon.History.Add(new CChangesRunRStyle(this, oldStyleId, styleId, this.private_IsCollPrChangeMine()));
|
||
|
||
this.Recalc_CompiledPr(true);
|
||
this.private_UpdateTrackRevisionOnChangeTextPr(true);
|
||
};
|
||
ParaRun.prototype.Get_RStyle = function()
|
||
{
|
||
return this.Get_CompiledPr(false).RStyle;
|
||
};
|
||
ParaRun.prototype.GetRStyle = function()
|
||
{
|
||
return this.Get_RStyle();
|
||
};
|
||
ParaRun.prototype.SetRStyle = function(sStyleId)
|
||
{
|
||
this.Set_RStyle(sStyleId);
|
||
};
|
||
|
||
ParaRun.prototype.Set_Spacing = function(Value)
|
||
{
|
||
if (Value !== this.Pr.Spacing)
|
||
{
|
||
var OldValue = this.Pr.Spacing;
|
||
this.Pr.Spacing = Value;
|
||
|
||
AscCommon.History.Add(new CChangesRunSpacing(this, OldValue, Value, this.private_IsCollPrChangeMine()));
|
||
|
||
this.Recalc_CompiledPr(true);
|
||
this.private_UpdateTrackRevisionOnChangeTextPr(true);
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.Get_Spacing = function()
|
||
{
|
||
return this.Get_CompiledPr(false).Spacing;
|
||
};
|
||
|
||
ParaRun.prototype.Set_DStrikeout = function(Value)
|
||
{
|
||
if ( Value !== this.Pr.DStrikeout )
|
||
{
|
||
var OldValue = this.Pr.DStrikeout;
|
||
this.Pr.DStrikeout = Value;
|
||
|
||
AscCommon.History.Add(new CChangesRunDStrikeout(this, OldValue, Value, this.private_IsCollPrChangeMine()));
|
||
|
||
this.Recalc_CompiledPr(false);
|
||
this.private_UpdateTrackRevisionOnChangeTextPr(true);
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.Get_DStrikeout = function()
|
||
{
|
||
return this.Get_CompiledPr(false).DStrikeout;
|
||
};
|
||
|
||
ParaRun.prototype.Set_Caps = function(Value)
|
||
{
|
||
if ( Value !== this.Pr.Caps )
|
||
{
|
||
var OldValue = this.Pr.Caps;
|
||
this.Pr.Caps = Value;
|
||
|
||
AscCommon.History.Add(new CChangesRunCaps(this, OldValue, Value, this.private_IsCollPrChangeMine()));
|
||
this.Recalc_CompiledPr(true);
|
||
this.private_UpdateTrackRevisionOnChangeTextPr(true);
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.Get_Caps = function()
|
||
{
|
||
return this.Get_CompiledPr(false).Caps;
|
||
};
|
||
|
||
ParaRun.prototype.Set_SmallCaps = function(Value)
|
||
{
|
||
if ( Value !== this.Pr.SmallCaps )
|
||
{
|
||
var OldValue = this.Pr.SmallCaps;
|
||
this.Pr.SmallCaps = Value;
|
||
|
||
AscCommon.History.Add(new CChangesRunSmallCaps(this, OldValue, Value, this.private_IsCollPrChangeMine()));
|
||
this.Recalc_CompiledPr(true);
|
||
this.private_UpdateTrackRevisionOnChangeTextPr(true);
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.Get_SmallCaps = function()
|
||
{
|
||
return this.Get_CompiledPr(false).SmallCaps;
|
||
};
|
||
|
||
ParaRun.prototype.Set_Position = function(Value)
|
||
{
|
||
if ( Value !== this.Pr.Position )
|
||
{
|
||
var OldValue = this.Pr.Position;
|
||
this.Pr.Position = Value;
|
||
|
||
AscCommon.History.Add(new CChangesRunPosition(this, OldValue, Value, this.private_IsCollPrChangeMine()));
|
||
this.Recalc_CompiledPr(false);
|
||
this.private_UpdateTrackRevisionOnChangeTextPr(true);
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.Get_Position = function()
|
||
{
|
||
return this.Get_CompiledPr(false).Position;
|
||
};
|
||
|
||
ParaRun.prototype.Set_RFonts = function(Value)
|
||
{
|
||
var OldValue = this.Pr.RFonts;
|
||
this.Pr.RFonts = Value;
|
||
|
||
AscCommon.History.Add(new CChangesRunRFonts(this, OldValue, Value, this.private_IsCollPrChangeMine()));
|
||
|
||
this.Recalc_CompiledPr(true);
|
||
this.private_UpdateTrackRevisionOnChangeTextPr(true);
|
||
};
|
||
ParaRun.prototype.Get_RFonts = function()
|
||
{
|
||
return this.Get_CompiledPr(false).RFonts;
|
||
};
|
||
ParaRun.prototype.Set_RFonts2 = function(oRFonts)
|
||
{
|
||
if (undefined !== oRFonts)
|
||
{
|
||
if (oRFonts.AsciiTheme)
|
||
{
|
||
this.SetRFontsAscii(undefined);
|
||
this.SetRFontsAsciiTheme(oRFonts.AsciiTheme);
|
||
}
|
||
else if (oRFonts.Ascii)
|
||
{
|
||
this.SetRFontsAscii(oRFonts.Ascii);
|
||
this.SetRFontsAsciiTheme(undefined);
|
||
}
|
||
else
|
||
{
|
||
if (null === oRFonts.Ascii)
|
||
this.SetRFontsAscii(undefined);
|
||
|
||
if (null === oRFonts.AsciiTheme)
|
||
this.SetRFontsAsciiTheme(undefined);
|
||
}
|
||
|
||
if (oRFonts.HAnsiTheme)
|
||
{
|
||
this.SetRFontsHAnsi(undefined);
|
||
this.SetRFontsHAnsiTheme(oRFonts.HAnsiTheme);
|
||
}
|
||
else if (oRFonts.HAnsi)
|
||
{
|
||
this.SetRFontsHAnsi(oRFonts.HAnsi);
|
||
this.SetRFontsHAnsiTheme(undefined);
|
||
}
|
||
else
|
||
{
|
||
if (null === oRFonts.HAnsi)
|
||
this.SetRFontsHAnsi(undefined);
|
||
|
||
if (null === oRFonts.HAnsiTheme)
|
||
this.SetRFontsHAnsiTheme(undefined);
|
||
}
|
||
|
||
if (oRFonts.CSTheme)
|
||
{
|
||
this.SetRFontsCS(undefined);
|
||
this.SetRFontsCSTheme(oRFonts.CSTheme);
|
||
}
|
||
else if (oRFonts.CS)
|
||
{
|
||
this.SetRFontsCS(oRFonts.CS);
|
||
this.SetRFontsCSTheme(undefined);
|
||
}
|
||
else
|
||
{
|
||
if (null === oRFonts.CS)
|
||
this.SetRFontsCS(undefined);
|
||
|
||
if (null === oRFonts.CSTheme)
|
||
this.SetRFontsCSTheme(undefined);
|
||
}
|
||
|
||
if (oRFonts.EastAsiaTheme)
|
||
{
|
||
this.SetRFontsEastAsia(undefined);
|
||
this.SetRFontsEastAsiaTheme(oRFonts.EastAsiaTheme);
|
||
}
|
||
else if (oRFonts.EastAsia)
|
||
{
|
||
this.SetRFontsEastAsia(oRFonts.EastAsia);
|
||
this.SetRFontsEastAsiaTheme(undefined);
|
||
}
|
||
else
|
||
{
|
||
if (null === oRFonts.EastAsia)
|
||
this.SetRFontsEastAsia(undefined);
|
||
|
||
if (null === oRFonts.EastAsiaTheme)
|
||
this.SetRFontsEastAsiaTheme(undefined);
|
||
}
|
||
|
||
if (undefined !== oRFonts.Hint)
|
||
this.SetRFontsHint(null === oRFonts.Hint ? undefined : oRFonts.Hint);
|
||
}
|
||
else
|
||
{
|
||
this.SetRFontsAscii(undefined);
|
||
this.SetRFontsAsciiTheme(undefined);
|
||
this.SetRFontsHAnsi(undefined);
|
||
this.SetRFontsHAnsiTheme(undefined);
|
||
this.SetRFontsCS(undefined);
|
||
this.SetRFontsCSTheme(undefined);
|
||
this.SetRFontsEastAsia(undefined);
|
||
this.SetRFontsEastAsiaTheme(undefined);
|
||
this.SetRFontsHint(undefined);
|
||
}
|
||
};
|
||
ParaRun.prototype.Set_RFont_ForMathRun = function()
|
||
{
|
||
this.SetRFontsAscii({Name : "Cambria Math", Index : -1});
|
||
this.SetRFontsCS({Name : "Cambria Math", Index : -1});
|
||
this.SetRFontsEastAsia({Name : "Cambria Math", Index : -1});
|
||
this.SetRFontsHAnsi({Name : "Cambria Math", Index : -1});
|
||
};
|
||
ParaRun.prototype.SetRFontsAscii = function(Value)
|
||
{
|
||
var _Value = (null === Value ? undefined : Value);
|
||
|
||
if (_Value !== this.Pr.RFonts.Ascii)
|
||
{
|
||
var OldValue = this.Pr.RFonts.Ascii;
|
||
this.Pr.RFonts.Ascii = _Value;
|
||
|
||
AscCommon.History.Add(new CChangesRunRFontsAscii(this, OldValue, _Value, this.private_IsCollPrChangeMine()));
|
||
this.Recalc_CompiledPr(true);
|
||
this.private_UpdateTrackRevisionOnChangeTextPr(true);
|
||
}
|
||
};
|
||
ParaRun.prototype.SetRFontsHAnsi = function(Value)
|
||
{
|
||
var _Value = (null === Value ? undefined : Value);
|
||
|
||
if (_Value !== this.Pr.RFonts.HAnsi)
|
||
{
|
||
var OldValue = this.Pr.RFonts.HAnsi;
|
||
this.Pr.RFonts.HAnsi = _Value;
|
||
|
||
AscCommon.History.Add(new CChangesRunRFontsHAnsi(this, OldValue, _Value, this.private_IsCollPrChangeMine()));
|
||
this.Recalc_CompiledPr(true);
|
||
this.private_UpdateTrackRevisionOnChangeTextPr(true);
|
||
}
|
||
};
|
||
ParaRun.prototype.SetRFontsCS = function(Value)
|
||
{
|
||
var _Value = (null === Value ? undefined : Value);
|
||
|
||
if (_Value !== this.Pr.RFonts.CS)
|
||
{
|
||
var OldValue = this.Pr.RFonts.CS;
|
||
this.Pr.RFonts.CS = _Value;
|
||
|
||
AscCommon.History.Add(new CChangesRunRFontsCS(this, OldValue, _Value, this.private_IsCollPrChangeMine()));
|
||
this.Recalc_CompiledPr(true);
|
||
this.private_UpdateTrackRevisionOnChangeTextPr(true);
|
||
}
|
||
};
|
||
ParaRun.prototype.SetRFontsEastAsia = function(Value)
|
||
{
|
||
var _Value = (null === Value ? undefined : Value);
|
||
|
||
if (_Value !== this.Pr.RFonts.EastAsia)
|
||
{
|
||
var OldValue = this.Pr.RFonts.EastAsia;
|
||
this.Pr.RFonts.EastAsia = _Value;
|
||
|
||
AscCommon.History.Add(new CChangesRunRFontsEastAsia(this, OldValue, _Value, this.private_IsCollPrChangeMine()));
|
||
this.Recalc_CompiledPr(true);
|
||
this.private_UpdateTrackRevisionOnChangeTextPr(true);
|
||
}
|
||
};
|
||
ParaRun.prototype.SetRFontsHint = function(Value)
|
||
{
|
||
var _Value = (null === Value ? undefined : Value);
|
||
|
||
if (_Value !== this.Pr.RFonts.Hint)
|
||
{
|
||
var OldValue = this.Pr.RFonts.Hint;
|
||
this.Pr.RFonts.Hint = _Value;
|
||
|
||
AscCommon.History.Add(new CChangesRunRFontsHint(this, OldValue, _Value, this.private_IsCollPrChangeMine()));
|
||
this.Recalc_CompiledPr(true);
|
||
this.private_UpdateTrackRevisionOnChangeTextPr(true);
|
||
}
|
||
};
|
||
ParaRun.prototype.SetRFontsAsciiTheme = function(sValue)
|
||
{
|
||
var _sValue = (!sValue ? undefined : sValue);
|
||
|
||
if (_sValue !== this.Pr.RFonts.AsciiTheme)
|
||
{
|
||
AscCommon.History.Add(new CChangesRunRFontsAsciiTheme(this, this.Pr.RFonts.AsciiTheme, _sValue, this.private_IsCollPrChangeMine()));
|
||
this.Pr.RFonts.AsciiTheme = _sValue;
|
||
this.Recalc_CompiledPr(true);
|
||
this.private_UpdateTrackRevisionOnChangeTextPr(true);
|
||
}
|
||
};
|
||
ParaRun.prototype.SetRFontsHAnsiTheme = function(sValue)
|
||
{
|
||
var _sValue = (!sValue ? undefined : sValue);
|
||
|
||
if (_sValue !== this.Pr.RFonts.HAnsiTheme)
|
||
{
|
||
AscCommon.History.Add(new CChangesRunRFontsHAnsiTheme(this, this.Pr.RFonts.HAnsiTheme, _sValue, this.private_IsCollPrChangeMine()));
|
||
this.Pr.RFonts.HAnsiTheme = _sValue;
|
||
this.Recalc_CompiledPr(true);
|
||
this.private_UpdateTrackRevisionOnChangeTextPr(true);
|
||
}
|
||
};
|
||
ParaRun.prototype.SetRFontsCSTheme = function(sValue)
|
||
{
|
||
var _sValue = (!sValue ? undefined : sValue);
|
||
|
||
if (_sValue !== this.Pr.RFonts.CSTheme)
|
||
{
|
||
AscCommon.History.Add(new CChangesRunRFontsCSTheme(this, this.Pr.RFonts.CSTheme, _sValue, this.private_IsCollPrChangeMine()));
|
||
this.Pr.RFonts.CSTheme = _sValue;
|
||
this.Recalc_CompiledPr(true);
|
||
this.private_UpdateTrackRevisionOnChangeTextPr(true);
|
||
}
|
||
};
|
||
ParaRun.prototype.SetRFontsEastAsiaTheme = function(sValue)
|
||
{
|
||
var _sValue = (!sValue ? undefined : sValue);
|
||
|
||
if (_sValue !== this.Pr.RFonts.EastAsiaTheme)
|
||
{
|
||
AscCommon.History.Add(new CChangesRunRFontsEastAsiaTheme(this, this.Pr.RFonts.EastAsiaTheme, _sValue, this.private_IsCollPrChangeMine()));
|
||
this.Pr.RFonts.EastAsiaTheme = _sValue;
|
||
this.Recalc_CompiledPr(true);
|
||
this.private_UpdateTrackRevisionOnChangeTextPr(true);
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.Set_Lang = function(Value)
|
||
{
|
||
var OldValue = this.Pr.Lang;
|
||
|
||
this.Pr.Lang = new CLang();
|
||
if ( undefined != Value )
|
||
this.Pr.Lang.Set_FromObject( Value );
|
||
|
||
AscCommon.History.Add(new CChangesRunLang(this, OldValue, this.Pr.Lang, this.private_IsCollPrChangeMine()));
|
||
this.Recalc_CompiledPr(false);
|
||
this.private_UpdateTrackRevisionOnChangeTextPr(true);
|
||
};
|
||
|
||
ParaRun.prototype.Set_Lang2 = function(Lang)
|
||
{
|
||
if ( undefined != Lang )
|
||
{
|
||
if ( undefined != Lang.Bidi )
|
||
this.Set_Lang_Bidi( Lang.Bidi );
|
||
|
||
if ( undefined != Lang.EastAsia )
|
||
this.Set_Lang_EastAsia( Lang.EastAsia );
|
||
|
||
if ( undefined != Lang.Val )
|
||
this.Set_Lang_Val( Lang.Val );
|
||
|
||
this.private_UpdateSpellChecking();
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.Set_Lang_Bidi = function(Value)
|
||
{
|
||
if ( Value !== this.Pr.Lang.Bidi )
|
||
{
|
||
var OldValue = this.Pr.Lang.Bidi;
|
||
this.Pr.Lang.Bidi = Value;
|
||
|
||
AscCommon.History.Add(new CChangesRunLangBidi(this, OldValue, Value, this.private_IsCollPrChangeMine()));
|
||
this.Recalc_CompiledPr(false);
|
||
this.private_UpdateTrackRevisionOnChangeTextPr(true);
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.Set_Lang_EastAsia = function(Value)
|
||
{
|
||
if ( Value !== this.Pr.Lang.EastAsia )
|
||
{
|
||
var OldValue = this.Pr.Lang.EastAsia;
|
||
this.Pr.Lang.EastAsia = Value;
|
||
|
||
AscCommon.History.Add(new CChangesRunLangEastAsia(this, OldValue, Value, this.private_IsCollPrChangeMine()));
|
||
this.Recalc_CompiledPr(false);
|
||
this.private_UpdateTrackRevisionOnChangeTextPr(true);
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.Set_Lang_Val = function(Value)
|
||
{
|
||
if ( Value !== this.Pr.Lang.Val )
|
||
{
|
||
var OldValue = this.Pr.Lang.Val;
|
||
this.Pr.Lang.Val = Value;
|
||
|
||
AscCommon.History.Add(new CChangesRunLangVal(this, OldValue, Value, this.private_IsCollPrChangeMine()));
|
||
this.Recalc_CompiledPr(false);
|
||
this.private_UpdateTrackRevisionOnChangeTextPr(true);
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.Set_Shd = function(Shd)
|
||
{
|
||
if ( (undefined === this.Pr.Shd && undefined === Shd) || (undefined !== this.Pr.Shd && undefined !== Shd && true === this.Pr.Shd.Compare( Shd ) ) )
|
||
return;
|
||
|
||
var OldShd = this.Pr.Shd;
|
||
|
||
if ( undefined !== Shd )
|
||
{
|
||
this.Pr.Shd = new CDocumentShd();
|
||
this.Pr.Shd.Set_FromObject( Shd );
|
||
}
|
||
else
|
||
this.Pr.Shd = undefined;
|
||
|
||
AscCommon.History.Add(new CChangesRunShd(this, OldShd, this.Pr.Shd, this.private_IsCollPrChangeMine()));
|
||
this.Recalc_CompiledPr(false);
|
||
this.private_UpdateTrackRevisionOnChangeTextPr(true);
|
||
};
|
||
ParaRun.prototype.SetLigatures = function(nType)
|
||
{
|
||
if (this.Pr.Ligatures === nType)
|
||
return;
|
||
|
||
AscCommon.History.Add(new CChangesRunLigatures(this, this.Pr.Ligatures, nType));
|
||
this.Pr.Ligatures = nType;
|
||
this.Recalc_CompiledPr(true);
|
||
this.private_UpdateShapeText();
|
||
this.private_UpdateTrackRevisionOnChangeTextPr(false);
|
||
};
|
||
ParaRun.prototype.IsCS = function()
|
||
{
|
||
return this.Get_CompiledPr(false).CS;
|
||
};
|
||
ParaRun.prototype.SetCS = function(isCS)
|
||
{
|
||
if (this.Pr.CS === isCS)
|
||
return;
|
||
|
||
let oChange = new CChangesRunCS(this, this.Pr.CS, isCS);
|
||
AscCommon.History.Add(oChange);
|
||
oChange.Redo();
|
||
};
|
||
ParaRun.prototype.IsRTL = function()
|
||
{
|
||
return this.Get_CompiledPr(false).RTL;
|
||
};
|
||
ParaRun.prototype.SetRTL = function(isRTL)
|
||
{
|
||
if (this.Pr.RTL === isRTL)
|
||
return;
|
||
|
||
let oChange = new CChangesRunRTL(this, this.Pr.RTL, isRTL);
|
||
AscCommon.History.Add(oChange);
|
||
oChange.Redo();
|
||
};
|
||
ParaRun.prototype.ApplyComplexScript = function(isCS)
|
||
{
|
||
if (isCS && !this.Pr.CS)
|
||
{
|
||
this.SetCS(true);
|
||
this.SetRFontsHint(AscWord.fonthint_CS);
|
||
|
||
if (undefined === this.Pr.BoldCS && undefined !== this.Pr.Bold)
|
||
this.SetBoldCS(this.Pr.Bold);
|
||
|
||
if (undefined === this.Pr.ItalicCS && undefined !== this.Pr.Italic)
|
||
this.SetItalicCS(this.Pr.Italic);
|
||
|
||
if (undefined === this.Pr.FontSizeCS && undefined !== this.Pr.FontSize)
|
||
this.SetFontSizeCS(this.Pr.FontSize);
|
||
}
|
||
else if (!isCS && this.Pr.CS)
|
||
{
|
||
this.SetCS(undefined);
|
||
this.SetRFontsHint(undefined);
|
||
|
||
if (undefined === this.Pr.Bold && undefined !== this.Pr.BoldCS)
|
||
this.SetBold(this.Pr.BoldCS);
|
||
|
||
if (undefined === this.Pr.Italic && undefined !== this.Pr.ItalicCS)
|
||
this.SetItalic(this.Pr.ItalicCS);
|
||
|
||
if (undefined === this.Pr.FontSize && undefined !== this.Pr.FontSizeCS)
|
||
this.SetFontSize(this.Pr.FontSizeCS);
|
||
}
|
||
};
|
||
ParaRun.prototype.IncreaseDecreaseFontSize = function(isIncrease)
|
||
{
|
||
let oTextPr = this.Get_CompiledPr(false);
|
||
this.private_AddCollPrChangeMine();
|
||
this.SetFontSizeCS(oTextPr.GetIncDecFontSizeCS(isIncrease));
|
||
this.SetFontSize(oTextPr.GetIncDecFontSize(isIncrease));
|
||
};
|
||
ParaRun.prototype.ApplyFontFamily = function(sFontName)
|
||
{
|
||
// let nFontSlot = this.GetFontSlotInRange(0, this.Content.length);
|
||
// if (nFontSlot & AscWord.fontslot_EastAsia)
|
||
// this.SetRFontsEastAsia({Name : sFontName, Index : -1});
|
||
|
||
// https://bugzilla.onlyoffice.com/show_bug.cgi?id=60106
|
||
// Пока мы не можем разруливать как в MSWord, потому что у нас нет возможности получать текущую раскладку
|
||
// и нет события о смене раскладки
|
||
this.SetRFontsEastAsia({Name : sFontName, Index : -1});
|
||
//------------------------------------------------------------------------------------------------------------------
|
||
|
||
this.SetRFontsAscii({Name : sFontName, Index : -1});
|
||
this.SetRFontsHAnsi({Name : sFontName, Index : -1});
|
||
this.SetRFontsCS({Name : sFontName, Index : -1});
|
||
|
||
this.SetRFontsAsciiTheme(undefined);
|
||
this.SetRFontsHAnsiTheme(undefined);
|
||
this.SetRFontsCSTheme(undefined);
|
||
};
|
||
//-----------------------------------------------------------------------------------
|
||
// Undo/Redo функции
|
||
//-----------------------------------------------------------------------------------
|
||
ParaRun.prototype.Check_HistoryUninon = function(Data1, Data2)
|
||
{
|
||
return (AscDFH.historyitem_ParaRun_AddItem === Data1.Type
|
||
&& AscDFH.historyitem_ParaRun_AddItem === Data2.Type
|
||
&& 1 === Data1.Items.length
|
||
&& 1 === Data2.Items.length
|
||
&& Data1.Pos === Data2.Pos - 1
|
||
&& ((Data1.Items[0].IsText() && Data2.Items[0].IsText())
|
||
|| (Data1.Items[0].IsSpace() && Data2.Items[0].IsSpace())));
|
||
};
|
||
//-----------------------------------------------------------------------------------
|
||
// Функции для совместного редактирования
|
||
//-----------------------------------------------------------------------------------
|
||
ParaRun.prototype.Write_ToBinary2 = function(Writer)
|
||
{
|
||
Writer.WriteLong( AscDFH.historyitem_type_ParaRun );
|
||
|
||
// Long : Type
|
||
// String : Id
|
||
// String : Paragraph Id
|
||
// Variable : CTextPr
|
||
// Long : ReviewType
|
||
// Bool : isUndefined ReviewInfo
|
||
// ->false : ReviewInfo
|
||
// Long : Количество элементов
|
||
// Array of variable : массив с элементами
|
||
|
||
Writer.WriteLong(this.Type);
|
||
var ParagraphToWrite, PrToWrite, ContentToWrite;
|
||
if(this.StartState)
|
||
{
|
||
ParagraphToWrite = this.StartState.Paragraph;
|
||
PrToWrite = this.StartState.Pr;
|
||
ContentToWrite = this.StartState.Content;
|
||
}
|
||
else
|
||
{
|
||
ParagraphToWrite = this.Paragraph;
|
||
PrToWrite = this.Pr;
|
||
ContentToWrite = this.Content;
|
||
}
|
||
|
||
Writer.WriteString2( this.Id );
|
||
Writer.WriteString2( null !== ParagraphToWrite && undefined !== ParagraphToWrite ? ParagraphToWrite.Get_Id() : "" );
|
||
PrToWrite.Write_ToBinary( Writer );
|
||
|
||
if (this.ReviewInfo)
|
||
{
|
||
Writer.WriteBool(false);
|
||
this.ReviewInfo.WriteToBinary(Writer);
|
||
}
|
||
else
|
||
{
|
||
Writer.WriteBool(true);
|
||
}
|
||
|
||
var Count = ContentToWrite.length;
|
||
Writer.WriteLong( Count );
|
||
for ( var Index = 0; Index < Count; Index++ )
|
||
{
|
||
var Item = ContentToWrite[Index];
|
||
Item.Write_ToBinary( Writer );
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.Read_FromBinary2 = function(Reader)
|
||
{
|
||
// Long : Type
|
||
// String : Id
|
||
// String : Paragraph Id
|
||
// Variable : CTextPr
|
||
// Long : ReviewType
|
||
// Bool : isUndefined ReviewInfo
|
||
// ->false : ReviewInfo
|
||
// Long : Количество элементов
|
||
// Array of variable : массив с элементами
|
||
|
||
this.Type = Reader.GetLong();
|
||
this.Id = Reader.GetString2();
|
||
this.Paragraph = g_oTableId.Get_ById( Reader.GetString2() );
|
||
this.Pr = new CTextPr();
|
||
this.Pr.Read_FromBinary( Reader );
|
||
|
||
if (!Reader.GetBool())
|
||
this.ReviewInfo = AscWord.ReviewInfo.fromBinary(Reader);
|
||
|
||
if (para_Math_Run == this.Type)
|
||
{
|
||
this.MathPrp = new CMPrp();
|
||
this.size = new CMathSize();
|
||
this.pos = new CMathPosition();
|
||
}
|
||
|
||
if(undefined !== editor && true === editor.isDocumentEditor)
|
||
{
|
||
var Count = Reader.GetLong();
|
||
this.Content = [];
|
||
for ( var Index = 0; Index < Count; Index++ )
|
||
{
|
||
var Element = AscWord.ReadRunElementFromBinary(Reader);
|
||
if ( null !== Element )
|
||
this.Content.push( Element );
|
||
}
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.Clear_CollaborativeMarks = function()
|
||
{
|
||
this.CollaborativeMarks.Clear();
|
||
this.CollPrChangeColor = null;
|
||
};
|
||
ParaRun.prototype.private_AddCollPrChangeMine = function()
|
||
{
|
||
this.CollPrChangeMine = true;
|
||
this.CollPrChangeColor = null;
|
||
};
|
||
ParaRun.prototype.private_IsCollPrChangeMine = function()
|
||
{
|
||
if (true === this.CollPrChangeMine)
|
||
return true;
|
||
|
||
return false;
|
||
};
|
||
ParaRun.prototype.setCollPrChangeColor = function(color)
|
||
{
|
||
this.CollPrChangeColor = color;
|
||
AscCommon.CollaborativeEditing.Add_ChangedClass(this);
|
||
};
|
||
ParaRun.prototype.getCollPrChangeColor = function()
|
||
{
|
||
return this.CollPrChangeColor;
|
||
};
|
||
/**
|
||
* Специальная функция-заглушка, добавляем элементы за знаком конца параграфа, для поддержки разделителей, лежащих
|
||
* между параграфами
|
||
* @param {AscWord.CRunElementBase} oElement
|
||
*/
|
||
ParaRun.prototype.AddAfterParaEnd = function(oElement)
|
||
{
|
||
this.State.ContentPos = this.Content.length;
|
||
this.AddToContent(this.State.ContentPos, oElement);
|
||
};
|
||
/**
|
||
* Специальная функция очищающая метки переноса во время рецензирования
|
||
* @param {AscWord.CTrackRevisionsManager} oTrackManager
|
||
*/
|
||
ParaRun.prototype.RemoveTrackMoveMarks = function(oTrackManager)
|
||
{
|
||
var oTrackMove = oTrackManager.GetProcessTrackMove();
|
||
|
||
var sMoveId = oTrackMove.GetMoveId();
|
||
var isFrom = oTrackMove.IsFrom();
|
||
|
||
for (var nPos = this.Content.length - 1; nPos >= 0; --nPos)
|
||
{
|
||
var oItem = this.Content[nPos];
|
||
if (para_RevisionMove === oItem.Type)
|
||
{
|
||
if (sMoveId === oItem.GetMarkId())
|
||
{
|
||
if (isFrom === oItem.IsFrom())
|
||
this.RemoveFromContent(nPos, 1, true);
|
||
}
|
||
else
|
||
{
|
||
oTrackMove.RegisterOtherMove(oItem.GetMarkId());
|
||
}
|
||
}
|
||
}
|
||
};
|
||
ParaRun.prototype.IsContainMathOperators = function ()
|
||
{
|
||
for (let i = 0; i < this.Content.length; i++)
|
||
{
|
||
let oCurrentMathText = this.Content[i];
|
||
let strOperator = String.fromCharCode(oCurrentMathText.value);
|
||
let isNamesOFLiteralsOperator = AscMath.MathLiterals.operator.SearchU(strOperator);
|
||
if (oCurrentMathText.IsBreakOperator() || isNamesOFLiteralsOperator)
|
||
return true;
|
||
}
|
||
return false;
|
||
};
|
||
ParaRun.prototype.IsContainSpaces = function ()
|
||
{
|
||
for (let i = 0; i < this.Content.length; i++)
|
||
{
|
||
let oCurrentMathText = this.Content[i];
|
||
let strSpace = String.fromCharCode(oCurrentMathText.value);
|
||
let isSpace = AscMath.MathLiterals.space.SearchU(strSpace);
|
||
if (isSpace)
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
ParaRun.prototype.IsContainNormalText = function()
|
||
{
|
||
for (let i = 0; i < this.Content.length; i++)
|
||
{
|
||
let oCurrentMathText = this.Content[i];
|
||
if (!oCurrentMathText.IsBreakOperator())
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
ParaRun.prototype.private_RecalcCtrPrp = function()
|
||
{
|
||
if (para_Math_Run === this.Type && undefined !== this.Parent && null !== this.Parent && null !== this.Parent.ParaMath)
|
||
this.Parent.ParaMath.SetRecalcCtrPrp(this);
|
||
};
|
||
function CParaRunSelection()
|
||
{
|
||
this.Use = false;
|
||
this.StartPos = 0;
|
||
this.EndPos = 0;
|
||
}
|
||
|
||
function CParaRunState()
|
||
{
|
||
this.Selection = new CParaRunSelection();
|
||
this.ContentPos = 0;
|
||
}
|
||
|
||
function CParaRunRecalcInfo()
|
||
{
|
||
this.TextPr = true; // Нужно ли пересчитать скомпилированные настройки
|
||
this.Measure = true; // Нужно ли перемерять элементы
|
||
this.Recalc = true; // Нужно ли пересчитывать (только если текстовый ран)
|
||
|
||
this.MeasurePositions = []; // Массив позиций элементов, которые нужно пересчитать
|
||
|
||
// Далее идут параметры, которые выставляются после пересчета данного Range, такие как пересчитывать ли нумерацию
|
||
this.NumberingItem = null;
|
||
this.NumberingUse = false; // Используется ли нумерация в данном ране
|
||
this.NumberingAdd = true; // Нужно ли в следующем ране использовать нумерацию
|
||
}
|
||
|
||
CParaRunRecalcInfo.prototype.Reset = function()
|
||
{
|
||
this.TextPr = true;
|
||
this.Measure = true;
|
||
this.Recalc = true;
|
||
|
||
this.MeasurePositions = [];
|
||
};
|
||
/**
|
||
* Вызываем данную функцию после пересчета элементов рана
|
||
*/
|
||
CParaRunRecalcInfo.prototype.ResetMeasure = function()
|
||
{
|
||
this.Measure = false;
|
||
this.MeasurePositions = [];
|
||
};
|
||
/**
|
||
* Проверяем нужен ли пересчет элементов рана
|
||
* @return {boolean}
|
||
*/
|
||
CParaRunRecalcInfo.prototype.IsMeasureNeed = function()
|
||
{
|
||
return (this.Measure || this.MeasurePositions.length > 0);
|
||
};
|
||
/**
|
||
* Регистрируем добавление элемента в ран
|
||
* @param nPos {number}
|
||
*/
|
||
CParaRunRecalcInfo.prototype.OnAdd = function(nPos)
|
||
{
|
||
if (this.Measure)
|
||
return;
|
||
|
||
for (var nIndex = 0, nCount = this.MeasurePositions.length; nIndex < nCount; ++nIndex)
|
||
{
|
||
if (this.MeasurePositions[nIndex] >= nPos)
|
||
this.MeasurePositions[nIndex]++;
|
||
}
|
||
|
||
this.MeasurePositions.push(nPos);
|
||
};
|
||
/**
|
||
* Регистрируем удаление элементов из рана
|
||
* @param nPos {number}
|
||
* @param nCount {number}
|
||
*/
|
||
CParaRunRecalcInfo.prototype.OnRemove = function(nPos, nCount)
|
||
{
|
||
if (this.Measure)
|
||
return;
|
||
|
||
for (var nIndex = 0, nLen = this.MeasurePositions.length; nIndex < nLen; ++nIndex)
|
||
{
|
||
if (nPos <= this.MeasurePositions[nIndex] && this.MeasurePositions[nIndex] <= nPos + nCount - 1)
|
||
{
|
||
this.MeasurePositions.splice(nIndex, 1);
|
||
nIndex--;
|
||
}
|
||
else if (this.MeasurePositions[nIndex] >= nPos + nCount)
|
||
{
|
||
this.MeasurePositions[nIndex] -= nCount;
|
||
}
|
||
}
|
||
};
|
||
|
||
function CParaRunRange(StartPos, EndPos)
|
||
{
|
||
this.StartPos = StartPos; // Начальная позиция в контенте, с которой начинается данный отрезок
|
||
this.EndPos = EndPos; // Конечная позиция в контенте, на которой заканчивается данный отрезок (перед которой)
|
||
}
|
||
|
||
function CParaRunLine()
|
||
{
|
||
this.Ranges = [];
|
||
this.Ranges[0] = new CParaRunRange( 0, 0 );
|
||
this.RangesLength = 0;
|
||
}
|
||
CParaRunLine.prototype.addRange = function(RangeIndex, StartPos, EndPos)
|
||
{
|
||
if (0 !== RangeIndex)
|
||
{
|
||
this.Ranges[RangeIndex] = new CParaRunRange(StartPos, EndPos);
|
||
this.RangesLength = RangeIndex + 1;
|
||
}
|
||
else
|
||
{
|
||
this.Ranges[0].StartPos = StartPos;
|
||
this.Ranges[0].EndPos = EndPos;
|
||
this.RangesLength = 1;
|
||
}
|
||
|
||
if (this.Ranges.length > this.RangesLength)
|
||
this.Ranges.legth = this.RangesLength;
|
||
};
|
||
|
||
CParaRunLine.prototype =
|
||
{
|
||
Copy : function()
|
||
{
|
||
var NewLine = new CParaRunLine();
|
||
|
||
NewLine.RangesLength = this.RangesLength;
|
||
|
||
for ( var CurRange = 0; CurRange < this.RangesLength; CurRange++ )
|
||
{
|
||
var Range = this.Ranges[CurRange];
|
||
NewLine.Ranges[CurRange] = new CParaRunRange( Range.StartPos, Range.EndPos );
|
||
}
|
||
|
||
return NewLine;
|
||
},
|
||
|
||
Compare : function(OtherLine, CurRange)
|
||
{
|
||
// Сначала проверим наличие данного отрезка в обеих строках
|
||
if ( this.RangesLength <= CurRange || OtherLine.RangesLength <= CurRange )
|
||
return false;
|
||
|
||
var OtherRange = OtherLine.Ranges[CurRange];
|
||
var ThisRange = this.Ranges[CurRange];
|
||
|
||
if ( OtherRange.StartPos !== ThisRange.StartPos || OtherRange.EndPos !== ThisRange.EndPos )
|
||
return false;
|
||
|
||
return true;
|
||
}
|
||
|
||
|
||
};
|
||
|
||
// Метка о конце или начале изменений пришедших от других соавторов документа
|
||
var pararun_CollaborativeMark_Start = 0x00;
|
||
var pararun_CollaborativeMark_End = 0x01;
|
||
|
||
function CParaRunCollaborativeMark(Pos, Type)
|
||
{
|
||
this.Pos = Pos;
|
||
this.Type = Type;
|
||
}
|
||
|
||
function FontSize_IncreaseDecreaseValue(bIncrease, Value)
|
||
{
|
||
// Закон изменения размеров :
|
||
// 1. Если значение меньше 8, тогда мы увеличиваем/уменьшаем по 1 (от 1 до 8)
|
||
// 2. Если значение больше 72, тогда мы увеличиваем/уменьшаем по 10 (от 80 до бесконечности
|
||
// 3. Если значение в отрезке [8,72], тогда мы переходим по следующим числам 8,9,10,11,12,14,16,18,20,22,24,26,28,36,48,72
|
||
|
||
var Sizes = [8,9,10,11,12,14,16,18,20,22,24,26,28,36,48,72];
|
||
|
||
var NewValue = Value;
|
||
if ( true === bIncrease )
|
||
{
|
||
if ( Value < Sizes[0] )
|
||
{
|
||
if ( Value >= Sizes[0] - 1 )
|
||
NewValue = Sizes[0];
|
||
else
|
||
NewValue = Math.floor(Value + 1);
|
||
}
|
||
else if ( Value >= Sizes[Sizes.length - 1] )
|
||
{
|
||
NewValue = Math.min( 300, Math.floor( Value / 10 + 1 ) * 10 );
|
||
}
|
||
else
|
||
{
|
||
for ( var Index = 0; Index < Sizes.length; Index++ )
|
||
{
|
||
if ( Value < Sizes[Index] )
|
||
{
|
||
NewValue = Sizes[Index];
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if ( Value <= Sizes[0] )
|
||
{
|
||
NewValue = Math.max( Math.floor( Value - 1 ), 1 );
|
||
}
|
||
else if ( Value > Sizes[Sizes.length - 1] )
|
||
{
|
||
if ( Value <= Math.floor( Sizes[Sizes.length - 1] / 10 + 1 ) * 10 )
|
||
NewValue = Sizes[Sizes.length - 1];
|
||
else
|
||
NewValue = Math.floor( Math.ceil(Value / 10) - 1 ) * 10;
|
||
}
|
||
else
|
||
{
|
||
for ( var Index = Sizes.length - 1; Index >= 0; Index-- )
|
||
{
|
||
if ( Value > Sizes[Index] )
|
||
{
|
||
NewValue = Sizes[Index];
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return NewValue;
|
||
}
|
||
|
||
|
||
function CRunCollaborativeMarks()
|
||
{
|
||
this.Ranges = [];
|
||
this.DrawingObj = {};
|
||
}
|
||
|
||
CRunCollaborativeMarks.prototype =
|
||
{
|
||
Add : function(PosS, PosE, Color)
|
||
{
|
||
var Count = this.Ranges.length;
|
||
for ( var Index = 0; Index < Count; Index++ )
|
||
{
|
||
var Range = this.Ranges[Index];
|
||
|
||
if ( PosS > Range.PosE )
|
||
continue;
|
||
else if ( PosS >= Range.PosS && PosS <= Range.PosE && PosE >= Range.PosS && PosE <= Range.PosE )
|
||
{
|
||
if ( true !== Color.Compare(Range.Color) )
|
||
{
|
||
var _PosE = Range.PosE;
|
||
Range.PosE = PosS;
|
||
this.Ranges.splice( Index + 1, 0, new CRunCollaborativeRange(PosS, PosE, Color) );
|
||
this.Ranges.splice( Index + 2, 0, new CRunCollaborativeRange(PosE, _PosE, Range.Color) );
|
||
}
|
||
|
||
return;
|
||
}
|
||
else if ( PosE < Range.PosS )
|
||
{
|
||
this.Ranges.splice( Index, 0, new CRunCollaborativeRange(PosS, PosE, Color) );
|
||
return;
|
||
}
|
||
else if ( PosS < Range.PosS && PosE > Range.PosE )
|
||
{
|
||
Range.PosS = PosS;
|
||
Range.PosE = PosE;
|
||
Range.Color = Color;
|
||
return;
|
||
}
|
||
else if ( PosS < Range.PosS ) // && PosE <= Range.PosE )
|
||
{
|
||
if ( true === Color.Compare(Range.Color) )
|
||
Range.PosS = PosS;
|
||
else
|
||
{
|
||
Range.PosS = PosE;
|
||
this.Ranges.splice( Index, 0, new CRunCollaborativeRange(PosS, PosE, Color) );
|
||
}
|
||
|
||
return;
|
||
}
|
||
else //if ( PosS >= Range.PosS && PosE > Range.Pos.E )
|
||
{
|
||
if ( true === Color.Compare(Range.Color) )
|
||
Range.PosE = PosE;
|
||
else
|
||
{
|
||
Range.PosE = PosS;
|
||
this.Ranges.splice( Index + 1, 0, new CRunCollaborativeRange(PosS, PosE, Color) );
|
||
}
|
||
|
||
return;
|
||
}
|
||
}
|
||
|
||
this.Ranges.push( new CRunCollaborativeRange(PosS, PosE, Color) );
|
||
},
|
||
|
||
Update_OnAdd : function(Pos)
|
||
{
|
||
var Count = this.Ranges.length;
|
||
for ( var Index = 0; Index < Count; Index++ )
|
||
{
|
||
var Range = this.Ranges[Index];
|
||
|
||
if ( Pos <= Range.PosS )
|
||
{
|
||
Range.PosS++;
|
||
Range.PosE++;
|
||
}
|
||
else if ( Pos > Range.PosS && Pos < Range.PosE )
|
||
{
|
||
var NewRange = new CRunCollaborativeRange( Pos + 1, Range.PosE + 1, Range.Color.Copy() );
|
||
this.Ranges.splice( Index + 1, 0, NewRange );
|
||
Range.PosE = Pos;
|
||
Count++;
|
||
Index++;
|
||
}
|
||
//else if ( Pos < Range.PosE )
|
||
// Range.PosE++;
|
||
}
|
||
},
|
||
|
||
Update_OnRemove : function(Pos, Count)
|
||
{
|
||
var Len = this.Ranges.length;
|
||
for ( var Index = 0; Index < Len; Index++ )
|
||
{
|
||
var Range = this.Ranges[Index];
|
||
|
||
var PosE = Pos + Count;
|
||
if ( Pos < Range.PosS )
|
||
{
|
||
if ( PosE <= Range.PosS )
|
||
{
|
||
Range.PosS -= Count;
|
||
Range.PosE -= Count;
|
||
}
|
||
else if ( PosE >= Range.PosE )
|
||
{
|
||
this.Ranges.splice( Index, 1 );
|
||
Len--;
|
||
Index--;continue;
|
||
}
|
||
else
|
||
{
|
||
Range.PosS = Pos;
|
||
Range.PosE -= Count;
|
||
}
|
||
}
|
||
else if ( Pos >= Range.PosS && Pos < Range.PosE )
|
||
{
|
||
if ( PosE >= Range.PosE )
|
||
Range.PosE = Pos;
|
||
else
|
||
Range.PosE -= Count;
|
||
}
|
||
else
|
||
continue;
|
||
}
|
||
},
|
||
|
||
Clear : function()
|
||
{
|
||
this.Ranges = [];
|
||
},
|
||
|
||
Init_Drawing : function()
|
||
{
|
||
this.DrawingObj = {};
|
||
|
||
var Count = this.Ranges.length;
|
||
for ( var CurPos = 0; CurPos < Count; CurPos++ )
|
||
{
|
||
var Range = this.Ranges[CurPos];
|
||
|
||
for ( var Pos = Range.PosS; Pos < Range.PosE; Pos++ )
|
||
this.DrawingObj[Pos] = Range.Color;
|
||
}
|
||
},
|
||
|
||
Check : function(Pos)
|
||
{
|
||
if ( undefined !== this.DrawingObj[Pos] )
|
||
return this.DrawingObj[Pos];
|
||
|
||
return null;
|
||
}
|
||
};
|
||
|
||
function CRunCollaborativeRange(PosS, PosE, Color)
|
||
{
|
||
this.PosS = PosS;
|
||
this.PosE = PosE;
|
||
this.Color = Color;
|
||
}
|
||
|
||
ParaRun.prototype.Math_SetPosition = function(pos, PosInfo)
|
||
{
|
||
var Line = PosInfo.CurLine,
|
||
Range = PosInfo.CurRange;
|
||
|
||
var CurLine = Line - this.StartLine;
|
||
var CurRange = ( 0 === CurLine ? Range - this.StartRange : Range );
|
||
|
||
var StartPos = this.protected_GetRangeStartPos(CurLine, CurRange);
|
||
var EndPos = this.protected_GetRangeEndPos(CurLine, CurRange);
|
||
|
||
// запомним позицию для recalculateCursorPosition, когда Run пустой
|
||
this.pos.x = pos.x;
|
||
this.pos.y = pos.y;
|
||
|
||
for(var Pos = StartPos; Pos < EndPos; Pos++)
|
||
{
|
||
var Item = this.Content[Pos];
|
||
if(PosInfo.DispositionOpers !== null && Item.Type == para_Math_BreakOperator)
|
||
{
|
||
PosInfo.DispositionOpers.push(pos.x + Item.GapLeft);
|
||
}
|
||
|
||
this.Content[Pos].setPosition(pos);
|
||
pos.x += this.Content[Pos].GetWidthVisible(); // GetWidth => GetWidthVisible
|
||
// GetWidthVisible - Width + Gaps с учетом настроек состояния
|
||
}
|
||
};
|
||
ParaRun.prototype.Math_Get_StartRangePos = function(_CurLine, _CurRange, SearchPos, Depth, bStartLine)
|
||
{
|
||
var CurLine = _CurLine - this.StartLine;
|
||
var CurRange = ( 0 === CurLine ? _CurRange - this.StartRange : _CurRange );
|
||
|
||
var StartPos = this.protected_GetRangeStartPos(CurLine, CurRange);
|
||
|
||
var Pos = this.State.ContentPos;
|
||
var Result = true;
|
||
|
||
if(bStartLine || StartPos < Pos)
|
||
{
|
||
SearchPos.Pos.Update(StartPos, Depth);
|
||
}
|
||
else
|
||
{
|
||
Result = false;
|
||
}
|
||
|
||
return Result;
|
||
};
|
||
ParaRun.prototype.Math_Get_EndRangePos = function(_CurLine, _CurRange, SearchPos, Depth, bEndLine)
|
||
{
|
||
var CurLine = _CurLine - this.StartLine;
|
||
var CurRange = ( 0 === CurLine ? _CurRange - this.StartRange : _CurRange );
|
||
|
||
var EndPos = this.protected_GetRangeEndPos(CurLine, CurRange);
|
||
|
||
var Pos = this.State.ContentPos;
|
||
var Result = true;
|
||
|
||
if(bEndLine || Pos < EndPos)
|
||
{
|
||
SearchPos.Pos.Update(EndPos, Depth);
|
||
}
|
||
else
|
||
{
|
||
Result = false;
|
||
}
|
||
|
||
return Result;
|
||
};
|
||
ParaRun.prototype.Math_Is_End = function(_CurLine, _CurRange)
|
||
{
|
||
var CurLine = _CurLine - this.StartLine;
|
||
var CurRange = ( 0 === CurLine ? _CurRange - this.StartRange : _CurRange );
|
||
|
||
var EndPos = this.protected_GetRangeEndPos(CurLine, CurRange);
|
||
|
||
return EndPos == this.Content.length;
|
||
};
|
||
ParaRun.prototype.IsEmptyRange = function(_CurLine, _CurRange)
|
||
{
|
||
var CurLine = _CurLine - this.StartLine;
|
||
var CurRange = ( 0 === CurLine ? _CurRange - this.StartRange : _CurRange );
|
||
|
||
var StartPos = this.protected_GetRangeStartPos(CurLine, CurRange);
|
||
var EndPos = this.protected_GetRangeEndPos(CurLine, CurRange);
|
||
|
||
return StartPos == EndPos;
|
||
};
|
||
ParaRun.prototype.Recalculate_Range_OneLine = function(PRS, ParaPr, Depth)
|
||
{
|
||
// данная функция используется только для мат объектов, которые на строки не разбиваются
|
||
|
||
// AscWord.CRunText (ParagraphContent.js)
|
||
// для настройки TextPr
|
||
// Measure
|
||
|
||
// FontClassification.js
|
||
// Get_FontClass
|
||
|
||
var Lng = this.Content.length;
|
||
|
||
var CurLine = PRS.Line - this.StartLine;
|
||
var CurRange = ( 0 === CurLine ? PRS.Range - this.StartRange : PRS.Range );
|
||
|
||
|
||
// обновляем позиции start и end для Range
|
||
var RangeStartPos = this.protected_AddRange(CurLine, CurRange);
|
||
var RangeEndPos = Lng;
|
||
|
||
this.Math_RecalculateContent(PRS);
|
||
|
||
this.protected_FillRange(CurLine, CurRange, RangeStartPos, RangeEndPos);
|
||
};
|
||
ParaRun.prototype.Math_RecalculateContent = function(PRS)
|
||
{
|
||
var WidthPoints = this.Parent.Get_WidthPoints();
|
||
this.bEqArray = this.Parent.IsEqArray();
|
||
|
||
var ascent = 0, descent = 0, width = 0;
|
||
|
||
this.Recalculate_MeasureContent();
|
||
var Lng = this.Content.length;
|
||
|
||
for(var i = 0 ; i < Lng; i++)
|
||
{
|
||
var Item = this.Content[i];
|
||
var size = Item.size,
|
||
Type = Item.Type;
|
||
|
||
var WidthItem = Item.GetWidthVisible(); // GetWidth => GetWidthVisible
|
||
// GetWidthVisible - Width + Gaps с учетом настроек состояния
|
||
width += WidthItem;
|
||
|
||
if(ascent < size.ascent)
|
||
ascent = size.ascent;
|
||
|
||
if (descent < size.height - size.ascent)
|
||
descent = size.height - size.ascent;
|
||
|
||
if(this.bEqArray)
|
||
{
|
||
if(Type === para_Math_Ampersand && true === Item.IsAlignPoint())
|
||
{
|
||
WidthPoints.AddNewAlignRange();
|
||
}
|
||
else
|
||
{
|
||
WidthPoints.UpdatePoint(WidthItem);
|
||
}
|
||
}
|
||
}
|
||
|
||
this.size.width = width;
|
||
this.size.ascent = ascent;
|
||
this.size.height = ascent + descent;
|
||
};
|
||
ParaRun.prototype.Math_Set_EmptyRange = function(_CurLine, _CurRange)
|
||
{
|
||
var CurLine = _CurLine - this.StartLine;
|
||
var CurRange = (0 === CurLine ? _CurRange - this.StartRange : _CurRange);
|
||
|
||
var RangeStartPos = this.protected_AddRange(CurLine, CurRange);
|
||
var RangeEndPos = RangeStartPos;
|
||
|
||
this.protected_FillRange(CurLine, CurRange, RangeStartPos, RangeEndPos);
|
||
};
|
||
// в этой функции проставляем состояние Gaps (крайние или нет) для всех операторов, к-ые участвуют в разбиении, чтобы не получилось случайно, что при изменении разбивки формулы на строки произошло, что у оператора не будет проставлен Gap
|
||
ParaRun.prototype.UpdateOperators = function(_CurLine, _CurRange, bEmptyGapLeft, bEmptyGapRight)
|
||
{
|
||
var CurLine = _CurLine - this.StartLine;
|
||
var CurRange = ( 0 === CurLine ? _CurRange - this.StartRange : _CurRange );
|
||
|
||
var StartPos = this.protected_GetRangeStartPos(CurLine, CurRange);
|
||
var EndPos = this.protected_GetRangeEndPos(CurLine, CurRange);
|
||
|
||
for(var Pos = StartPos; Pos < EndPos; Pos++)
|
||
{
|
||
var _bEmptyGapLeft = bEmptyGapLeft && Pos == StartPos,
|
||
_bEmptyGapRight = bEmptyGapRight && Pos == EndPos - 1;
|
||
|
||
this.Content[Pos].Update_StateGapLeft(_bEmptyGapLeft);
|
||
this.Content[Pos].Update_StateGapRight(_bEmptyGapRight);
|
||
}
|
||
};
|
||
ParaRun.prototype.Math_Apply_Style = function(Value)
|
||
{
|
||
if(Value !== this.MathPrp.sty)
|
||
{
|
||
var OldValue = this.MathPrp.sty;
|
||
this.MathPrp.sty = Value;
|
||
|
||
AscCommon.History.Add(new CChangesRunMathStyle(this, OldValue, Value));
|
||
|
||
this.Recalc_CompiledPr(true);
|
||
this.private_UpdateTrackRevisionOnChangeTextPr(true);
|
||
}
|
||
};
|
||
ParaRun.prototype.IsNormalText = function()
|
||
{
|
||
var comp_MPrp = this.MathPrp.GetCompiled_ScrStyles();
|
||
return comp_MPrp.nor === true;
|
||
};
|
||
ParaRun.prototype.getPropsForWrite = function()
|
||
{
|
||
var prRPr = null, wRPrp = null;
|
||
if(this.Paragraph && false === this.Paragraph.bFromDocument){
|
||
prRPr = this.Pr.Copy();
|
||
}
|
||
else{
|
||
wRPrp = this.Pr.Copy();
|
||
}
|
||
var mathRPrp = this.MathPrp.Copy();
|
||
|
||
return {wRPrp: wRPrp, mathRPrp: mathRPrp, prRPrp: prRPr};
|
||
};
|
||
ParaRun.prototype.GetMathPr = function(isCopy)
|
||
{
|
||
if (para_Math_Run === this.Type)
|
||
{
|
||
if (isCopy)
|
||
return this.MathPrp.Copy();
|
||
else
|
||
return this.MathPrp;
|
||
}
|
||
|
||
return null;
|
||
};
|
||
ParaRun.prototype.Math_PreRecalc = function(Parent, ParaMath, ArgSize, RPI, GapsInfo)
|
||
{
|
||
this.Parent = Parent;
|
||
this.Paragraph = ParaMath.Paragraph;
|
||
|
||
var FontSize = this.Get_CompiledPr(false).FontSize;
|
||
|
||
if(RPI.bChangeInline)
|
||
this.RecalcInfo.Measure = true; // нужно сделать пересчет элементов, например для дроби, т.к. ArgSize у внутренних контентов будет другой => размер
|
||
|
||
if(RPI.bCorrect_ConvertFontSize) // изменение FontSize после конвертации из старого формата в новый
|
||
{
|
||
var FontKoef;
|
||
|
||
if(ArgSize == -1 || ArgSize == -2)
|
||
{
|
||
var Pr = new CTextPr();
|
||
|
||
if(this.Pr.FontSize !== null && this.Pr.FontSize !== undefined)
|
||
{
|
||
FontKoef = MatGetKoeffArgSize(this.Pr.FontSize, ArgSize);
|
||
Pr.FontSize = (((this.Pr.FontSize/FontKoef * 2 + 0.5) | 0) / 2);
|
||
this.RecalcInfo.TextPr = true;
|
||
this.RecalcInfo.Measure = true;
|
||
}
|
||
|
||
if(this.Pr.FontSizeCS !== null && this.Pr.FontSizeCS !== undefined)
|
||
{
|
||
FontKoef = MatGetKoeffArgSize( this.Pr.FontSizeCS, ArgSize);
|
||
Pr.FontSizeCS = (((this.Pr.FontSizeCS/FontKoef * 2 + 0.5) | 0) / 2);
|
||
this.RecalcInfo.TextPr = true;
|
||
this.RecalcInfo.Measure = true;
|
||
}
|
||
|
||
this.Apply_Pr(Pr);
|
||
}
|
||
}
|
||
|
||
for (var Pos = 0 ; Pos < this.Content.length; Pos++ )
|
||
{
|
||
if( !this.Content[Pos].IsAlignPoint() )
|
||
GapsInfo.setGaps(this.Content[Pos], FontSize);
|
||
|
||
this.Content[Pos].PreRecalc(this, ParaMath);
|
||
this.Content[Pos].SetUpdateGaps(false);
|
||
}
|
||
|
||
};
|
||
ParaRun.prototype.Math_GetRealFontSize = function(FontSize)
|
||
{
|
||
var RealFontSize = FontSize ;
|
||
|
||
if(FontSize !== null && FontSize !== undefined)
|
||
{
|
||
var ArgSize = this.Parent.Compiled_ArgSz.value;
|
||
RealFontSize = FontSize*MatGetKoeffArgSize(FontSize, ArgSize);
|
||
}
|
||
|
||
return RealFontSize;
|
||
};
|
||
ParaRun.prototype.Math_GetFontSize = function(fromBegin)
|
||
{
|
||
let compiledPr = this.Get_CompiledPr(false);
|
||
let fontSize = compiledPr.FontSize;
|
||
if (this.Content.length > 0)
|
||
{
|
||
let runItem = this.Content[fromBegin ? 0 : this.Content.length - 1];
|
||
fontSize = runItem.IsCS() ? compiledPr.FontSizeCS : compiledPr.FontSize;
|
||
}
|
||
|
||
return this.Math_GetRealFontSize(fontSize);
|
||
};
|
||
ParaRun.prototype.Math_EmptyRange = function(_CurLine, _CurRange) // до пересчета нужно узнать будет ли данный Run пустым или нет в данном Range, необходимо для того, чтобы выставить wrapIndent
|
||
{
|
||
var bEmptyRange = true;
|
||
var Lng = this.Content.length;
|
||
|
||
if(Lng > 0)
|
||
{
|
||
var CurLine = _CurLine - this.StartLine;
|
||
var CurRange = ( 0 === CurLine ? _CurRange - this.StartRange : _CurRange );
|
||
|
||
bEmptyRange = this.protected_GetPrevRangeEndPos(CurLine, CurRange) >= Lng;
|
||
}
|
||
|
||
return bEmptyRange;
|
||
};
|
||
ParaRun.prototype.Math_UpdateGaps = function(_CurLine, _CurRange, GapsInfo)
|
||
{
|
||
var CurLine = _CurLine - this.StartLine;
|
||
var CurRange = ( 0 === CurLine ? _CurRange - this.StartRange : _CurRange );
|
||
|
||
var StartPos = this.protected_GetRangeStartPos(CurLine, CurRange);
|
||
var EndPos = this.protected_GetRangeEndPos(CurLine, CurRange);
|
||
|
||
var FontSize = this.Get_CompiledPr(false).FontSize;
|
||
|
||
for(var Pos = StartPos; Pos < EndPos; Pos++)
|
||
{
|
||
GapsInfo.updateCurrentObject(this.Content[Pos], FontSize);
|
||
|
||
var bUpdateCurrent = this.Content[Pos].IsNeedUpdateGaps();
|
||
|
||
if(bUpdateCurrent || GapsInfo.bUpdate)
|
||
{
|
||
GapsInfo.updateGaps();
|
||
}
|
||
|
||
GapsInfo.bUpdate = bUpdateCurrent;
|
||
|
||
this.Content[Pos].SetUpdateGaps(false);
|
||
|
||
}
|
||
};
|
||
ParaRun.prototype.Math_Can_ModidyForcedBreak = function(Pr, bStart, bEnd)
|
||
{
|
||
var Pos = this.Math_GetPosForcedBreak(bStart, bEnd);
|
||
|
||
if(Pos !== null)
|
||
{
|
||
if(this.MathPrp.IsBreak())
|
||
{
|
||
Pr.Set_DeleteForcedBreak();
|
||
}
|
||
else
|
||
{
|
||
Pr.Set_InsertForcedBreak();
|
||
}
|
||
}
|
||
|
||
};
|
||
ParaRun.prototype.Math_GetPosForcedBreak = function(bStart, bEnd)
|
||
{
|
||
var ResultPos = null;
|
||
|
||
if(this.Content.length > 0)
|
||
{
|
||
var StartPos = this.Selection.StartPos,
|
||
EndPos = this.Selection.EndPos,
|
||
bSelect = this.Selection.Use;
|
||
|
||
if(StartPos > EndPos)
|
||
{
|
||
StartPos = this.Selection.EndPos;
|
||
EndPos = this.Selection.StartPos;
|
||
}
|
||
|
||
var bCheckTwoItem = bSelect == false || (bSelect == true && EndPos == StartPos),
|
||
bCheckOneItem = bSelect == true && EndPos - StartPos == 1;
|
||
|
||
if(bStart)
|
||
{
|
||
ResultPos = this.Content[0].Type == para_Math_BreakOperator ? 0 : ResultPos;
|
||
}
|
||
else if(bEnd)
|
||
{
|
||
var lastPos = this.Content.length - 1;
|
||
ResultPos = this.Content[lastPos].Type == para_Math_BreakOperator ? lastPos : ResultPos;
|
||
}
|
||
else if(bCheckTwoItem)
|
||
{
|
||
var Pos = bSelect == false ? this.State.ContentPos : StartPos;
|
||
var bPrevBreakOperator = Pos > 0 ? this.Content[Pos - 1].Type == para_Math_BreakOperator : false,
|
||
bCurrBreakOperator = Pos < this.Content.length ? this.Content[Pos].Type == para_Math_BreakOperator : false;
|
||
|
||
if(bCurrBreakOperator)
|
||
{
|
||
ResultPos = Pos
|
||
}
|
||
else if(bPrevBreakOperator)
|
||
{
|
||
ResultPos = Pos - 1;
|
||
}
|
||
|
||
}
|
||
else if(bCheckOneItem)
|
||
{
|
||
if(this.Content[StartPos].Type == para_Math_BreakOperator)
|
||
{
|
||
ResultPos = StartPos;
|
||
}
|
||
}
|
||
}
|
||
|
||
return ResultPos;
|
||
};
|
||
ParaRun.prototype.Check_ForcedBreak = function(bStart, bEnd)
|
||
{
|
||
return this.Math_GetPosForcedBreak(bStart, bEnd) !== null;
|
||
};
|
||
ParaRun.prototype.Set_MathForcedBreak = function(bInsert, alnAt)
|
||
{
|
||
if (bInsert == true && false == this.MathPrp.IsBreak())
|
||
{
|
||
AscCommon.History.Add(new CChangesRunMathForcedBreak(this, true, alnAt));
|
||
this.MathPrp.Insert_ForcedBreak(alnAt);
|
||
}
|
||
else if (bInsert == false && true == this.MathPrp.IsBreak())
|
||
{
|
||
AscCommon.History.Add(new CChangesRunMathForcedBreak(this, false, this.MathPrp.Get_AlnAt()));
|
||
this.MathPrp.Delete_ForcedBreak();
|
||
}
|
||
};
|
||
ParaRun.prototype.Math_SplitRunForcedBreak = function()
|
||
{
|
||
var Pos = this.Math_GetPosForcedBreak();
|
||
var NewRun = null;
|
||
|
||
if(Pos != null && Pos > 0) // разбиваем Run на два
|
||
{
|
||
NewRun = this.Split_Run(Pos);
|
||
}
|
||
|
||
return NewRun;
|
||
};
|
||
ParaRun.prototype.UpdLastElementForGaps = function(_CurLine, _CurRange, GapsInfo)
|
||
{
|
||
var CurLine = _CurLine - this.StartLine;
|
||
var CurRange = ( 0 === CurLine ? _CurRange - this.StartRange : _CurRange );
|
||
|
||
var EndPos = this.protected_GetRangeEndPos(CurLine, CurRange);
|
||
var FontSize = this.Get_CompiledPr(false).FontSize;
|
||
var Last = this.Content[EndPos];
|
||
|
||
GapsInfo.updateCurrentObject(Last, FontSize);
|
||
|
||
};
|
||
ParaRun.prototype.IsPlaceholder = function()
|
||
{
|
||
return this.Content.length == 1 && this.Content[0].IsPlaceholder && this.Content[0].IsPlaceholder();
|
||
};
|
||
ParaRun.prototype.AddMathPlaceholder = function()
|
||
{
|
||
var oPlaceholder = new CMathText(false);
|
||
oPlaceholder.SetPlaceholder();
|
||
this.Add_ToContent(0, oPlaceholder, false);
|
||
|
||
// TODO: Расчет стилей разный для плейсхолдера и для текса (разобраться почему)
|
||
this.Recalc_CompiledPr();
|
||
};
|
||
ParaRun.prototype.RemoveMathPlaceholder = function()
|
||
{
|
||
for (var nPos = 0; nPos < this.Content.length; ++nPos)
|
||
{
|
||
if (para_Math_Placeholder === this.Content[nPos].Type)
|
||
{
|
||
this.Remove_FromContent(nPos, 1, true);
|
||
nPos--;
|
||
}
|
||
}
|
||
|
||
// TODO: Расчет стилей разный для плейсхолдера и для текса (разобраться почему)
|
||
this.Recalc_CompiledPr();
|
||
};
|
||
ParaRun.prototype.ProcessingOldEquationConvert = function()
|
||
{
|
||
for (let nPos = 0; nPos < this.Content.length; nPos++)
|
||
{
|
||
let oCurrentCMathText = this.Content[nPos];
|
||
|
||
if (oCurrentCMathText.value === 8202 || oCurrentCMathText.value === 8201)
|
||
{
|
||
this.Remove_FromContent(nPos, 1);
|
||
nPos--;
|
||
}
|
||
else if (oCurrentCMathText.value === 8203)
|
||
{
|
||
oCurrentCMathText.add("⥂".charCodeAt(0));
|
||
}
|
||
else if (oCurrentCMathText.value === 8197)
|
||
{
|
||
oCurrentCMathText.add(" ".charCodeAt(0)); //3/MSP
|
||
}
|
||
}
|
||
}
|
||
ParaRun.prototype.Set_MathPr = function(MPrp)
|
||
{
|
||
var OldValue = this.MathPrp;
|
||
this.MathPrp.Set_Pr(MPrp);
|
||
|
||
AscCommon.History.Add(new CChangesRunMathPrp(this, OldValue, this.MathPrp));
|
||
this.Recalc_CompiledPr(true);
|
||
this.private_UpdateTrackRevisionOnChangeTextPr(true);
|
||
};
|
||
ParaRun.prototype.Set_MathTextPr2 = function(TextPr, MathPr)
|
||
{
|
||
this.Set_Pr(TextPr.Copy());
|
||
this.Set_MathPr(MathPr.Copy());
|
||
};
|
||
ParaRun.prototype.IsAccent = function()
|
||
{
|
||
return this.Parent.IsAccent();
|
||
};
|
||
ParaRun.prototype.GetCompiled_ScrStyles = function()
|
||
{
|
||
return this.MathPrp.GetCompiled_ScrStyles();
|
||
};
|
||
ParaRun.prototype.IsEqArray = function()
|
||
{
|
||
return this.Parent.IsEqArray();
|
||
};
|
||
ParaRun.prototype.IsForcedBreak = function()
|
||
{
|
||
var bForcedBreak = false;
|
||
|
||
if(this.ParaMath!== null)
|
||
bForcedBreak = false == this.ParaMath.Is_Inline() && true == this.MathPrp.IsBreak();
|
||
|
||
return bForcedBreak;
|
||
};
|
||
ParaRun.prototype.Is_StartForcedBreakOperator = function()
|
||
{
|
||
var bStartOperator = this.Content.length > 0 && this.Content[0].Type == para_Math_BreakOperator;
|
||
return true == this.IsForcedBreak() && true == bStartOperator;
|
||
};
|
||
ParaRun.prototype.Get_AlignBrk = function(_CurLine, bBrkBefore)
|
||
{
|
||
// null - break отсутствует
|
||
// 0 - break присутствует, alnAt = undefined
|
||
// Number = break присутствует, alnAt = Number
|
||
|
||
|
||
// если оператор находится в конце строки и по этому оператору осушествляется принудительный перенос (Forced)
|
||
// тогда StartPos = 0, EndPos = 1 (для предыдущей строки), т.к. оператор с принудительным переносом всегда должен находится в начале Run
|
||
|
||
var CurLine = _CurLine - this.StartLine;
|
||
var AlnAt = null;
|
||
|
||
if(CurLine > 0)
|
||
{
|
||
var RangesCount = this.protected_GetRangesCount(CurLine - 1);
|
||
var StartPos = this.protected_GetRangeStartPos(CurLine - 1, RangesCount - 1);
|
||
var EndPos = this.protected_GetRangeEndPos(CurLine - 1, RangesCount - 1);
|
||
|
||
var bStartBreakOperator = bBrkBefore == true && StartPos == 0 && EndPos == 0;
|
||
var bEndBreakOperator = bBrkBefore == false && StartPos == 0 && EndPos == 1;
|
||
|
||
if(bStartBreakOperator || bEndBreakOperator)
|
||
{
|
||
AlnAt = false == this.Is_StartForcedBreakOperator() ? null : this.MathPrp.Get_AlignBrk();
|
||
}
|
||
}
|
||
|
||
return AlnAt;
|
||
};
|
||
ParaRun.prototype.Math_Is_InclineLetter = function()
|
||
{
|
||
var result = false;
|
||
|
||
if(this.Content.length == 1)
|
||
result = this.Content[0].Is_InclineLetter();
|
||
|
||
return result;
|
||
};
|
||
ParaRun.prototype.GetMathTextPrForMenu = function()
|
||
{
|
||
var TextPr = new CTextPr();
|
||
|
||
if(this.IsPlaceholder())
|
||
TextPr.Merge(this.Parent.GetCtrPrp());
|
||
|
||
TextPr.Merge(this.Pr);
|
||
|
||
var MathTextPr = this.MathPrp.Copy();
|
||
var BI = MathTextPr.GetBoldItalic();
|
||
|
||
TextPr.Italic = BI.Italic;
|
||
TextPr.Bold = BI.Bold;
|
||
|
||
return TextPr;
|
||
};
|
||
ParaRun.prototype.ToMathRun = function()
|
||
{
|
||
if (this.IsMathRun())
|
||
return this.Copy();
|
||
|
||
let oRun = new ParaRun(undefined, true);
|
||
for (var nPos = 0, nCount = this.Content.length; nPos < nCount; ++nPos)
|
||
{
|
||
let oMathItem = this.Content[nPos].ToMathElement();
|
||
if (oMathItem)
|
||
oRun.Add(oMathItem);
|
||
}
|
||
|
||
oRun.ApplyPr(this.GetDirectTextPr());
|
||
return oRun;
|
||
};
|
||
ParaRun.prototype.ApplyPoints = function(PointsInfo)
|
||
{
|
||
if(this.Parent.IsEqArray())
|
||
{
|
||
this.size.width = 0;
|
||
|
||
for(var Pos = 0; Pos < this.Content.length; Pos++)
|
||
{
|
||
var Item = this.Content[Pos];
|
||
if(Item.Type === para_Math_Ampersand && true === Item.IsAlignPoint())
|
||
{
|
||
PointsInfo.NextAlignRange();
|
||
Item.size.width = PointsInfo.GetAlign();
|
||
}
|
||
|
||
this.size.width += this.Content[Pos].GetWidthVisible(); // GetWidth => GetWidthVisible
|
||
// GetWidthVisible - Width + Gaps с учетом настроек состояния
|
||
}
|
||
}
|
||
};
|
||
ParaRun.prototype.IsShade = function()
|
||
{
|
||
var oShd = this.Get_CompiledPr(false).Shd;
|
||
return !(oShd === undefined || c_oAscShdNil === oShd.Value);
|
||
};
|
||
ParaRun.prototype.Get_RangesByPos = function(Pos)
|
||
{
|
||
var Ranges = [];
|
||
var LinesCount = this.protected_GetLinesCount();
|
||
for (var LineIndex = 0; LineIndex < LinesCount; LineIndex++)
|
||
{
|
||
var RangesCount = this.protected_GetRangesCount(LineIndex);
|
||
for (var RangeIndex = 0; RangeIndex < RangesCount; RangeIndex++)
|
||
{
|
||
var StartPos = this.protected_GetRangeStartPos(LineIndex, RangeIndex);
|
||
var EndPos = this.protected_GetRangeEndPos(LineIndex, RangeIndex);
|
||
|
||
if (StartPos <= Pos && Pos <= EndPos)
|
||
Ranges.push({Range : (LineIndex === 0 ? RangeIndex + this.StartRange : RangeIndex), Line : LineIndex + this.StartLine});
|
||
}
|
||
}
|
||
|
||
return Ranges;
|
||
};
|
||
ParaRun.prototype.CompareDrawingsLogicPositions = function(CompareObject)
|
||
{
|
||
var Drawing1 = CompareObject.Drawing1;
|
||
var Drawing2 = CompareObject.Drawing2;
|
||
|
||
for (var Pos = 0, Count = this.Content.length; Pos < Count; Pos++)
|
||
{
|
||
var Item = this.Content[Pos];
|
||
|
||
if (Item === Drawing1)
|
||
{
|
||
CompareObject.Result = 1;
|
||
return;
|
||
}
|
||
else if (Item === Drawing2)
|
||
{
|
||
CompareObject.Result = -1;
|
||
return;
|
||
}
|
||
}
|
||
};
|
||
ParaRun.prototype.GetReviewType = function()
|
||
{
|
||
return this.ReviewInfo ? this.ReviewInfo.getType() : reviewtype_Common;
|
||
};
|
||
ParaRun.prototype.GetReviewMoveType = function()
|
||
{
|
||
return this.ReviewInfo ? this.ReviewInfo.GetMoveType() : Asc.c_oAscRevisionsMove.NoMove;
|
||
};
|
||
ParaRun.prototype.RemoveReviewMoveType = function()
|
||
{
|
||
if (!this.ReviewInfo || Asc.c_oAscRevisionsMove.NoMove === this.ReviewInfo.GetMoveType())
|
||
return;
|
||
|
||
let newInfo = this.ReviewInfo.Copy();
|
||
newInfo.SetMoveType(Asc.c_oAscRevisionsMove.NoMove);
|
||
|
||
AscCommon.History.Add(new CChangesRunContentReviewInfo(this, this.ReviewInfo, newInfo.Copy()));
|
||
|
||
this.ReviewInfo = newInfo;
|
||
this.updateTrackRevisions();
|
||
};
|
||
ParaRun.prototype.GetReviewInfo = function()
|
||
{
|
||
return this.ReviewInfo;
|
||
};
|
||
ParaRun.prototype.GetReviewColor = function()
|
||
{
|
||
if (this.ReviewInfo)
|
||
return this.ReviewInfo.Get_Color();
|
||
|
||
return REVIEW_COLOR;
|
||
};
|
||
/**
|
||
* Меняем тип рецензирования для данного рана
|
||
* @param {number} nType
|
||
* @param {boolean} [isCheckDeleteAdded=false] - нужно ли проверять, что происходит удаление добавленного ранее
|
||
* @constructor
|
||
*/
|
||
ParaRun.prototype.SetReviewType = function(nType, isCheckDeleteAdded)
|
||
{
|
||
var oParagraph = this.GetParagraph();
|
||
if (this.IsParaEndRun() && oParagraph)
|
||
{
|
||
var oParent = oParagraph.GetParent();
|
||
if (reviewtype_Common !== nType
|
||
&& !oParagraph.Get_DocumentNext()
|
||
&& oParent
|
||
&& (oParent instanceof CDocument
|
||
|| (oParent instanceof CDocumentContent &&
|
||
oParent.GetParent() instanceof CTableCell)))
|
||
{
|
||
return;
|
||
}
|
||
}
|
||
|
||
if (nType === this.GetReviewType())
|
||
return;
|
||
|
||
let prevType = this.GetReviewType();
|
||
let prevInfo = this.ReviewInfo ? this.ReviewInfo.Copy() : undefined;
|
||
|
||
if (reviewtype_Add === prevType && reviewtype_Remove === nType && isCheckDeleteAdded)
|
||
this.ReviewInfo.SavePrev(prevType);
|
||
|
||
if (!this.ReviewInfo)
|
||
this.ReviewInfo = new AscWord.ReviewInfo();
|
||
|
||
this.ReviewInfo.setType(nType);
|
||
this.ReviewInfo.Update();
|
||
|
||
if (this.GetLogicDocument() && null !== this.GetLogicDocument().TrackMoveId)
|
||
this.ReviewInfo.SetMove(Asc.c_oAscRevisionsMove.MoveFrom);
|
||
|
||
AscCommon.History.Add(new CChangesRunContentReviewInfo(this, prevInfo, this.ReviewInfo.Copy()));
|
||
this.updateTrackRevisions();
|
||
};
|
||
/**
|
||
* Меняем тип рецензирования вместе с информацией о рецензента
|
||
* @param {number} reviewType
|
||
* @param {AscWord.ReviewInfo} reviewInfo
|
||
* @param {boolean} [isCheckLastParagraph=true] Нужно ли проверять последний параграф в документе или в ячейке таблицы
|
||
*/
|
||
ParaRun.prototype.SetReviewTypeWithInfo = function(reviewType, reviewInfo, isCheckLastParagraph)
|
||
{
|
||
var oParagraph = this.GetParagraph();
|
||
if (false !== isCheckLastParagraph && this.IsParaEndRun() && oParagraph)
|
||
{
|
||
var oParent = oParagraph.GetParent();
|
||
if (reviewtype_Common !== reviewType
|
||
&& !oParagraph.Get_DocumentNext()
|
||
&& oParent
|
||
&& (oParent instanceof CDocument
|
||
|| (oParent instanceof CDocumentContent &&
|
||
oParent.GetParent() instanceof CTableCell)))
|
||
{
|
||
return;
|
||
}
|
||
}
|
||
|
||
if (reviewtype_Common === reviewType)
|
||
reviewInfo = undefined;
|
||
else if (!reviewInfo)
|
||
reviewInfo = new AscWord.ReviewInfo();
|
||
|
||
if (reviewInfo)
|
||
reviewInfo.setType(reviewType);
|
||
|
||
AscCommon.History.Add(new CChangesRunContentReviewInfo(this, this.ReviewInfo ? this.ReviewInfo.Copy() : undefined, reviewInfo));
|
||
|
||
this.ReviewInfo = reviewInfo;
|
||
this.updateTrackRevisions();
|
||
};
|
||
ParaRun.prototype.Get_Parent = function()
|
||
{
|
||
return this.GetParent();
|
||
};
|
||
ParaRun.prototype.private_GetPosInParent = function(_Parent)
|
||
{
|
||
return this.GetPosInParent(_Parent);
|
||
};
|
||
ParaRun.prototype.Make_ThisElementCurrent = function(bUpdateStates)
|
||
{
|
||
if (this.IsUseInDocument())
|
||
{
|
||
this.SetThisElementCurrentInParagraph();
|
||
this.Paragraph.Document_SetThisElementCurrent(true === bUpdateStates ? true : false);
|
||
}
|
||
};
|
||
ParaRun.prototype.SetThisElementCurrent = function()
|
||
{
|
||
var ContentPos = this.Paragraph.Get_PosByElement(this);
|
||
if (!ContentPos)
|
||
return;
|
||
|
||
var StartPos = ContentPos.Copy();
|
||
this.Get_StartPos(StartPos, StartPos.GetDepth() + 1);
|
||
|
||
this.Paragraph.Set_ParaContentPos(StartPos, true, -1, -1, false);
|
||
this.Paragraph.Document_SetThisElementCurrent(false);
|
||
};
|
||
/**
|
||
* Устанавливаем курсор параграфа в текущую позицию данного рана
|
||
*/
|
||
ParaRun.prototype.SetThisElementCurrentInParagraph = function()
|
||
{
|
||
if (!this.Paragraph)
|
||
return;
|
||
|
||
var oContentPos = this.Paragraph.Get_PosByElement(this);
|
||
if (!oContentPos)
|
||
return;
|
||
|
||
oContentPos.Add(this.State.ContentPos);
|
||
this.Paragraph.Set_ParaContentPos(oContentPos, true, -1, -1, false);
|
||
};
|
||
ParaRun.prototype.GetDocumentPositionForCurrentPosition = function()
|
||
{
|
||
let docPos = this.GetDocumentPositionFromObject();
|
||
docPos.push({Class : this, Position : this.State.ContentPos});
|
||
return docPos;
|
||
};
|
||
ParaRun.prototype.GetAllParagraphs = function(Props, ParaArray)
|
||
{
|
||
var ContentLen = this.Content.length;
|
||
for (var CurPos = 0; CurPos < ContentLen; CurPos++)
|
||
{
|
||
if (para_Drawing === this.Content[CurPos].Type)
|
||
this.Content[CurPos].GetAllParagraphs(Props, ParaArray);
|
||
}
|
||
};
|
||
ParaRun.prototype.GetAllTables = function(oProps, arrTables)
|
||
{
|
||
if (!arrTables)
|
||
arrTables = [];
|
||
|
||
for (var nCurPos = 0, nLen = this.Content.length; nCurPos < nLen; ++nCurPos)
|
||
{
|
||
if (para_Drawing === this.Content[nCurPos].Type)
|
||
this.Content[nCurPos].GetAllTables(oProps, arrTables);
|
||
}
|
||
|
||
return arrTables;
|
||
};
|
||
ParaRun.prototype.CheckRevisionsChanges = function(Checker, ContentPos, Depth)
|
||
{
|
||
if (this.Is_Empty())
|
||
return;
|
||
|
||
if (true !== Checker.Is_ParaEndRun() && true !== Checker.Is_CheckOnlyTextPr())
|
||
{
|
||
var ReviewType = this.GetReviewType();
|
||
if (Checker.IsStopAddRemoveChange(ReviewType, this.GetReviewInfo()))
|
||
{
|
||
Checker.FlushAddRemoveChange();
|
||
ContentPos.Update(0, Depth);
|
||
|
||
if (reviewtype_Add === ReviewType || reviewtype_Remove === ReviewType)
|
||
Checker.StartAddRemove(ReviewType, ContentPos, this.GetReviewMoveType());
|
||
}
|
||
|
||
if (reviewtype_Add === ReviewType || reviewtype_Remove === ReviewType)
|
||
{
|
||
var Text = "";
|
||
var ContentLen = this.Content.length;
|
||
for (var CurPos = 0; CurPos < ContentLen; CurPos++)
|
||
{
|
||
var Item = this.Content[CurPos];
|
||
var ItemType = Item.Type;
|
||
switch (ItemType)
|
||
{
|
||
case para_Drawing:
|
||
{
|
||
Checker.Add_Text(Text);
|
||
Text = "";
|
||
Checker.Add_Drawing(Item);
|
||
break;
|
||
}
|
||
case para_Text :
|
||
{
|
||
Text += String.fromCharCode(Item.Value);
|
||
break;
|
||
}
|
||
case para_Math_Text:
|
||
{
|
||
Text += String.fromCharCode(Item.getCodeChr());
|
||
break;
|
||
}
|
||
case para_Space:
|
||
case para_Tab :
|
||
{
|
||
Text += " ";
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
Checker.Add_Text(Text);
|
||
ContentPos.Update(this.Content.length, Depth);
|
||
Checker.Set_AddRemoveEndPos(ContentPos);
|
||
Checker.Update_AddRemoveReviewInfo(this.ReviewInfo);
|
||
}
|
||
}
|
||
|
||
var HavePrChange = this.HavePrChange();
|
||
var DiffPr = this.GetDiffPrChange();
|
||
if (HavePrChange !== Checker.HavePrChange() || true !== Checker.ComparePrChange(DiffPr) || this.Pr.ReviewInfo.GetUserId() !== Checker.Get_PrChangeUserId())
|
||
{
|
||
Checker.FlushTextPrChange();
|
||
ContentPos.Update(0, Depth);
|
||
if (true === HavePrChange)
|
||
{
|
||
Checker.Start_PrChange(DiffPr, ContentPos);
|
||
}
|
||
}
|
||
|
||
if (true === HavePrChange)
|
||
{
|
||
ContentPos.Update(this.Content.length, Depth);
|
||
Checker.SetPrChangeEndPos(ContentPos);
|
||
Checker.Update_PrChangeReviewInfo(this.Pr.ReviewInfo);
|
||
}
|
||
};
|
||
ParaRun.prototype.private_UpdateTrackRevisionOnChangeContent = function(bUpdateInfo)
|
||
{
|
||
if (reviewtype_Common !== this.GetReviewType())
|
||
{
|
||
this.updateTrackRevisions();
|
||
|
||
if (true === bUpdateInfo && this.Paragraph && this.Paragraph.LogicDocument && this.Paragraph.bFromDocument && true === this.Paragraph.LogicDocument.IsTrackRevisions() && this.ReviewInfo && true === this.ReviewInfo.IsCurrentUser())
|
||
{
|
||
var OldReviewInfo = this.ReviewInfo.Copy();
|
||
this.ReviewInfo.Update();
|
||
AscCommon.History.Add(new CChangesRunContentReviewInfo(this, OldReviewInfo, this.ReviewInfo.Copy()));
|
||
}
|
||
}
|
||
};
|
||
ParaRun.prototype.private_UpdateTrackRevisionOnChangeTextPr = function(bUpdateInfo)
|
||
{
|
||
if (true === this.HavePrChange())
|
||
{
|
||
this.updateTrackRevisions();
|
||
|
||
if (true === bUpdateInfo && this.Paragraph && this.Paragraph.bFromDocument && this.Paragraph.LogicDocument && true === this.Paragraph.LogicDocument.IsTrackRevisions())
|
||
{
|
||
var OldReviewInfo = this.Pr.ReviewInfo.Copy();
|
||
this.Pr.ReviewInfo.Update();
|
||
AscCommon.History.Add(new CChangesRunPrReviewInfo(this, OldReviewInfo, this.Pr.ReviewInfo.Copy()));
|
||
}
|
||
}
|
||
};
|
||
ParaRun.prototype.AcceptRevisionChanges = function(nType, bAll)
|
||
{
|
||
if (this.Selection.Use && c_oAscRevisionsChangeType.MoveMarkRemove === nType)
|
||
return this.RemoveReviewMoveType();
|
||
|
||
var Parent = this.Get_Parent();
|
||
var RunPos = this.private_GetPosInParent();
|
||
|
||
var ReviewType = this.GetReviewType();
|
||
var HavePrChange = this.HavePrChange();
|
||
|
||
// Нет изменений в данном ране
|
||
if (reviewtype_Common === ReviewType && true !== HavePrChange)
|
||
return;
|
||
|
||
var oTrackManager = this.GetLogicDocument() ? this.GetLogicDocument().GetTrackRevisionsManager() : null;
|
||
var oProcessMove = oTrackManager ? oTrackManager.GetProcessTrackMove() : null;
|
||
|
||
if (true === this.Selection.Use || true === bAll)
|
||
{
|
||
var StartPos = this.Selection.StartPos;
|
||
var EndPos = this.Selection.EndPos;
|
||
if (StartPos > EndPos)
|
||
{
|
||
StartPos = this.Selection.EndPos;
|
||
EndPos = this.Selection.StartPos;
|
||
}
|
||
|
||
if (true === bAll)
|
||
{
|
||
StartPos = 0;
|
||
EndPos = this.Content.length;
|
||
}
|
||
|
||
var CenterRun = null, CenterRunPos = RunPos;
|
||
if (0 === StartPos && this.Content.length === EndPos)
|
||
{
|
||
CenterRun = this;
|
||
}
|
||
else if (StartPos > 0 && this.Content.length === EndPos)
|
||
{
|
||
CenterRun = this.Split2(StartPos, Parent, RunPos);
|
||
CenterRunPos = RunPos + 1;
|
||
}
|
||
else if (0 === StartPos && this.Content.length > EndPos)
|
||
{
|
||
CenterRun = this;
|
||
this.Split2(EndPos, Parent, RunPos);
|
||
}
|
||
else
|
||
{
|
||
this.Split2(EndPos, Parent, RunPos);
|
||
CenterRun = this.Split2(StartPos, Parent, RunPos);
|
||
CenterRunPos = RunPos + 1;
|
||
}
|
||
|
||
if (true === HavePrChange && (undefined === nType || c_oAscRevisionsChangeType.TextPr === nType))
|
||
{
|
||
CenterRun.RemovePrChange();
|
||
}
|
||
|
||
if (reviewtype_Add === ReviewType
|
||
&& (undefined === nType
|
||
|| c_oAscRevisionsChangeType.TextAdd === nType
|
||
|| (c_oAscRevisionsChangeType.MoveMark === nType
|
||
&& Asc.c_oAscRevisionsMove.NoMove !== this.GetReviewMoveType()
|
||
&& oProcessMove
|
||
&& !oProcessMove.IsFrom()
|
||
&& oProcessMove.GetUserId() === this.GetReviewInfo().GetUserId())))
|
||
{
|
||
CenterRun.SetReviewType(reviewtype_Common);
|
||
}
|
||
else if (reviewtype_Remove === ReviewType
|
||
&& (undefined === nType
|
||
|| c_oAscRevisionsChangeType.TextRem === nType
|
||
|| (c_oAscRevisionsChangeType.MoveMark === nType
|
||
&& Asc.c_oAscRevisionsMove.NoMove !== this.GetReviewMoveType()
|
||
&& oProcessMove
|
||
&& oProcessMove.IsFrom()
|
||
&& oProcessMove.GetUserId() === this.GetReviewInfo().GetUserId())))
|
||
{
|
||
Parent.RemoveFromContent(CenterRunPos, 1);
|
||
CenterRun.ClearContent();
|
||
|
||
if (Parent.GetContentLength() <= 0)
|
||
{
|
||
Parent.RemoveSelection();
|
||
Parent.AddToContent(0, new ParaRun());
|
||
Parent.MoveCursorToStartPos();
|
||
}
|
||
}
|
||
}
|
||
};
|
||
ParaRun.prototype.RejectRevisionChanges = function(nType, bAll)
|
||
{
|
||
var Parent = this.Get_Parent();
|
||
var RunPos = this.private_GetPosInParent();
|
||
|
||
var ReviewType = this.GetReviewType();
|
||
var HavePrChange = this.HavePrChange();
|
||
|
||
// Нет изменений в данном ране
|
||
if (reviewtype_Common === ReviewType && true !== HavePrChange)
|
||
return;
|
||
|
||
var oTrackManager = this.GetLogicDocument() ? this.GetLogicDocument().GetTrackRevisionsManager() : null;
|
||
var oProcessMove = oTrackManager ? oTrackManager.GetProcessTrackMove() : null;
|
||
|
||
if (true === this.Selection.Use || true === bAll)
|
||
{
|
||
var StartPos = this.Selection.StartPos;
|
||
var EndPos = this.Selection.EndPos;
|
||
if (StartPos > EndPos)
|
||
{
|
||
StartPos = this.Selection.EndPos;
|
||
EndPos = this.Selection.StartPos;
|
||
}
|
||
|
||
if (true === bAll)
|
||
{
|
||
StartPos = 0;
|
||
EndPos = this.Content.length;
|
||
}
|
||
|
||
var CenterRun = null, CenterRunPos = RunPos;
|
||
if (0 === StartPos && this.Content.length === EndPos)
|
||
{
|
||
CenterRun = this;
|
||
}
|
||
else if (StartPos > 0 && this.Content.length === EndPos)
|
||
{
|
||
CenterRun = this.Split2(StartPos, Parent, RunPos);
|
||
CenterRunPos = RunPos + 1;
|
||
}
|
||
else if (0 === StartPos && this.Content.length > EndPos)
|
||
{
|
||
CenterRun = this;
|
||
this.Split2(EndPos, Parent, RunPos);
|
||
}
|
||
else
|
||
{
|
||
this.Split2(EndPos, Parent, RunPos);
|
||
CenterRun = this.Split2(StartPos, Parent, RunPos);
|
||
CenterRunPos = RunPos + 1;
|
||
}
|
||
|
||
if (true === HavePrChange && (undefined === nType || c_oAscRevisionsChangeType.TextPr === nType))
|
||
{
|
||
CenterRun.Set_Pr(CenterRun.Pr.PrChange);
|
||
}
|
||
|
||
let reviewInfo = this.GetReviewInfo();
|
||
let prevInfo = reviewInfo ? reviewInfo.GetPrevAdded() : null;
|
||
if ((reviewtype_Add === ReviewType
|
||
&& (undefined === nType
|
||
|| c_oAscRevisionsChangeType.TextAdd === nType
|
||
|| (c_oAscRevisionsChangeType.MoveMark === nType
|
||
&& Asc.c_oAscRevisionsMove.NoMove !== this.GetReviewMoveType()
|
||
&& oProcessMove
|
||
&& !oProcessMove.IsFrom()
|
||
&& oProcessMove.GetUserId() === reviewInfo.GetUserId())))
|
||
|| (undefined === nType
|
||
&& bAll
|
||
&& reviewtype_Remove === ReviewType
|
||
&& prevInfo))
|
||
{
|
||
Parent.RemoveFromContent(CenterRunPos, 1);
|
||
CenterRun.ClearContent();
|
||
|
||
if (Parent.GetContentLength() <= 0)
|
||
{
|
||
Parent.RemoveSelection();
|
||
Parent.AddToContent(0, new ParaRun());
|
||
Parent.MoveCursorToStartPos();
|
||
}
|
||
}
|
||
else if (reviewtype_Remove === ReviewType
|
||
&& (undefined === nType
|
||
|| c_oAscRevisionsChangeType.TextRem === nType
|
||
|| (c_oAscRevisionsChangeType.MoveMark === nType
|
||
&& Asc.c_oAscRevisionsMove.NoMove !== this.GetReviewMoveType()
|
||
&& oProcessMove
|
||
&& oProcessMove.IsFrom()
|
||
&& oProcessMove.GetUserId() === reviewInfo.GetUserId())))
|
||
{
|
||
if (prevInfo && c_oAscRevisionsChangeType.MoveMark !== nType)
|
||
{
|
||
CenterRun.SetReviewTypeWithInfo(reviewtype_Add, prevInfo.Copy());
|
||
}
|
||
else
|
||
{
|
||
CenterRun.SetReviewType(reviewtype_Common);
|
||
}
|
||
}
|
||
}
|
||
};
|
||
ParaRun.prototype.IsInHyperlink = function()
|
||
{
|
||
if (!this.Paragraph)
|
||
return false;
|
||
|
||
var ContentPos = this.Paragraph.Get_PosByElement(this);
|
||
var Classes = this.Paragraph.Get_ClassesByPos(ContentPos);
|
||
|
||
var bHyper = false;
|
||
var bRun = false;
|
||
|
||
for (var Index = 0, Count = Classes.length; Index < Count; Index++)
|
||
{
|
||
var Item = Classes[Index];
|
||
if (Item === this)
|
||
{
|
||
bRun = true;
|
||
break;
|
||
}
|
||
else if (Item instanceof ParaHyperlink)
|
||
{
|
||
bHyper = true;
|
||
}
|
||
}
|
||
|
||
return (bHyper && bRun);
|
||
};
|
||
ParaRun.prototype.Get_ClassesByPos = function(Classes, ContentPos, Depth)
|
||
{
|
||
Classes.push(this);
|
||
};
|
||
/**
|
||
* Получаем позицию данного рана в родительском параграфе
|
||
* @param nInObjectPos {?number}
|
||
* @returns {?AscWord.CParagraphContentPos}
|
||
*/
|
||
ParaRun.prototype.GetParagraphContentPosFromObject = function(nInObjectPos)
|
||
{
|
||
if (undefined === nInObjectPos)
|
||
nInObjectPos = 0;
|
||
|
||
var oParagraph = this.GetParagraph();
|
||
if (!oParagraph)
|
||
return null;
|
||
|
||
var oContentPos = oParagraph.GetPosByElement(this);
|
||
if (!oContentPos)
|
||
return null;
|
||
|
||
oContentPos.Add(nInObjectPos);
|
||
return oContentPos;
|
||
};
|
||
ParaRun.prototype.Displace_BreakOperator = function(isForward, bBrkBefore, CountOperators)
|
||
{
|
||
var bResult = true;
|
||
var bFirstItem = this.State.ContentPos == 0 || this.State.ContentPos == 1,
|
||
bLastItem = this.State.ContentPos == this.Content.length - 1 || this.State.ContentPos == this.Content.length;
|
||
|
||
if(true === this.Is_StartForcedBreakOperator() && bFirstItem == true)
|
||
{
|
||
var AlnAt = this.MathPrp.Get_AlnAt();
|
||
|
||
var NotIncrease = AlnAt == CountOperators && isForward == true;
|
||
|
||
if(NotIncrease == false)
|
||
{
|
||
this.MathPrp.Displace_Break(isForward);
|
||
|
||
var NewAlnAt = this.MathPrp.Get_AlnAt();
|
||
|
||
if(AlnAt !== NewAlnAt)
|
||
{
|
||
AscCommon.History.Add(new CChangesRunMathAlnAt(this, AlnAt, NewAlnAt));
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
bResult = (bLastItem && bBrkBefore) || (bFirstItem && !bBrkBefore) ? false : true;
|
||
}
|
||
|
||
return bResult; // применили смещение к данному Run
|
||
};
|
||
ParaRun.prototype.Math_UpdateLineMetrics = function(PRS, ParaPr)
|
||
{
|
||
var LineRule = ParaPr.Spacing.LineRule;
|
||
|
||
let textMetrics = this.getTextMetrics();
|
||
let ascent = textMetrics.Ascent + textMetrics.LineGap;
|
||
let ascent2 = textMetrics.Ascent;
|
||
let descent = textMetrics.Descent;
|
||
|
||
// Пересчитаем метрику строки относительно размера данного текста
|
||
if ( PRS.LineTextAscent < ascent )
|
||
PRS.LineTextAscent = ascent;
|
||
|
||
if ( PRS.LineTextAscent2 < ascent2 )
|
||
PRS.LineTextAscent2 = ascent2;
|
||
|
||
if ( PRS.LineTextDescent < descent )
|
||
PRS.LineTextDescent = descent;
|
||
|
||
if ( Asc.linerule_Exact === LineRule )
|
||
{
|
||
// Смещение не учитывается в метриках строки, когда расстояние между строк точное
|
||
if ( PRS.LineAscent < ascent )
|
||
PRS.LineAscent = ascent;
|
||
|
||
if ( PRS.LineDescent < descent )
|
||
PRS.LineDescent = descent;
|
||
}
|
||
else
|
||
{
|
||
let yOffset = this.getYOffset();
|
||
if ( PRS.LineAscent < ascent + yOffset)
|
||
PRS.LineAscent = ascent + yOffset;
|
||
|
||
if ( PRS.LineDescent < descent - yOffset)
|
||
PRS.LineDescent = descent - yOffset;
|
||
}
|
||
|
||
};
|
||
ParaRun.prototype.Set_CompositeInput = function(oCompositeInput)
|
||
{
|
||
this.CompositeInput = oCompositeInput;
|
||
};
|
||
ParaRun.prototype.GetFootnotesList = function(oEngine)
|
||
{
|
||
for (var nIndex = 0, nCount = this.Content.length; nIndex < nCount; ++nIndex)
|
||
{
|
||
var oItem = this.Content[nIndex];
|
||
if ((oEngine.IsCheckFootnotes() && para_FootnoteReference === oItem.Type) || (oEngine.IsCheckEndnotes() && para_EndnoteReference === oItem.Type))
|
||
{
|
||
oEngine.Add(oItem.GetFootnote(), oItem, this);
|
||
}
|
||
}
|
||
};
|
||
ParaRun.prototype.GetParaEnd = function()
|
||
{
|
||
for (var nIndex = 0, nCount = this.Content.length; nIndex < nCount; ++nIndex)
|
||
{
|
||
if (this.Content[nIndex].Type === para_End)
|
||
return this.Content[nIndex];
|
||
}
|
||
|
||
return null;
|
||
};
|
||
/**
|
||
* Проверяем, является ли это ран со знаком конца параграфа
|
||
* @returns {boolean}
|
||
*/
|
||
ParaRun.prototype.IsParaEndRun = function()
|
||
{
|
||
return this.GetParaEnd() ? true : false;
|
||
};
|
||
ParaRun.prototype.RemoveElement = function(oElement)
|
||
{
|
||
for (var nIndex = 0, nCount = this.Content.length; nIndex < nCount; ++nIndex)
|
||
{
|
||
if (oElement === this.Content[nIndex])
|
||
{
|
||
this.RemoveFromContent(nIndex, 1, true);
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
};
|
||
ParaRun.prototype.GotoFootnoteRef = function(isNext, isCurrent, isStepOver, isStepFootnote, isStepEndnote)
|
||
{
|
||
var nPos = 0;
|
||
if (true === isCurrent)
|
||
{
|
||
if (true === this.Selection.Use)
|
||
nPos = Math.min(this.Selection.StartPos, this.Selection.EndPos);
|
||
else
|
||
nPos = this.State.ContentPos;
|
||
}
|
||
else
|
||
{
|
||
if (true === isNext)
|
||
nPos = 0;
|
||
else
|
||
nPos = this.Content.length - 1;
|
||
}
|
||
|
||
var nResult = 0;
|
||
if (true === isNext)
|
||
{
|
||
for (var nIndex = nPos, nCount = this.Content.length; nIndex < nCount; ++nIndex)
|
||
{
|
||
if (((para_FootnoteReference === this.Content[nIndex].Type && isStepFootnote) || (para_EndnoteReference === this.Content[nIndex].Type && isStepEndnote))
|
||
&& ((true !== isCurrent && true === isStepOver) || (true === isCurrent && (true === this.Selection.Use || nPos !== nIndex))))
|
||
{
|
||
if (this.Paragraph && this.Paragraph.bFromDocument && this.Paragraph.LogicDocument)
|
||
this.Paragraph.LogicDocument.RemoveSelection();
|
||
|
||
this.State.ContentPos = nIndex;
|
||
this.Make_ThisElementCurrent(true);
|
||
return -1;
|
||
}
|
||
nResult++;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
for (var nIndex = Math.min(nPos, this.Content.length - 1); nIndex >= 0; --nIndex)
|
||
{
|
||
if (((para_FootnoteReference === this.Content[nIndex].Type && isStepFootnote) || (para_EndnoteReference === this.Content[nIndex].Type && isStepEndnote))
|
||
&& ((true !== isCurrent && true === isStepOver) || (true === isCurrent && (true === this.Selection.Use || nPos !== nIndex))))
|
||
{
|
||
if (this.Paragraph && this.Paragraph.bFromDocument && this.Paragraph.LogicDocument)
|
||
this.Paragraph.LogicDocument.RemoveSelection();
|
||
|
||
this.State.ContentPos = nIndex;
|
||
this.Make_ThisElementCurrent(true);
|
||
return -1;
|
||
}
|
||
nResult++;
|
||
}
|
||
}
|
||
|
||
return nResult;
|
||
};
|
||
ParaRun.prototype.GetFootnoteRefsInRange = function(arrFootnotes, _CurLine, _CurRange)
|
||
{
|
||
var CurLine = _CurLine - this.StartLine;
|
||
var CurRange = (0 === CurLine ? _CurRange - this.StartRange : _CurRange);
|
||
|
||
var StartPos = this.protected_GetRangeStartPos(CurLine, CurRange);
|
||
var EndPos = this.protected_GetRangeEndPos(CurLine, CurRange);
|
||
|
||
for (var CurPos = StartPos; CurPos < EndPos; CurPos++)
|
||
{
|
||
if (para_FootnoteReference === this.Content[CurPos].Type || para_EndnoteReference === this.Content[CurPos].Type)
|
||
arrFootnotes.push(this.Content[CurPos]);
|
||
}
|
||
};
|
||
ParaRun.prototype.GetSelectedContentControls = function(arrContentControls)
|
||
{
|
||
let startPos = (this.Selection.StartPos < this.Selection.EndPos ? this.Selection.StartPos : this.Selection.EndPos);
|
||
let endPos = (this.Selection.StartPos < this.Selection.EndPos ? this.Selection.EndPos : this.Selection.StartPos);
|
||
|
||
for (let i = startPos; i < endPos; ++i)
|
||
{
|
||
let item = this.Content[i];
|
||
if (item.IsDrawing())
|
||
item.GetAllContentControls(arrContentControls);
|
||
}
|
||
};
|
||
ParaRun.prototype.GetAllContentControls = function(arrContentControls)
|
||
{
|
||
if (!arrContentControls)
|
||
return;
|
||
|
||
for (var nIndex = 0, nCount = this.Content.length; nIndex < nCount; ++nIndex)
|
||
{
|
||
var oItem = this.Content[nIndex];
|
||
if (para_Drawing === oItem.Type || para_FootnoteReference === oItem.Type || para_EndnoteReference === oItem.Type)
|
||
{
|
||
oItem.GetAllContentControls(arrContentControls);
|
||
}
|
||
}
|
||
};
|
||
/**
|
||
* Получаем позицию заданного элемента
|
||
* @param oElement
|
||
* @returns {number} позиция, либо -1, если заданного элемента нет
|
||
*/
|
||
ParaRun.prototype.GetElementPosition = function(oElement)
|
||
{
|
||
for (var nPos = 0, nCount = this.Content.length; nPos < nCount; ++nPos)
|
||
{
|
||
if (oElement === this.Content[nPos])
|
||
return nPos;
|
||
}
|
||
|
||
return -1;
|
||
};
|
||
/**
|
||
* Устанавливаем текущее положение позиции курсора в данном ране
|
||
* @param nPos
|
||
*/
|
||
ParaRun.prototype.SetCursorPosition = function(nPos)
|
||
{
|
||
this.State.ContentPos = Math.max(0, Math.min(nPos, this.Content.length));
|
||
};
|
||
/**
|
||
* Получаем номер строки по заданной позиции.
|
||
* @param nPos
|
||
*/
|
||
ParaRun.prototype.GetLineByPosition = function(nPos)
|
||
{
|
||
for (var nLineIndex = 0, nLinesCount = this.protected_GetLinesCount(); nLineIndex < nLinesCount; ++nLineIndex)
|
||
{
|
||
for (var nRangeIndex = 0, nRangesCount = this.protected_GetRangesCount(nLineIndex); nRangeIndex < nRangesCount; ++nRangeIndex)
|
||
{
|
||
var nStartPos = this.protected_GetRangeStartPos(nLineIndex, nRangeIndex);
|
||
var nEndPos = this.protected_GetRangeEndPos(nLineIndex, nRangeIndex);
|
||
|
||
if (nPos >= nStartPos && nPos < nEndPos)
|
||
return nLineIndex + this.StartLine;
|
||
}
|
||
}
|
||
|
||
return this.StartLine;
|
||
};
|
||
/**
|
||
* Данная функция вызывается перед удалением данного рана из родительского класса.
|
||
*/
|
||
ParaRun.prototype.PreDelete = function(isDeep)
|
||
{
|
||
if (this.Paragraph && this.Paragraph.isPreventedPreDelete())
|
||
return;
|
||
|
||
// TODO: Перенести это, когда удаляется непосредственно элемент из класса
|
||
// Сейчас работает не совсем корректно, потому что при большой вложенности у элементов чистится Parent,
|
||
// хотя по факту он должен чистится только у первого уровня элементов, с которых начинается удаление
|
||
if (true !== isDeep)
|
||
this.SetParent(null);
|
||
|
||
for (var nIndex = 0, nCount = this.Content.length; nIndex < nCount; ++nIndex)
|
||
{
|
||
if (this.Content[nIndex].PreDelete)
|
||
this.Content[nIndex].PreDelete(true);
|
||
}
|
||
|
||
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;
|
||
for (var nPos = 0; nPos < nEndPos; ++nPos)
|
||
{
|
||
var oItem = this.Content[nPos];
|
||
if (oItem.Type !== para_FieldChar)
|
||
continue;
|
||
|
||
if (isFieldPos)
|
||
{
|
||
var oComplexField = oItem.GetComplexField();
|
||
if (oItem.IsBegin())
|
||
{
|
||
arrComplexFields.push(new CComplexFieldStatePos(oComplexField, true));
|
||
}
|
||
else if (oItem.IsSeparate())
|
||
{
|
||
if (arrComplexFields.length > 0)
|
||
{
|
||
arrComplexFields[arrComplexFields.length - 1].SetFieldCode(false)
|
||
}
|
||
}
|
||
else if (oItem.IsEnd())
|
||
{
|
||
if (arrComplexFields.length > 0)
|
||
{
|
||
arrComplexFields.splice(arrComplexFields.length - 1, 1);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (oItem.IsBegin())
|
||
{
|
||
arrComplexFields.push(oItem.GetComplexField());
|
||
}
|
||
else if (oItem.IsEnd())
|
||
{
|
||
if (arrComplexFields.length > 0)
|
||
{
|
||
arrComplexFields.splice(arrComplexFields.length - 1, 1);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
};
|
||
ParaRun.prototype.RemoveTabsForTOC = function(_isTab)
|
||
{
|
||
var isTab = _isTab;
|
||
for (var nPos = 0; nPos < this.Content.length; ++nPos)
|
||
{
|
||
if (para_Tab === this.Content[nPos].Type)
|
||
{
|
||
if (!isTab)
|
||
{
|
||
// Первый таб в параграфе оставляем
|
||
isTab = true;
|
||
}
|
||
else
|
||
{
|
||
this.Remove_FromContent(nPos, 1);
|
||
}
|
||
}
|
||
}
|
||
|
||
return isTab;
|
||
};
|
||
ParaRun.prototype.GetAllFields = function(isUseSelection, arrFields)
|
||
{
|
||
var nStartPos = isUseSelection ?
|
||
(this.Selection.StartPos < this.Selection.EndPos ? this.Selection.StartPos : this.Selection.EndPos)
|
||
: 0;
|
||
|
||
var nEndPos = isUseSelection ?
|
||
(this.Selection.StartPos < this.Selection.EndPos ? this.Selection.EndPos : this.Selection.StartPos)
|
||
: this.Content.length;
|
||
|
||
for (var nPos = nStartPos; nPos < nEndPos; ++nPos)
|
||
{
|
||
var oItem = this.Content[nPos];
|
||
if (para_FieldChar === oItem.Type)
|
||
{
|
||
let complexField = oItem.GetComplexField();
|
||
if (complexField
|
||
&& complexField.IsValid()
|
||
&& -1 === arrFields.indexOf(complexField))
|
||
{
|
||
arrFields.push(complexField);
|
||
}
|
||
}
|
||
else if (para_Drawing === oItem.Type)
|
||
{
|
||
oItem.GetAllFields(false, arrFields);
|
||
}
|
||
else if (para_FootnoteReference === oItem.Type || para_EndnoteReference === oItem.Type)
|
||
{
|
||
oItem.GetFootnote().GetAllFields(false, arrFields);
|
||
}
|
||
}
|
||
};
|
||
|
||
ParaRun.prototype.GetAllSeqFieldsByType = function(sType, aFields)
|
||
{
|
||
for (var nPos = 0; nPos < this.Content.length; ++nPos)
|
||
{
|
||
var oItem = this.Content[nPos];
|
||
if (para_FieldChar === oItem.Type)
|
||
{
|
||
let complexField = oItem.GetComplexField();
|
||
let instruction = complexField && complexField.IsValid() ? complexField.GetInstruction() : null;
|
||
if (instruction
|
||
&& instruction.Type === AscWord.fieldtype_SEQ
|
||
&& instruction.CheckId(sType)
|
||
&& -1 === aFields.indexOf(complexField))
|
||
{
|
||
aFields.push(complexField);
|
||
}
|
||
}
|
||
else if (para_Field === oItem.Type
|
||
&& oItem.FieldType === AscWord.fieldtype_SEQ
|
||
&& oItem.Arguments[0] === sType)
|
||
{
|
||
aFields.push(oItem);
|
||
}
|
||
else if (para_Drawing === oItem.Type)
|
||
{
|
||
oItem.GetAllSeqFieldsByType(sType, aFields);
|
||
}
|
||
}
|
||
};
|
||
ParaRun.prototype.GetLastSEQPos = function(sType)
|
||
{
|
||
for (var nPos = this.Content.length - 1; nPos > -1; --nPos)
|
||
{
|
||
var oItem = this.Content[nPos];
|
||
if (para_FieldChar === oItem.Type)
|
||
{
|
||
var oComplexField = oItem.GetComplexField();
|
||
if(oComplexField)
|
||
{
|
||
var oInstruction = oComplexField.Instruction;
|
||
if(oInstruction)
|
||
{
|
||
if(oInstruction.Type === AscWord.fieldtype_SEQ)
|
||
{
|
||
if(oInstruction.Id === sType)
|
||
{
|
||
return this.GetParagraphContentPosFromObject(nPos + 1);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else if(para_Field === oItem.Type)
|
||
{
|
||
if(oItem.FieldType === AscWord.fieldtype_SEQ)
|
||
{
|
||
if(oItem.Arguments[0] === sType)
|
||
{
|
||
return this.GetParagraphContentPosFromObject(nPos + 1);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return null;
|
||
};
|
||
ParaRun.prototype.FindNoSpaceElement = function(nStart)
|
||
{
|
||
for(var nIndex = nStart; nIndex < this.Content.length; ++nIndex)
|
||
{
|
||
var oElement = this.Content[nIndex];
|
||
if(oElement.Type === para_Space ||
|
||
oElement.Type === para_Tab ||
|
||
oElement.Type === para_NewLine)
|
||
{
|
||
continue;
|
||
}
|
||
else
|
||
{
|
||
return nIndex;
|
||
}
|
||
}
|
||
return -1;
|
||
};
|
||
ParaRun.prototype.AddToContent = function(nPos, oItem, isUpdatePositions)
|
||
{
|
||
return this.Add_ToContent(nPos, oItem, isUpdatePositions);
|
||
};
|
||
ParaRun.prototype.AddToContentToEnd = function(oItem, isUpdatePositions)
|
||
{
|
||
return this.Add_ToContent(this.GetElementsCount(), oItem, isUpdatePositions);
|
||
};
|
||
ParaRun.prototype.RemoveFromContent = function(nPos, nCount, isUpdatePositions)
|
||
{
|
||
return this.Remove_FromContent(nPos, nCount, isUpdatePositions);
|
||
};
|
||
ParaRun.prototype.GetComplexField = function(nType)
|
||
{
|
||
for (var nPos = 0, nCount = this.Content.length; nPos < nCount; ++nPos)
|
||
{
|
||
var oItem = this.Content[nPos];
|
||
|
||
if (para_FieldChar === oItem.Type && oItem.IsBegin())
|
||
{
|
||
var oComplexField = oItem.GetComplexField();
|
||
if (!oComplexField)
|
||
continue;
|
||
|
||
var oInstruction = oComplexField.GetInstruction();
|
||
if (!oInstruction)
|
||
continue;
|
||
|
||
if (nType === oInstruction.GetType())
|
||
return oComplexField;
|
||
}
|
||
}
|
||
return null;
|
||
};
|
||
ParaRun.prototype.GetComplexFieldsArray = function(nType, arrComplexFields)
|
||
{
|
||
for (var nPos = 0, nCount = this.Content.length; nPos < nCount; ++nPos)
|
||
{
|
||
var oItem = this.Content[nPos];
|
||
|
||
if (para_FieldChar === oItem.Type && oItem.IsBegin())
|
||
{
|
||
var oComplexField = oItem.GetComplexField();
|
||
if (!oComplexField)
|
||
continue;
|
||
|
||
var oInstruction = oComplexField.GetInstruction();
|
||
if (!oInstruction)
|
||
continue;
|
||
|
||
if (nType === oInstruction.GetType())
|
||
arrComplexFields.push(oComplexField);
|
||
}
|
||
}
|
||
};
|
||
/**
|
||
* Получаем количество элементов в ране
|
||
* @returns {Number}
|
||
*/
|
||
ParaRun.prototype.GetElementsCount = function()
|
||
{
|
||
return this.Content.length;
|
||
};
|
||
/**
|
||
* Получаем элемент по заданной позиции
|
||
* @param nPos {number}
|
||
* @returns {?AscWord.CRunElementBase}
|
||
*/
|
||
ParaRun.prototype.GetElement = function(nPos)
|
||
{
|
||
if (nPos < 0 || nPos >= this.Content.length)
|
||
return null;
|
||
|
||
return this.Content[nPos];
|
||
};
|
||
/**
|
||
* Проверяем является ли данный ран специальным, содержащим ссылку на сноску
|
||
* @returns {boolean}
|
||
*/
|
||
ParaRun.prototype.IsFootEndnoteReferenceRun = function()
|
||
{
|
||
return (1 === this.Content.length && (para_FootnoteReference === this.Content[0].Type || para_EndnoteReference == this.Content[0].Type));
|
||
};
|
||
/**
|
||
* Производим автозамену
|
||
* @param {number} nPos - позиция, на которой был добавлен последний элемент, с которого стартовала автозамена
|
||
* @param {number} nFlags - флаги, какие автозамены мы пробуем делать
|
||
* @param {number} [nHistoryActions=1] Автозамене предществовало заданное количество точек в истории
|
||
* @returns {number} Возвращаются флаги, произведенных автозамен
|
||
*/
|
||
ParaRun.prototype.ProcessAutoCorrect = function(nPos, nFlags, nHistoryActions)
|
||
{
|
||
return (new AscWord.CRunAutoCorrect(this, nPos).DoAutoCorrect(nFlags, nHistoryActions));
|
||
};
|
||
/**
|
||
* Выполняем автозамену в конце параграфа
|
||
* @param {number} [nHistoryActions=1] Автозамене предществовало заданное количество точек в истории
|
||
*/
|
||
ParaRun.prototype.ProcessAutoCorrectOnParaEnd = function(nHistoryActions)
|
||
{
|
||
var oParaEnd = this.GetParaEnd();
|
||
if (!oParaEnd)
|
||
return;
|
||
|
||
this.ProcessAutoCorrect(0, oParaEnd.GetAutoCorrectFlags(), nHistoryActions);
|
||
};
|
||
ParaRun.prototype.CollectTextToUnicode = function(ListForUnicode, oSettings)
|
||
{
|
||
if (!this.Selection.Use)
|
||
return;
|
||
|
||
if (oSettings.nDirection === 1)
|
||
oSettings.textForUnicode += this.GetSelectedText(false);
|
||
else
|
||
oSettings.textForUnicode = this.GetSelectedText(false) + oSettings.textForUnicode;
|
||
|
||
let startPos = this.Selection.StartPos;
|
||
let endPos = this.Selection.EndPos;
|
||
|
||
function HandleItem(run, pos)
|
||
{
|
||
let item = run.Content[pos];
|
||
if (para_Text === item.Type
|
||
|| para_Space === item.Type
|
||
|| para_Math_Text === item.Type
|
||
|| para_Math_BreakOperator === item.Type)
|
||
{
|
||
ListForUnicode[oSettings.fFlagForUnicode++] = {
|
||
oRun: run,
|
||
currentPos: pos,
|
||
value: item.GetCodePoint()
|
||
};
|
||
|
||
if (para_Math_Text === item.Type || para_Math_BreakOperator === item.Type)
|
||
oSettings.IsForMathPart = -1;
|
||
}
|
||
else
|
||
{
|
||
if (!item.IsParaEnd())
|
||
oSettings.bBreak = true;
|
||
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
}
|
||
|
||
if (startPos > endPos)
|
||
{
|
||
oSettings.nDirection = -1;
|
||
for (let pos = startPos - 1; pos >= endPos; --pos)
|
||
{
|
||
if (HandleItem(this, pos))
|
||
break;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
oSettings.nDirection = 1;
|
||
for (let pos = startPos; pos < endPos; ++pos)
|
||
{
|
||
if (HandleItem(this, pos))
|
||
break;
|
||
}
|
||
}
|
||
};
|
||
ParaRun.prototype.SetMathMetaData = function(oMathMetaData)
|
||
{
|
||
if (!oMathMetaData)
|
||
return;
|
||
|
||
if (this.math_autocorrection)
|
||
{
|
||
let oOldMetaData = oMathMetaData.Copy();
|
||
this.math_autocorrection.Set(oMathMetaData);
|
||
AscCommon.History.Add(new CChangesRunMathMetaData(this, oOldMetaData, this.math_autocorrection));
|
||
}
|
||
else
|
||
{
|
||
this.math_autocorrection = oMathMetaData.Copy();
|
||
AscCommon.History.Add(new CChangesRunMathMetaData(this, false, this.math_autocorrection));
|
||
}
|
||
};
|
||
ParaRun.prototype.UpdateBookmarks = function(oManager)
|
||
{
|
||
for (var nIndex = 0, nCount = this.Content.length; nIndex < nCount; ++nIndex)
|
||
{
|
||
if (para_Drawing === this.Content[nIndex].Type)
|
||
this.Content[nIndex].UpdateBookmarks(oManager);
|
||
}
|
||
};
|
||
ParaRun.prototype.CheckRunContent = function(fCheck, oStartPos, oEndPos, nDepth, oCurrentPos, isForward)
|
||
{
|
||
let nStartPos = oStartPos && oStartPos.GetDepth() >= nDepth ? oStartPos.Get(nDepth) : 0;
|
||
let nEndPos = oEndPos && oEndPos.GetDepth() >= nDepth ? oEndPos.Get(nDepth) : this.Content.length;
|
||
|
||
return fCheck(this, nStartPos, nEndPos, oCurrentPos);
|
||
};
|
||
ParaRun.prototype.ProcessComplexFields = function(oComplexFields)
|
||
{
|
||
var isRemovedInReview = (reviewtype_Remove === this.GetReviewType());
|
||
|
||
for (var nPos = 0, nCount = this.Content.length; nPos < nCount; ++nPos)
|
||
{
|
||
var oItem = this.private_CheckInstrText(this.Content[nPos]);
|
||
var nItemType = oItem.Type;
|
||
|
||
if (oComplexFields.isHiddenFieldContent() && para_End !== nItemType && para_FieldChar !== nItemType)
|
||
continue;
|
||
|
||
if (para_FieldChar === nItemType)
|
||
oComplexFields.processFieldCharAndCollectComplexField(oItem);
|
||
else if (para_InstrText === nItemType && !isRemovedInReview)
|
||
oComplexFields.processInstruction(oItem);
|
||
}
|
||
};
|
||
ParaRun.prototype.GetSelectedElementsInfo = function(oInfo)
|
||
{
|
||
if (oInfo && oInfo.IsCheckAllSelection() && !this.IsSelectionEmpty(true))
|
||
{
|
||
oInfo.RegisterReviewType(this.GetReviewType());
|
||
|
||
var oElement;
|
||
for (var nPos = 0, nCount = this.Content.length; nPos < nCount; ++nPos)
|
||
{
|
||
oElement = this.Content[nPos];
|
||
if (para_RevisionMove === oElement.Type)
|
||
{
|
||
oInfo.RegisterTrackMoveMark(oElement.Type);
|
||
}
|
||
else if(para_FootnoteReference === oElement.Type || para_EndnoteReference === oElement.Type)
|
||
{
|
||
oInfo.RegisterFootEndNoteRef(oElement);
|
||
}
|
||
}
|
||
}
|
||
};
|
||
ParaRun.prototype.GetLastTrackMoveMark = function()
|
||
{
|
||
for (var nPos = this.Content.length - 1; nPos >= 0; --nPos)
|
||
{
|
||
if (para_RevisionMove === this.Content[nPos].Type)
|
||
return this.Content[nPos];
|
||
}
|
||
|
||
return null;
|
||
};
|
||
/**
|
||
* Можно ли удалять данный ран во время рецензирования
|
||
* @returns {boolean}
|
||
*/
|
||
ParaRun.prototype.CanDeleteInReviewMode = function()
|
||
{
|
||
var nReviewType = this.GetReviewType();
|
||
var oReviewInfo = this.GetReviewInfo();
|
||
|
||
return ((reviewtype_Add === nReviewType && oReviewInfo.IsCurrentUser() && (!oReviewInfo.IsMovedTo() || this.Paragraph.LogicDocument.TrackMoveRelocation)) || (reviewtype_Remove === nReviewType && oReviewInfo.IsPrevAddedByCurrentUser()));
|
||
};
|
||
/**
|
||
* Данная функция используется в иерархии классов для поиска первого рана
|
||
* @returns {ParaRun}
|
||
*/
|
||
ParaRun.prototype.GetFirstRun = function()
|
||
{
|
||
return this;
|
||
};
|
||
ParaRun.prototype.GetFirstRunElementPos = function(nType, oStartPos, oEndPos, nDepth)
|
||
{
|
||
for (var nPos = 0, nCount = this.Content.length; nPos < nCount; ++nPos)
|
||
{
|
||
if (nType === this.Content[nPos].Type)
|
||
{
|
||
oStartPos.Update(nPos, nDepth);
|
||
oEndPos.Update(nPos + 1, nDepth);
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
};
|
||
ParaRun.prototype.GetTextForm = function()
|
||
{
|
||
var oTextFormPr = this.Parent instanceof CInlineLevelSdt && this.Parent.IsTextForm() ? this.Parent.GetTextFormPr() : null;
|
||
if (!oTextFormPr)
|
||
return null;
|
||
|
||
return oTextFormPr;
|
||
};
|
||
ParaRun.prototype.GetFormPDF = function()
|
||
{
|
||
let oPara = this.GetParagraph();
|
||
let oParaParent = oPara.GetParent();
|
||
if (oParaParent && oParaParent.ParentPDF)
|
||
return oParaParent.ParentPDF;
|
||
|
||
return null;
|
||
};
|
||
ParaRun.prototype.IsInCheckBox = function()
|
||
{
|
||
var arrParentCC = this.GetParentContentControls();
|
||
for (var nIndex = 0, nCount = arrParentCC.length; nIndex < nCount; ++nIndex)
|
||
{
|
||
if (arrParentCC[nIndex].IsCheckBox())
|
||
return true;
|
||
}
|
||
|
||
return false;
|
||
};
|
||
ParaRun.prototype.GetTextFormAutoWidth = function()
|
||
{
|
||
this.Recalculate_MeasureContent();
|
||
let metrics = this.getTextMetrics();
|
||
return metrics.Ascent + metrics.LineGap;
|
||
};
|
||
ParaRun.prototype.CheckParentFormKey = function()
|
||
{
|
||
let oForm = this.GetParentForm();
|
||
let oLogicDocument = this.GetLogicDocument();
|
||
if (oForm && oLogicDocument && oLogicDocument.IsDocumentEditor())
|
||
oLogicDocument.OnChangeForm(oForm);
|
||
};
|
||
ParaRun.prototype.GetParentForm = function()
|
||
{
|
||
return (this.Parent instanceof CInlineLevelSdt && this.Parent.IsForm() ? this.Parent : null);
|
||
};
|
||
ParaRun.prototype.GetParentPictureContentControl = function()
|
||
{
|
||
var arrParentCC = this.GetParentContentControls();
|
||
for (var nIndex = 0, nCount = arrParentCC.length; nIndex < nCount; ++nIndex)
|
||
{
|
||
if (arrParentCC[nIndex].IsPicture())
|
||
return arrParentCC[nIndex];
|
||
}
|
||
|
||
return null;
|
||
};
|
||
ParaRun.prototype.CopyTextFormContent = function(oRun)
|
||
{
|
||
var nRunLen = oRun.Content.length;
|
||
|
||
var oTextForm = this.GetTextForm();
|
||
if (oTextForm && undefined !== oTextForm.GetMaxCharacters() && oTextForm.GetMaxCharacters() > 0)
|
||
nRunLen = Math.min(oTextForm.GetMaxCharacters(), nRunLen);
|
||
|
||
// Упрощенный вариант сравнения двух контентов. Сравниваем просто начало и конец
|
||
|
||
var nStart = 0;
|
||
var nEnd = 0;
|
||
|
||
var nCount = Math.min(this.Content.length, oRun.Content.length);
|
||
|
||
for (var nPos = 0; nPos < nCount; ++nPos)
|
||
{
|
||
if (this.Content[nPos].IsEqual(oRun.Content[nPos]))
|
||
nStart = nPos + 1;
|
||
else
|
||
break;
|
||
}
|
||
|
||
nCount -= nStart;
|
||
for (var nPos = 0; nPos < nCount; ++nPos)
|
||
{
|
||
if (this.Content[this.Content.length - 1 - nPos].IsEqual(oRun.Content[nRunLen - 1 - nPos]))
|
||
nEnd = nPos + 1;
|
||
else
|
||
break;
|
||
}
|
||
|
||
if (this.Content.length - nStart - nEnd > 0)
|
||
this.RemoveFromContent(nStart, this.Content.length - nStart - nEnd, true);
|
||
|
||
for (var nPos = nStart, nEndPos = nRunLen - nEnd; nPos < nEndPos; ++nPos)
|
||
{
|
||
this.AddToContent(nPos, oRun.Content[nPos].Copy(), true);
|
||
}
|
||
};
|
||
/**
|
||
* Изменяем содержимое и настройки рана при конвертации одного типа сносок в другие
|
||
* @param isToFootnote {boolean}
|
||
* @param oStyles {CStyles}
|
||
* @param oFootnote {CFootEndnote}
|
||
* @param oRef {AscWord.CRunFootnoteReference | AscWord.CRunEndnoteReference}
|
||
*/
|
||
ParaRun.prototype.ConvertFootnoteType = function(isToFootnote, oStyles, oFootnote, oRef)
|
||
{
|
||
let _t = this;
|
||
function replaceRef(pos, newRef)
|
||
{
|
||
AscCommon.executeNoPreDelete(function(){
|
||
_t.RemoveFromContent(pos, 1);
|
||
_t.AddToContent(pos, newRef);
|
||
}, _t.GetLogicDocument());
|
||
}
|
||
|
||
var sRStyle = this.GetRStyle();
|
||
if (isToFootnote)
|
||
{
|
||
if (sRStyle === oStyles.GetDefaultEndnoteTextChar())
|
||
this.SetRStyle(oStyles.GetDefaultFootnoteTextChar());
|
||
else if (sRStyle === oStyles.GetDefaultEndnoteReference())
|
||
this.SetRStyle(oStyles.GetDefaultFootnoteReference());
|
||
|
||
for (let nCurPos = 0, nCount = this.Content.length; nCurPos < nCount; ++nCurPos)
|
||
{
|
||
let oElement = this.Content[nCurPos];
|
||
if (!oRef || oRef === oElement)
|
||
{
|
||
if (para_EndnoteReference === oElement.Type)
|
||
replaceRef(nCurPos, new AscWord.CRunFootnoteReference(oFootnote, oElement.CustomMark));
|
||
else if (para_EndnoteRef === oElement.Type)
|
||
replaceRef(nCurPos, new AscWord.CRunFootnoteRef(oFootnote));
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (sRStyle === oStyles.GetDefaultFootnoteTextChar())
|
||
this.SetRStyle(oStyles.GetDefaultEndnoteTextChar());
|
||
else if (sRStyle === oStyles.GetDefaultFootnoteReference())
|
||
this.SetRStyle(oStyles.GetDefaultEndnoteReference());
|
||
|
||
for (let nCurPos = 0, nCount = this.Content.length; nCurPos < nCount; ++nCurPos)
|
||
{
|
||
let oElement = this.Content[nCurPos];
|
||
if (!oRef || oRef === oElement)
|
||
{
|
||
if (para_FootnoteReference === oElement.Type)
|
||
replaceRef(nCurPos, new AscWord.CRunEndnoteReference(oFootnote, oElement.CustomMark));
|
||
else if (para_FootnoteRef === oElement.Type)
|
||
replaceRef(nCurPos, new AscWord.CRunEndnoteRef(oFootnote));
|
||
}
|
||
}
|
||
}
|
||
};
|
||
ParaRun.prototype.FindNextFillingForm = function(isNext, isCurrent, isStart)
|
||
{
|
||
var nCurPos = this.Selection.Use === true ? this.Selection.EndPos : this.State.ContentPos;
|
||
|
||
var nStartPos = 0, nEndPos = 0;
|
||
if (isCurrent)
|
||
{
|
||
if (isStart)
|
||
{
|
||
nStartPos = nCurPos;
|
||
nEndPos = isNext ? this.Content.length : 0;
|
||
}
|
||
else
|
||
{
|
||
nStartPos = isNext ? 0 : this.Content.length;
|
||
nEndPos = nCurPos;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (isNext)
|
||
{
|
||
nStartPos = 0;
|
||
nEndPos = this.Content.length;
|
||
}
|
||
else
|
||
{
|
||
nStartPos = this.Content.length;
|
||
nEndPos = 0;
|
||
}
|
||
}
|
||
|
||
if (isNext)
|
||
{
|
||
for (var nIndex = nStartPos; nIndex < nEndPos; ++nIndex)
|
||
{
|
||
if (this.Content[nIndex].FindNextFillingForm)
|
||
{
|
||
var oRes = this.Content[nIndex].FindNextFillingForm(true, false, false);
|
||
if (oRes)
|
||
return oRes;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
for (var nIndex = nStartPos - 1; nIndex >= nEndPos; --nIndex)
|
||
{
|
||
if (this.Content[nIndex].FindNextFillingForm)
|
||
{
|
||
var oRes = this.Content[nIndex].FindNextFillingForm(false, false, false);
|
||
if (oRes)
|
||
return oRes;
|
||
}
|
||
}
|
||
}
|
||
|
||
return null;
|
||
};
|
||
ParaRun.prototype.CalculateTextToTable = function(oEngine)
|
||
{
|
||
if (reviewtype_Remove === this.GetReviewType())
|
||
return;
|
||
|
||
// В формулах делим только по ранам, находящимся в самом верху стэка формулы
|
||
if (this.IsMathRun() && (!this.ParaMath || this.Parent !== this.ParaMath.Root))
|
||
return;
|
||
|
||
if (oEngine.IsCalculateTableSizeMode())
|
||
{
|
||
for (var nPos = 0, nCount = this.Content.length; nPos < nCount; ++nPos)
|
||
{
|
||
if (oEngine.CheckSeparator(this.Content[nPos]))
|
||
{
|
||
oEngine.AddItem();
|
||
}
|
||
}
|
||
}
|
||
else if (oEngine.IsCheckSeparatorMode())
|
||
{
|
||
for (var nPos = 0, nCount = this.Content.length; nPos < nCount; ++nPos)
|
||
{
|
||
var oItem = this.Content[nPos];
|
||
var nItemType = oItem.Type;
|
||
|
||
if (para_Tab === nItemType)
|
||
oEngine.AddTab();
|
||
else if ((para_Text === nItemType && 0x3B === oItem.Value) || (para_Math_Text === nItemType && 0x3B === oItem.value))
|
||
oEngine.AddSemicolon();
|
||
}
|
||
}
|
||
else if (oEngine.IsConvertMode())
|
||
{
|
||
var oRunPos = null, oParagraph = null;
|
||
for (var nPos = 0, nCount = this.Content.length; nPos < nCount; ++nPos)
|
||
{
|
||
if (oEngine.CheckSeparator(this.Content[nPos]))
|
||
{
|
||
if (!oRunPos)
|
||
{
|
||
oParagraph = this.GetParagraph();
|
||
if (!oParagraph)
|
||
return;
|
||
|
||
oRunPos = oParagraph.GetPosByElement(this);
|
||
if (!oRunPos)
|
||
return;
|
||
}
|
||
|
||
var oContentPos = oRunPos.Copy();
|
||
oContentPos.Add(nPos);
|
||
oEngine.AddParaPosition(oContentPos);
|
||
}
|
||
}
|
||
}
|
||
};
|
||
ParaRun.prototype.IsUseAscFont = function(oTextPr)
|
||
{
|
||
return (1 === this.Content.length
|
||
&& para_Text === this.Content[0].Type
|
||
&& this.IsInCheckBox()
|
||
&& AscCommon.IsAscFontSupport(oTextPr.RFonts.Ascii.Name, this.Content[0].Value));
|
||
};
|
||
/**
|
||
* Получаем предыдущий элемент, с учетом предыдущих классов внутри параграфа
|
||
* @param nPos {number} позиция внутри данного рана
|
||
* @returns {?AscWord.CRunElementBase}
|
||
*/
|
||
ParaRun.prototype.GetPrevRunElement = function(nPos)
|
||
{
|
||
if (nPos > 0)
|
||
return this.Content[nPos - 1];
|
||
|
||
var oParagraph = this.GetParagraph();
|
||
if (!oParagraph)
|
||
return null;
|
||
|
||
var oContentPos = this.GetParagraphContentPosFromObject(0);
|
||
var oRunElements = new CParagraphRunElements(oContentPos, 1, null, true);
|
||
oParagraph.GetPrevRunElements(oRunElements);
|
||
|
||
if (oRunElements.Elements.length <= 0)
|
||
return null;
|
||
|
||
return oRunElements.Elements[0];
|
||
};
|
||
/**
|
||
* Получаем следующий элемент, с учетом следующих классов внутри параграфа
|
||
* @param nPos {number} позиция внутри данного рана
|
||
* @returns {?AscWord.CRunElementBase}
|
||
*/
|
||
ParaRun.prototype.GetNextRunElement = function(nPos)
|
||
{
|
||
if (nPos <= this.Content.length - 1 && nPos >= 0)
|
||
return this.Content[nPos];
|
||
|
||
var oParagraph = this.GetParagraph();
|
||
if (!oParagraph)
|
||
return null;
|
||
|
||
var oContentPos = this.GetParagraphContentPosFromObject(this.Content.length);
|
||
var oRunElements = new CParagraphRunElements(oContentPos, 1, null, true);
|
||
oParagraph.GetNextRunElements(oRunElements);
|
||
|
||
if (oRunElements.Elements.length <= 0)
|
||
return null;
|
||
|
||
return oRunElements.Elements[0];
|
||
};
|
||
/**
|
||
* Получаем позицию следующего элемента внутри параграфа
|
||
* @param nPos {number} позиция внутри данного рана
|
||
* @returns {?{Element : AscWord.CRunElementBase, Pos : AscWord.CParagraphContentPos}}
|
||
*/
|
||
ParaRun.prototype.GetNextRunElementEx = function(nPos)
|
||
{
|
||
let oParagraph = this.GetParagraph();
|
||
if (!oParagraph)
|
||
return null;
|
||
|
||
if (nPos <= this.Content.length - 1 && nPos >= 0)
|
||
{
|
||
let oContentPos = this.GetParagraphContentPosFromObject(nPos);
|
||
if (!oContentPos)
|
||
return null;
|
||
|
||
return {
|
||
Element : this.Content[nPos],
|
||
Pos : oContentPos
|
||
}
|
||
}
|
||
|
||
let oContentPos = this.GetParagraphContentPosFromObject(this.Content.length);
|
||
let oRunElements = new CParagraphRunElements(oContentPos, 1, null, true);
|
||
oRunElements.SkipMath = false;
|
||
oRunElements.SetSaveContentPositions(true);
|
||
oParagraph.GetNextRunElements(oRunElements);
|
||
|
||
let arrPositions = oRunElements.GetContentPositions();
|
||
let arrElements = oRunElements.GetElements();
|
||
|
||
if (1 !== arrPositions.length || 1 !== arrElements.length)
|
||
return null;
|
||
|
||
return {
|
||
Element : arrElements[0],
|
||
Pos : arrPositions[0]
|
||
}
|
||
};
|
||
//----------------------------------------------------------------------------------------------------------------------
|
||
// SpellCheck
|
||
//----------------------------------------------------------------------------------------------------------------------
|
||
ParaRun.prototype.RestartSpellCheck = function()
|
||
{
|
||
this.Recalc_CompiledPr(false);
|
||
|
||
for (let nIndex = 0, nCount = this.Content.length; nIndex < nCount; nIndex++)
|
||
{
|
||
let oItem = this.Content[nIndex];
|
||
if (oItem.IsDrawing())
|
||
oItem.RestartSpellCheck();
|
||
}
|
||
};
|
||
ParaRun.prototype.CheckSpelling = function(oCollector, nDepth)
|
||
{
|
||
if (oCollector.IsExceedLimit())
|
||
return;
|
||
|
||
if (reviewtype_Remove === this.GetReviewType())
|
||
{
|
||
oCollector.FlushWord();
|
||
return;
|
||
}
|
||
|
||
let nStartPos = 0;
|
||
let oCurTextPr = this.Get_CompiledPr(false);
|
||
if (oCollector.IsFindStart())
|
||
{
|
||
nStartPos = oCollector.GetPos(nDepth);
|
||
oCollector.SetFindStart(false);
|
||
}
|
||
else
|
||
{
|
||
this.SpellingMarks = [];
|
||
|
||
if (true === this.IsEmpty())
|
||
return;
|
||
|
||
oCollector.HandleLang(oCurTextPr.Lang);
|
||
}
|
||
|
||
for (let nPos = nStartPos, nContentLen = this.Content.length; nPos < nContentLen; ++nPos)
|
||
{
|
||
oCollector.UpdatePos(nPos, nDepth);
|
||
oCollector.HandleRunElement(this.Content[nPos], oCurTextPr, this, nPos);
|
||
|
||
if (oCollector.IsExceedLimit())
|
||
break;
|
||
}
|
||
};
|
||
ParaRun.prototype.AddSpellCheckerElement = function(spellMark)
|
||
{
|
||
this.SpellingMarks.push(spellMark);
|
||
};
|
||
ParaRun.prototype.RemoveSpellCheckerElement = function(element)
|
||
{
|
||
for (let iMark = this.SpellingMarks.length - 1; iMark >= 0; --iMark)
|
||
{
|
||
if (this.SpellingMarks[iMark].getElement() === element)
|
||
this.SpellingMarks.splice(iMark, 1);
|
||
}
|
||
};
|
||
ParaRun.prototype.ClearSpellingMarks = function()
|
||
{
|
||
this.SpellingMarks = [];
|
||
};
|
||
ParaRun.prototype.GetSelectedDrawingObjectsInText = function(arrDrawings)
|
||
{
|
||
if (!this.IsSelectionUse())
|
||
return;
|
||
|
||
let nStartPos = this.Selection.StartPos;
|
||
let nEndPos = this.Selection.EndPos;
|
||
if (nStartPos > nEndPos)
|
||
{
|
||
let nTemp = nStartPos;
|
||
nStartPos = nEndPos;
|
||
nEndPos = nTemp;
|
||
}
|
||
|
||
for (let nPos = nStartPos; nPos < nEndPos; ++nPos)
|
||
{
|
||
let oItem = this.Content[nPos];
|
||
if (oItem.IsDrawing())
|
||
arrDrawings.push(oItem);
|
||
}
|
||
|
||
return arrDrawings;
|
||
};
|
||
//----------------------------------------------------------------------------------------------------------------------
|
||
// Search
|
||
//----------------------------------------------------------------------------------------------------------------------
|
||
ParaRun.prototype.Search = function(ParaSearch)
|
||
{
|
||
this.SearchMarks = [];
|
||
|
||
var Para = ParaSearch.Paragraph;
|
||
var SearchEngine = ParaSearch.SearchEngine;
|
||
var Type = ParaSearch.Type;
|
||
let isWholeWords = SearchEngine.IsWholeWords();
|
||
|
||
for (var nPos = 0, nContentLen = this.Content.length; nPos < nContentLen; ++nPos)
|
||
{
|
||
var oItem = this.Content[nPos];
|
||
if (para_Drawing === oItem.Type)
|
||
oItem.Search(SearchEngine, Type);
|
||
|
||
while (ParaSearch.SearchIndex > 0 && !ParaSearch.Check(ParaSearch.SearchIndex, oItem))
|
||
{
|
||
if (isWholeWords)
|
||
{
|
||
ParaSearch.Reset();
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
|
||
ParaSearch.SearchIndex = ParaSearch.GetPrefix(ParaSearch.SearchIndex - 1);
|
||
if (0 === ParaSearch.SearchIndex)
|
||
{
|
||
ParaSearch.Reset();
|
||
break;
|
||
}
|
||
else if (ParaSearch.Check(ParaSearch.SearchIndex, oItem))
|
||
{
|
||
ParaSearch.StartPos = ParaSearch.StartPosBuf.shift();
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (ParaSearch.Check(ParaSearch.SearchIndex, oItem))
|
||
{
|
||
if (0 === ParaSearch.SearchIndex)
|
||
{
|
||
if (isWholeWords)
|
||
{
|
||
var oPrevElement = this.GetPrevRunElement(nPos);
|
||
if (!oPrevElement || (!oPrevElement.IsLetter() && !oPrevElement.IsDigit()))
|
||
ParaSearch.StartPos = {Run : this, Pos : nPos};
|
||
}
|
||
else
|
||
{
|
||
ParaSearch.StartPos = {Run : this, Pos : nPos};
|
||
}
|
||
}
|
||
|
||
if (0 !== ParaSearch.GetPrefix(ParaSearch.SearchIndex))
|
||
ParaSearch.StartPosBuf.push({Run : this, Pos : nPos});
|
||
|
||
ParaSearch.SearchIndex++;
|
||
|
||
if (ParaSearch.CheckSearchEnd())
|
||
{
|
||
if (ParaSearch.StartPos)
|
||
{
|
||
var isAdd = false;
|
||
if (isWholeWords)
|
||
{
|
||
var oNextElement = this.GetNextRunElement(nPos + 1);
|
||
if (!oNextElement || (!oNextElement.IsLetter() && !oNextElement.IsDigit()))
|
||
isAdd = true;
|
||
}
|
||
else
|
||
{
|
||
isAdd = true;
|
||
}
|
||
|
||
if (isAdd)
|
||
{
|
||
Para.AddSearchResult(
|
||
SearchEngine.Add(Para),
|
||
ParaSearch.StartPos.Run.GetParagraphContentPosFromObject(ParaSearch.StartPos.Pos),
|
||
this.GetParagraphContentPosFromObject(nPos + 1),
|
||
Type
|
||
);
|
||
}
|
||
}
|
||
|
||
ParaSearch.Reset();
|
||
}
|
||
}
|
||
}
|
||
};
|
||
ParaRun.prototype.AddSearchResult = function(oSearchResult, isStart, oContentPos, nDepth)
|
||
{
|
||
oSearchResult.RegisterClass(isStart, this);
|
||
this.SearchMarks.push(new AscCommonWord.CParagraphSearchMark(oSearchResult, isStart, nDepth));
|
||
};
|
||
ParaRun.prototype.ClearSearchResults = function()
|
||
{
|
||
this.SearchMarks = [];
|
||
};
|
||
ParaRun.prototype.RemoveSearchResult = function(oSearchResult)
|
||
{
|
||
for (var nIndex = 0, nMarksCount = this.SearchMarks.length; nIndex < nMarksCount; ++nIndex)
|
||
{
|
||
var oMark = this.SearchMarks[nIndex];
|
||
if (oSearchResult === oMark.SearchResult)
|
||
{
|
||
this.SearchMarks.splice(nIndex, 1);
|
||
nIndex--;
|
||
nMarksCount--;
|
||
}
|
||
}
|
||
};
|
||
ParaRun.prototype.GetSearchElementId = function(bNext, bUseContentPos, ContentPos, Depth)
|
||
{
|
||
var StartPos = 0;
|
||
|
||
if ( true === bUseContentPos )
|
||
{
|
||
StartPos = ContentPos.Get( Depth );
|
||
}
|
||
else
|
||
{
|
||
if ( true === bNext )
|
||
{
|
||
StartPos = 0;
|
||
}
|
||
else
|
||
{
|
||
StartPos = this.Content.length;
|
||
}
|
||
}
|
||
|
||
var NearElementId = null;
|
||
|
||
if ( true === bNext )
|
||
{
|
||
var NearPos = this.Content.length;
|
||
|
||
var SearchMarksCount = this.SearchMarks.length;
|
||
for ( var SPos = 0; SPos < SearchMarksCount; SPos++)
|
||
{
|
||
var Mark = this.SearchMarks[SPos];
|
||
var MarkPos = Mark.SearchResult.StartPos.Get(Mark.Depth);
|
||
|
||
if (Mark.SearchResult.ClassesS.length > 0 && this === Mark.SearchResult.ClassesS[Mark.SearchResult.ClassesS.length - 1] && MarkPos >= StartPos && MarkPos < NearPos)
|
||
{
|
||
NearElementId = Mark.SearchResult.Id;
|
||
NearPos = MarkPos;
|
||
}
|
||
}
|
||
|
||
for ( var CurPos = StartPos; CurPos < NearPos; CurPos++ )
|
||
{
|
||
var Item = this.Content[CurPos];
|
||
if ( para_Drawing === Item.Type )
|
||
{
|
||
var TempElementId = Item.GetSearchElementId( true, false );
|
||
if ( null != TempElementId )
|
||
return TempElementId;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
var NearPos = -1;
|
||
|
||
var SearchMarksCount = this.SearchMarks.length;
|
||
for ( var SPos = 0; SPos < SearchMarksCount; SPos++)
|
||
{
|
||
var Mark = this.SearchMarks[SPos];
|
||
var MarkPos = Mark.SearchResult.StartPos.Get(Mark.Depth);
|
||
|
||
if (Mark.SearchResult.ClassesS.length > 0 && this === Mark.SearchResult.ClassesS[Mark.SearchResult.ClassesS.length - 1] && MarkPos < StartPos && MarkPos > NearPos)
|
||
{
|
||
NearElementId = Mark.SearchResult.Id;
|
||
NearPos = MarkPos;
|
||
}
|
||
}
|
||
|
||
StartPos = Math.min( this.Content.length - 1, StartPos - 1 );
|
||
for ( var CurPos = StartPos; CurPos > NearPos; CurPos-- )
|
||
{
|
||
var Item = this.Content[CurPos];
|
||
if ( para_Drawing === Item.Type )
|
||
{
|
||
var TempElementId = Item.GetSearchElementId( false, false );
|
||
if ( null != TempElementId )
|
||
return TempElementId;
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
return NearElementId;
|
||
};
|
||
//----------------------------------------------------------------------------------------------------------------------
|
||
ParaRun.prototype.GetFontSlotInRange = function(nStartPos, nEndPos)
|
||
{
|
||
if (nStartPos >= nEndPos
|
||
|| nStartPos >= this.Content.length
|
||
|| nEndPos <= 0
|
||
|| this.IsMathRun())
|
||
return AscWord.fontslot_None;
|
||
|
||
let oTextPr = this.Get_CompiledPr(false);
|
||
|
||
let nFontSlot = AscWord.fontslot_None;
|
||
for (let nPos = nStartPos; nPos < nEndPos; ++nPos)
|
||
{
|
||
let oItem = this.Content[nPos];
|
||
nFontSlot |= oItem.GetFontSlot(oTextPr)
|
||
}
|
||
|
||
if (AscWord.fontslot_Unknown === nFontSlot)
|
||
return AscWord.fontslot_Unknown;
|
||
|
||
if (oTextPr.RTL || oTextPr.CS)
|
||
return AscWord.fontslot_CS;
|
||
|
||
return nFontSlot;
|
||
};
|
||
ParaRun.prototype.GetDirectionFlagInRange = function(startPos, endPos)
|
||
{
|
||
if (startPos >= endPos
|
||
|| startPos >= this.Content.length
|
||
|| endPos <= 0
|
||
|| this.IsMathRun())
|
||
return AscBidi.DIRECTION_FLAG.None;
|
||
|
||
let dir = AscBidi.DIRECTION_FLAG.None;
|
||
for (let pos = startPos; pos < endPos; ++pos)
|
||
{
|
||
let item = this.Content[pos];
|
||
dir |= item.GetDirectionFlag();
|
||
}
|
||
|
||
return dir;
|
||
};
|
||
/**
|
||
* Get first find parent typeof CMathContent or MathBase
|
||
* @return {*}
|
||
*/
|
||
ParaRun.prototype.GetMathBaseFirst = function()
|
||
{
|
||
if (!this.IsMathRun())
|
||
return false;
|
||
|
||
return this.Parent.GetMathBaseFirst();
|
||
}
|
||
ParaRun.prototype.GetFontSlotByPosition = function(nPos)
|
||
{
|
||
if (nPos > this.Content.length
|
||
|| nPos < 0
|
||
|| this.Content.length <= 0)
|
||
return AscWord.fontslot_None;
|
||
|
||
let oTextPr = this.Get_CompiledPr(false);
|
||
if (oTextPr.RTL || oTextPr.CS)
|
||
return AscWord.fontslot_CS;
|
||
|
||
let oPrev, oNext;
|
||
if (nPos > 0)
|
||
oPrev = this.GetElement(nPos - 1);
|
||
if (nPos < this.Content.length)
|
||
oNext = this.GetElement(nPos);
|
||
|
||
let nFontSlot = AscWord.fontslot_None;
|
||
if (oPrev)
|
||
nFontSlot = oPrev.GetFontSlot(oTextPr);
|
||
else if (oNext)
|
||
nFontSlot = oNext.GetFontSlot(oTextPr);
|
||
|
||
return nFontSlot;
|
||
};
|
||
ParaRun.prototype.SetIsRecalculated = function(isRecalculated)
|
||
{
|
||
if (!isRecalculated && this.Paragraph)
|
||
this.Paragraph.SetIsRecalculated(false);
|
||
};
|
||
ParaRun.prototype.private_UpdateMarksOnAdd = function(pos, count)
|
||
{
|
||
if (AscCommon.CollaborativeEditing.IsSplitConcatRun())
|
||
return;
|
||
|
||
for (let iMark = 0, nMarks = this.SearchMarks.length; iMark < nMarks; ++iMark)
|
||
{
|
||
var Mark = this.SearchMarks[iMark];
|
||
var ContentPos = ( true === Mark.Start ? Mark.SearchResult.StartPos : Mark.SearchResult.EndPos );
|
||
var Depth = Mark.Depth;
|
||
|
||
if (ContentPos.Data[Depth] > pos || (ContentPos.Data[Depth] === pos && true === Mark.Start))
|
||
ContentPos.Data[Depth] += count;
|
||
}
|
||
|
||
for (let iMark = 0, nMarks = this.SpellingMarks.length; iMark < nMarks; ++iMark)
|
||
{
|
||
this.SpellingMarks[iMark].onAdd(pos, count);
|
||
}
|
||
|
||
this.private_UpdateCustomMarksOnAdd(pos, count);
|
||
};
|
||
ParaRun.prototype.private_UpdateMarksOnRemove = function(pos, count)
|
||
{
|
||
if (AscCommon.CollaborativeEditing.IsSplitConcatRun())
|
||
return;
|
||
|
||
for (let iMark = 0, nMarks = this.SearchMarks.length; iMark < nMarks; ++iMark)
|
||
{
|
||
var Mark = this.SearchMarks[iMark];
|
||
var ContentPos = (true === Mark.Start ? Mark.SearchResult.StartPos : Mark.SearchResult.EndPos);
|
||
var Depth = Mark.Depth;
|
||
|
||
if (ContentPos.Data[Depth] > pos + count)
|
||
ContentPos.Data[Depth] -= count;
|
||
else if (ContentPos.Data[Depth] > pos)
|
||
ContentPos.Data[Depth] = Math.max(0, pos);
|
||
}
|
||
|
||
for (let iMark = 0, nMarks = this.SpellingMarks.length; iMark < nMarks; ++iMark)
|
||
{
|
||
this.SpellingMarks[iMark].onRemove(pos, count);
|
||
}
|
||
this.private_UpdateCustomMarksOnRemove(pos, count);
|
||
};
|
||
ParaRun.prototype.private_UpdateMarksOnSplit = function(pos, nextRun)
|
||
{
|
||
if (!nextRun)
|
||
return;
|
||
|
||
for (let iMark = 0, nMarks = this.SpellingMarks.length; iMark < nMarks; ++iMark)
|
||
{
|
||
let mark = this.SpellingMarks[iMark];
|
||
if (mark.getPos() >= pos)
|
||
{
|
||
mark.movePos(-pos);
|
||
nextRun.SpellingMarks.push(mark);
|
||
this.SpellingMarks.splice(iMark, 1);
|
||
--nMarks;
|
||
--iMark;
|
||
}
|
||
}
|
||
this.private_UpdateCustomMarksOnSplit(pos, nextRun);
|
||
};
|
||
ParaRun.prototype.private_UpdateMarksOnConcat = function(pos, run)
|
||
{
|
||
if (!run)
|
||
return;
|
||
|
||
// Присылаем сюда позицию pos не потому что в любой позции соединяем, а чтобы данный вызов не контролировать
|
||
// относительно времени соединения ранов (т.е. на данный момент соединение уже может быть, а может и не быть)
|
||
// Мы, в любом случае считаем, что когда раны соединялись, то длина первого рана равнялась pos
|
||
for (let iMark = 0, nMarks = run.SpellingMarks.length; iMark < nMarks; ++iMark)
|
||
{
|
||
let mark = run.SpellingMarks[iMark];
|
||
mark.movePos(pos);
|
||
this.SpellingMarks.push(mark);
|
||
}
|
||
this.private_UpdateCustomMarksOnConcat(pos, run);
|
||
};
|
||
ParaRun.prototype.private_UpdateCustomMarksOnAdd = function(pos, count)
|
||
{
|
||
let logicDocument = this.GetLogicDocument();
|
||
let customMarks = logicDocument && logicDocument.IsDocumentEditor() ? logicDocument.GetCustomMarks() : null;
|
||
if (customMarks)
|
||
customMarks.onAddToRun(this.GetId(), pos, count);
|
||
};
|
||
ParaRun.prototype.private_UpdateCustomMarksOnRemove = function(pos, count)
|
||
{
|
||
let logicDocument = this.GetLogicDocument();
|
||
let customMarks = logicDocument && logicDocument.IsDocumentEditor() ? logicDocument.GetCustomMarks() : null;
|
||
if (customMarks)
|
||
customMarks.onRemoveFromRun(this.GetId(), pos, count);
|
||
};
|
||
ParaRun.prototype.private_UpdateCustomMarksOnSplit = function(pos, nextRun)
|
||
{
|
||
let logicDocument = this.GetLogicDocument();
|
||
let customMarks = logicDocument && logicDocument.IsDocumentEditor() ? logicDocument.GetCustomMarks() : null;
|
||
if (customMarks)
|
||
customMarks.onSplitRun(this.GetId(), pos, nextRun.GetId());
|
||
};
|
||
ParaRun.prototype.private_UpdateCustomMarksOnConcat = function(pos, run)
|
||
{
|
||
let logicDocument = this.GetLogicDocument();
|
||
let customMarks = logicDocument && logicDocument.IsDocumentEditor() ? logicDocument.GetCustomMarks() : null;
|
||
if (customMarks)
|
||
customMarks.onConcatRun(this.GetId(), pos, run.GetId());
|
||
};
|
||
|
||
function CParaRunStartState(Run)
|
||
{
|
||
this.Paragraph = Run.Paragraph;
|
||
this.Pr = Run.Pr.Copy();
|
||
this.Content = [];
|
||
for(var i = 0; i < Run.Content.length; ++i)
|
||
{
|
||
this.Content.push(Run.Content[i]);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @constructor
|
||
*/
|
||
function CRunWithPosition(oRun, nPos)
|
||
{
|
||
this.Run = oRun;
|
||
this.Pos = nPos;
|
||
}
|
||
CRunWithPosition.prototype.SetDocumentPositionHere = function()
|
||
{
|
||
this.Run.State.ContentPos = this.Pos;
|
||
this.Run.Make_ThisElementCurrent();
|
||
|
||
// Не корректируем позицию внутри параграфа в данной функции, либо надо переделывать удаление в обратном
|
||
// порядке в ране в случае рецензирования, т.к. в такой ситуации можно оставлять курсор между CombiningMarks,
|
||
// в то время как в обычной ситуации мы не даем туда поставить курсор
|
||
};
|
||
|
||
function CanUpdatePosition(Para, Run) {
|
||
return (Para && true === Para.IsUseInDocument() && true === Run.IsUseInParagraph());
|
||
}
|
||
|
||
//--------------------------------------------------------export----------------------------------------------------
|
||
window['AscCommonWord'] = window['AscCommonWord'] || {};
|
||
window['AscCommonWord'].ParaRun = ParaRun;
|
||
window['AscCommonWord'].CanUpdatePosition = CanUpdatePosition;
|
||
|
||
window['AscWord'] = window['AscWord'] || {};
|
||
window['AscWord'].ParaRun = ParaRun;
|
||
window['AscWord'].CRun = ParaRun;
|
||
window['AscWord'].Run = ParaRun;
|