772 lines
21 KiB
JavaScript
772 lines
21 KiB
JavaScript
/*
|
|
* (c) Copyright Ascensio System SIA 2010-2024
|
|
*
|
|
* This program is a free software product. You can redistribute it and/or
|
|
* modify it under the terms of the GNU Affero General Public License (AGPL)
|
|
* version 3 as published by the Free Software Foundation. In accordance with
|
|
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
|
|
* that Ascensio System SIA expressly excludes the warranty of non-infringement
|
|
* of any third-party rights.
|
|
*
|
|
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
|
|
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
|
|
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
|
|
*
|
|
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
|
|
* street, Riga, Latvia, EU, LV-1050.
|
|
*
|
|
* The interactive user interfaces in modified source and object code versions
|
|
* of the Program must display Appropriate Legal Notices, as required under
|
|
* Section 5 of the GNU AGPL version 3.
|
|
*
|
|
* Pursuant to Section 7(b) of the License you must retain the original Product
|
|
* logo when distributing the program. Pursuant to Section 7(e) we decline to
|
|
* grant you any rights under trademark law for use of our trademarks.
|
|
*
|
|
* All the Product's GUI elements, including illustrations and icon sets, as
|
|
* well as technical writing content are licensed under the terms of the
|
|
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
|
|
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
|
*
|
|
*/
|
|
|
|
"use strict";
|
|
|
|
(function(window)
|
|
{
|
|
const NumberingType = Asc.c_oAscJSONNumberingType;
|
|
|
|
/**
|
|
* Класс для применения нумерации к документу
|
|
* @param {AscWord.CDocument} document
|
|
* @constructor
|
|
*/
|
|
function CNumberingApplicator(document)
|
|
{
|
|
this.Document = document;
|
|
this.Numbering = document.GetNumbering();
|
|
|
|
this.NumPr = null;
|
|
this.Paragraphs = [];
|
|
this.NumInfo = new AscWord.CNumInfo();
|
|
|
|
this.LastBulleted = null;
|
|
this.LastNumbered = null;
|
|
}
|
|
|
|
/**
|
|
* Применяем нумерацию по заданному объекту
|
|
* @param numInfo {object}
|
|
*/
|
|
CNumberingApplicator.prototype.Apply = function(numInfo)
|
|
{
|
|
if (!this.Document || !numInfo)
|
|
return false;
|
|
|
|
this.NumInfo = numInfo;
|
|
this.NumPr = this.GetCurrentNumPr();
|
|
this.Paragraphs = this.GetParagraphs();
|
|
|
|
if (!this.Paragraphs.length)
|
|
return false;
|
|
|
|
let result = false;
|
|
if (this.IsRemoveNumbering())
|
|
result = this.RemoveNumbering();
|
|
else if (this.IsBulleted())
|
|
result = this.ApplyBulleted();
|
|
else if (this.IsNumbered())
|
|
result = this.ApplyNumbered();
|
|
else if (this.IsSingleLevel())
|
|
result = this.ApplySingleLevel();
|
|
else if (this.IsMultilevel())
|
|
result = this.ApplyMultilevel();
|
|
|
|
if (result)
|
|
this.UpdateDocumentOutline();
|
|
|
|
return result;
|
|
};
|
|
CNumberingApplicator.prototype.ResetLast = function()
|
|
{
|
|
this.SetLastNumbered(null);
|
|
this.SetLastBulleted(null);
|
|
};
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Private area
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
CNumberingApplicator.prototype.GetLastBulleted = function()
|
|
{
|
|
return this.LastBulleted;
|
|
};
|
|
CNumberingApplicator.prototype.SetLastBulleted = function(numId, ilvl)
|
|
{
|
|
if (!numId)
|
|
this.LastBulleted = null;
|
|
else
|
|
this.LastBulleted = new AscWord.NumPr(numId, ilvl);
|
|
};
|
|
CNumberingApplicator.prototype.GetLastNumbered = function()
|
|
{
|
|
return this.LastNumbered;
|
|
};
|
|
CNumberingApplicator.prototype.SetLastNumbered = function(numId, ilvl)
|
|
{
|
|
if (!numId)
|
|
this.LastNumbered = null;
|
|
else
|
|
this.LastNumbered = new AscWord.NumPr(numId, ilvl);
|
|
};
|
|
CNumberingApplicator.prototype.GetCurrentNumPr = function()
|
|
{
|
|
let document = this.Document;
|
|
|
|
let numPr = document.GetSelectedNum();
|
|
if (!numPr && !document.IsTextSelectionUse())
|
|
numPr = document.GetSelectedNum(true);
|
|
|
|
return numPr;
|
|
};
|
|
CNumberingApplicator.prototype.GetParagraphs = function()
|
|
{
|
|
let paragraphs = [];
|
|
if (this.NumPr)
|
|
paragraphs = this.Document.GetAllParagraphsByNumbering(this.NumPr);
|
|
else
|
|
paragraphs = this.Document.GetSelectedParagraphs();
|
|
|
|
return paragraphs;
|
|
};
|
|
CNumberingApplicator.prototype.IsRemoveNumbering = function()
|
|
{
|
|
return (NumberingType.Remove === this.NumInfo.Type);
|
|
};
|
|
CNumberingApplicator.prototype.IsBulleted = function()
|
|
{
|
|
return (NumberingType.Bullet === this.NumInfo.Type && 0 === this.NumInfo.Lvl.length);
|
|
};
|
|
CNumberingApplicator.prototype.IsNumbered = function()
|
|
{
|
|
return (NumberingType.Number === this.NumInfo.Type && 0 === this.NumInfo.Lvl.length);
|
|
};
|
|
CNumberingApplicator.prototype.IsSingleLevel = function()
|
|
{
|
|
return (NumberingType.Remove !== this.NumInfo.Type && 1 === this.NumInfo.Lvl.length);
|
|
};
|
|
CNumberingApplicator.prototype.IsMultilevel = function()
|
|
{
|
|
return (this.NumInfo.Lvl.length >= 8);
|
|
};
|
|
CNumberingApplicator.prototype.RemoveNumbering = function()
|
|
{
|
|
let document = this.Document;
|
|
if (document.IsNumberingSelection())
|
|
document.RemoveSelection();
|
|
|
|
for (let index = 0, count = this.Paragraphs.length; index < count; ++index)
|
|
{
|
|
this.Paragraphs[index].RemoveNumPr();
|
|
}
|
|
return true;
|
|
};
|
|
CNumberingApplicator.prototype.ApplyBulleted = function()
|
|
{
|
|
if (this.ApplyBulletedToCurrent())
|
|
return true;
|
|
|
|
// 1. Пытаемся присоединить список к списку предыдущего параграфа (если только он маркированный)
|
|
// 2. Пытаемся присоединить список к списку следующего параграфа (если он маркированный)
|
|
// 3. Пытаемся добавить список, который добавлялся предыдущий раз
|
|
// 4. Создаем новый маркированный список
|
|
|
|
let numberingManager = this.Document.GetNumbering();
|
|
|
|
let numId = null;
|
|
let ilvl = 0;
|
|
|
|
let prevNumPr = this.GetPrevNumPr();
|
|
if (prevNumPr && numberingManager.CheckFormat(prevNumPr.NumId, prevNumPr.Lvl, Asc.c_oAscNumberingFormat.Bullet))
|
|
{
|
|
numId = prevNumPr.NumId;
|
|
ilvl = prevNumPr.Lvl;
|
|
}
|
|
|
|
if (!numId)
|
|
{
|
|
let nextNumPr = this.GetNextNumPr();
|
|
if (nextNumPr && numberingManager.CheckFormat(nextNumPr.NumId, nextNumPr.Lvl, Asc.c_oAscNumberingFormat.Bullet))
|
|
{
|
|
numId = nextNumPr.NumId;
|
|
ilvl = nextNumPr.Lvl;
|
|
}
|
|
}
|
|
|
|
let isCheckPrev = false;
|
|
if (!numId)
|
|
{
|
|
let lastNumPr = this.GetLastBulleted();
|
|
let lastNum = lastNumPr ? this.Numbering.GetNum(lastNumPr.NumId) : null;
|
|
if (lastNum && lastNum.GetLvl(0).IsBulleted())
|
|
{
|
|
let newNum = this.Numbering.CreateNum();
|
|
newNum.CreateDefault(c_oAscMultiLevelNumbering.Bullet);
|
|
newNum.SetLvl(lastNum.GetLvl(lastNumPr.Lvl).Copy(), 0);
|
|
|
|
numId = newNum.GetId();
|
|
ilvl = 0;
|
|
|
|
isCheckPrev = true;
|
|
}
|
|
}
|
|
|
|
if (!numId)
|
|
{
|
|
let newNum = this.Numbering.CreateNum();
|
|
newNum.CreateDefault(c_oAscMultiLevelNumbering.Bullet);
|
|
|
|
numId = newNum.GetId();
|
|
ilvl = 0;
|
|
|
|
isCheckPrev = true;
|
|
}
|
|
|
|
if (isCheckPrev)
|
|
{
|
|
let result = this.CheckPrevNumPr(numId, ilvl);
|
|
if (result)
|
|
{
|
|
numId = result.NumId;
|
|
ilvl = result.Lvl;
|
|
}
|
|
}
|
|
|
|
this.MergeTextPrFromCommonNum(numId, ilvl);
|
|
this.SetLastBulleted(numId, ilvl);
|
|
this.ApplyNumPr(numId, ilvl);
|
|
return true;
|
|
};
|
|
CNumberingApplicator.prototype.ApplyBulletedToCurrent = function()
|
|
{
|
|
let numPr = this.NumPr;
|
|
if (!numPr)
|
|
return false;
|
|
|
|
let num = this.Numbering.GetNum(numPr.NumId);
|
|
if (!num)
|
|
return false;
|
|
|
|
let lvl;
|
|
|
|
let lastNumPr = this.GetLastBulleted();
|
|
let lastNum = lastNumPr ? this.Numbering.GetNum(lastNumPr.NumId) : null;
|
|
if (lastNum && lastNum.GetLvl(numPr.Lvl).IsBulleted())
|
|
{
|
|
lvl = lastNum.GetLvl(lastNumPr.Lvl).Copy();
|
|
}
|
|
else
|
|
{
|
|
lvl = num.GetLvl(numPr.Lvl).Copy();
|
|
|
|
let textPr = lvl.GetTextPr().Copy();
|
|
textPr.RFonts.SetAll("Symbol");
|
|
lvl.SetByType(c_oAscNumberingLevel.Bullet, numPr.Lvl, String.fromCharCode(0x00B7), textPr);
|
|
}
|
|
|
|
lvl.ParaPr = num.GetLvl(numPr.Lvl).ParaPr.Copy();
|
|
|
|
num.SetLvl(lvl, numPr.Lvl);
|
|
this.SetLastBulleted(numPr.NumId, numPr.Lvl);
|
|
return true;
|
|
};
|
|
CNumberingApplicator.prototype.ApplyNumbered = function()
|
|
{
|
|
if (this.ApplyNumberedToCurrent())
|
|
return true;
|
|
|
|
// 1. Пытаемся присоединить список к списку предыдущего параграфа (если он нумерованный)
|
|
// 2. Пытаемся присоединить список к списку следующего параграфа (если он нумерованный)
|
|
// 3. Пытаемся добавить список, который добавлялся предыдущий раз (добавляем его копию, и опционально продолжаем)
|
|
// 4. Создаем новый нумерованный список
|
|
|
|
let numberingManager = this.Document.GetNumbering();
|
|
|
|
let numId = null;
|
|
let ilvl = 0;
|
|
|
|
let prevNumPr = this.GetPrevNumPr();
|
|
if (prevNumPr && numberingManager.CheckFormat(prevNumPr.NumId, prevNumPr.Lvl, Asc.c_oAscNumberingFormat.Decimal))
|
|
{
|
|
numId = prevNumPr.NumId;
|
|
ilvl = undefined;
|
|
}
|
|
|
|
if (!numId)
|
|
{
|
|
let nextNumPr = this.GetNextNumPr();
|
|
if (nextNumPr && numberingManager.CheckFormat(nextNumPr.NumId, nextNumPr.Lvl, Asc.c_oAscNumberingFormat.Decimal))
|
|
{
|
|
numId = nextNumPr.NumId;
|
|
ilvl = undefined;
|
|
}
|
|
}
|
|
|
|
let isCheckPrev = false;
|
|
if (!numId)
|
|
{
|
|
let lastNumPr = this.GetLastNumbered();
|
|
let lastNum = lastNumPr ? this.Numbering.GetNum(lastNumPr.NumId) : null;
|
|
if (lastNum && lastNum.GetLvl(0).IsNumbered())
|
|
{
|
|
let newNum = this.Numbering.CreateNum();
|
|
|
|
if (lastNum.IsHaveRelatedLvlText())
|
|
{
|
|
for (let ilvlTemp = 0; ilvlTemp < 9; ++ilvlTemp)
|
|
{
|
|
newNum.SetLvl(lastNum.GetLvl(ilvlTemp).Copy(), ilvlTemp);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
newNum.CreateDefault(c_oAscMultiLevelNumbering.Numbered);
|
|
newNum.SetLvl(lastNum.GetLvl(lastNumPr.Lvl).Copy(), 0);
|
|
}
|
|
|
|
numId = newNum.GetId();
|
|
ilvl = 0;
|
|
|
|
isCheckPrev = true;
|
|
}
|
|
}
|
|
|
|
if (!numId)
|
|
{
|
|
let newNum = this.Numbering.CreateNum();
|
|
newNum.CreateDefault(c_oAscMultiLevelNumbering.Numbered);
|
|
|
|
numId = newNum.GetId();
|
|
ilvl = 0;
|
|
|
|
isCheckPrev = true;
|
|
}
|
|
|
|
if (isCheckPrev)
|
|
{
|
|
let result = this.CheckPrevNumPr(numId, ilvl);
|
|
if (result)
|
|
{
|
|
numId = result.NumId;
|
|
ilvl = result.Lvl;
|
|
}
|
|
}
|
|
|
|
let _ilvl = undefined !== ilvl ? ilvl : 0;
|
|
|
|
this.MergeTextPrFromCommonNum(numId, _ilvl);
|
|
this.SetLastNumbered(numId, _ilvl);
|
|
this.ApplyNumPr(numId, ilvl);
|
|
return true;
|
|
};
|
|
CNumberingApplicator.prototype.ApplyNumberedToCurrent = function()
|
|
{
|
|
let numPr = this.NumPr;
|
|
if (!numPr)
|
|
return false;
|
|
|
|
let num = this.Numbering.GetNum(numPr.NumId);
|
|
if (!num)
|
|
return false;
|
|
|
|
let lvl;
|
|
|
|
let lastNumPr = this.GetLastNumbered();
|
|
let lastNum = lastNumPr ? this.Numbering.GetNum(lastNumPr.NumId) : null;
|
|
if (lastNum && lastNum.GetLvl(numPr.Lvl).IsNumbered())
|
|
{
|
|
if (lastNum.IsHaveRelatedLvlText())
|
|
{
|
|
// В этом случае мы не можем подменить просто текущий уровень, меняем целиком весь список
|
|
for (let iLvl = 0; iLvl < 9; ++iLvl)
|
|
{
|
|
num.SetLvl(lastNum.GetLvl(iLvl).Copy(), iLvl);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
lvl = lastNum.GetLvl(lastNum.Lvl).Copy();
|
|
lvl.ParaPr = num.GetLvl(numPr.Lvl).ParaPr.Copy();
|
|
lvl.ResetNumberedText(numPr.Lvl);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
lvl = num.GetLvl(numPr.Lvl).Copy();
|
|
lvl.SetByType(c_oAscNumberingLevel.DecimalDot_Right, numPr.Lvl);
|
|
lvl.ParaPr = num.GetLvl(numPr.Lvl).ParaPr.Copy();
|
|
}
|
|
|
|
if (lvl)
|
|
num.SetLvl(lvl, numPr.Lvl);
|
|
|
|
this.SetLastNumbered(numPr.NumId, numPr.Lvl);
|
|
return true;
|
|
};
|
|
CNumberingApplicator.prototype.ApplySingleLevel = function()
|
|
{
|
|
let numLvl = this.CreateSingleNumberingLvl();
|
|
if (!numLvl)
|
|
return false;
|
|
|
|
let commonNumPr = this.NumPr ? this.NumPr : null;
|
|
if (commonNumPr && commonNumPr.NumId)
|
|
{
|
|
let num = this.Numbering.GetNum(commonNumPr.NumId);
|
|
if (num)
|
|
{
|
|
this.MergePrToLvl(num.GetLvl(commonNumPr.Lvl), numLvl);
|
|
numLvl.ResetNumberedText(commonNumPr.Lvl);
|
|
num.SetLvl(numLvl, commonNumPr.Lvl);
|
|
this.SetLastSingleLevel(commonNumPr.NumId, commonNumPr.Lvl);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
let num = this.CreateBaseNum();
|
|
let numId = num.GetId();
|
|
let ilvl = !commonNumPr || !commonNumPr.Lvl ? 0 : commonNumPr.Lvl;
|
|
|
|
this.MergePrToLvl(num.GetLvl(ilvl), numLvl);
|
|
|
|
numLvl.ResetNumberedText(ilvl);
|
|
num.SetLvl(numLvl, ilvl);
|
|
|
|
let prevNumPr = this.CheckPrevNumPr(numId, ilvl);
|
|
if (prevNumPr)
|
|
{
|
|
numId = prevNumPr.NumId;
|
|
ilvl = prevNumPr.Lvl;
|
|
}
|
|
|
|
this.ApplyNumPr(numId, ilvl);
|
|
this.SetLastSingleLevel(numId, ilvl);
|
|
}
|
|
|
|
return true;
|
|
};
|
|
CNumberingApplicator.prototype.SetLastSingleLevel = function(numId, ilvl)
|
|
{
|
|
if (NumberingType.Bullet === this.NumInfo.Type)
|
|
this.SetLastBulleted(numId, ilvl);
|
|
else if (NumberingType.Number === this.NumInfo.Type)
|
|
this.SetLastNumbered(numId, ilvl);
|
|
};
|
|
CNumberingApplicator.prototype.ApplyMultilevel = function()
|
|
{
|
|
let commonNumId = this.NumPr ? this.NumPr.NumId : null;
|
|
|
|
let num, numId;
|
|
if (commonNumId)
|
|
{
|
|
num = this.Numbering.GetNum(commonNumId);
|
|
}
|
|
else
|
|
{
|
|
num = this.CreateBaseNum();
|
|
numId = num.GetId();
|
|
}
|
|
|
|
if (!num)
|
|
return false;
|
|
|
|
for (let iLvl = 0; iLvl < 9; ++iLvl)
|
|
{
|
|
let numLvl = this.CreateSingleNumberingLvl(iLvl);
|
|
if (numLvl)
|
|
{
|
|
let pStyle = num.GetLvl(iLvl).GetPStyle();
|
|
if (pStyle)
|
|
numLvl.SetPStyle(pStyle);
|
|
|
|
num.SetLvl(numLvl, iLvl);
|
|
}
|
|
}
|
|
|
|
if (numId)
|
|
{
|
|
this.ApplyNumPr(numId, 0);
|
|
this.ApplyToHeadings(numId);
|
|
}
|
|
else
|
|
{
|
|
this.LinkNumWithHeadings(num);
|
|
}
|
|
|
|
return true;
|
|
};
|
|
CNumberingApplicator.prototype.GetPrevNumPr = function()
|
|
{
|
|
if (!this.Paragraphs || !this.Paragraphs.length)
|
|
return null;
|
|
|
|
let prevParagraph = this.Paragraphs[0].GetPrevParagraph();
|
|
while (prevParagraph)
|
|
{
|
|
if (prevParagraph.GetNumPr() || !prevParagraph.IsEmpty())
|
|
break;
|
|
|
|
prevParagraph = prevParagraph.GetPrevParagraph();
|
|
}
|
|
|
|
return prevParagraph ? prevParagraph.GetNumPr() : null;
|
|
};
|
|
CNumberingApplicator.prototype.GetNextNumPr = function()
|
|
{
|
|
if (!this.Paragraphs || !this.Paragraphs.length)
|
|
return null;
|
|
|
|
let nextParagraph = this.Paragraphs[this.Paragraphs.length - 1].GetNextParagraph();
|
|
while (nextParagraph)
|
|
{
|
|
if (nextParagraph.GetNumPr() || !nextParagraph.IsEmpty())
|
|
break;
|
|
|
|
nextParagraph = nextParagraph.GetNextParagraph();
|
|
}
|
|
|
|
return nextParagraph ? nextParagraph.GetNumPr() : null;
|
|
};
|
|
CNumberingApplicator.prototype.CheckPrevNumPr = function(numId, ilvl)
|
|
{
|
|
if (this.Paragraphs.length !== 1 || this.Document.IsSelectionUse())
|
|
return new AscWord.NumPr(numId, ilvl);
|
|
|
|
var prevParagraph = this.Paragraphs[0].GetPrevParagraph();
|
|
while (prevParagraph)
|
|
{
|
|
if (prevParagraph.GetNumPr() || !prevParagraph.IsEmpty())
|
|
break;
|
|
|
|
prevParagraph = prevParagraph.GetPrevParagraph();
|
|
}
|
|
|
|
let prevNumPr = prevParagraph ? prevParagraph.GetNumPr() : null;
|
|
if (prevNumPr)
|
|
{
|
|
let prevLvl = this.Numbering.GetNum(prevNumPr.NumId).GetLvl(prevNumPr.Lvl);
|
|
let currLvl = this.Numbering.GetNum(numId).GetLvl(ilvl);
|
|
|
|
if (prevLvl.IsSimilar(currLvl))
|
|
return new AscWord.NumPr(prevNumPr.NumId, prevNumPr.Lvl);
|
|
}
|
|
|
|
return new AscWord.NumPr(numId, ilvl);
|
|
};
|
|
CNumberingApplicator.prototype.MergeTextPrFromCommonNum = function(numId, iLvl)
|
|
{
|
|
let commonNumPr = this.NumPr ? this.NumPr : this.GetCommonNumPr(true);
|
|
if (!commonNumPr || !commonNumPr.NumId)
|
|
return;
|
|
|
|
let num = this.Numbering.GetNum(numId);
|
|
let commonNum = this.Numbering.GetNum(commonNumPr.NumId);
|
|
if (!num || !commonNum)
|
|
return;
|
|
|
|
let numLvl = num.GetLvl(iLvl);
|
|
|
|
numLvl = numLvl.Copy();
|
|
this.MergePrToLvl(commonNum.GetLvl(commonNumPr.Lvl), numLvl);
|
|
num.SetLvl(numLvl, iLvl);
|
|
};
|
|
CNumberingApplicator.prototype.GetCommonNumPr = function(skipBulletedCheck)
|
|
{
|
|
let isDiffLvl = false;
|
|
let isDiffId = false;
|
|
let numId = null;
|
|
let ilvl = null;
|
|
|
|
for (let index = 0, count = this.Paragraphs.length; index < count; ++index)
|
|
{
|
|
if (isDiffLvl)
|
|
break;
|
|
|
|
let numPr = this.Paragraphs[index].GetNumPr();
|
|
if (numPr)
|
|
{
|
|
if (null === ilvl)
|
|
ilvl = numPr.Lvl;
|
|
else if (ilvl !== numPr.Lvl)
|
|
isDiffLvl = true;
|
|
|
|
if (null === numId)
|
|
numId = numPr.NumId;
|
|
else if (numId !== numPr.NumId)
|
|
isDiffId = true;
|
|
}
|
|
else
|
|
{
|
|
isDiffLvl = true;
|
|
}
|
|
}
|
|
|
|
if (isDiffLvl)
|
|
{
|
|
numId = null;
|
|
ilvl = 0;
|
|
}
|
|
else if (isDiffId)
|
|
{
|
|
numId = null;
|
|
}
|
|
else if (numId)
|
|
{
|
|
// TODO: Проверить нужна ли эта проверка, если да, то написать тесты (если нет - тоже)
|
|
if (!skipBulletedCheck &&
|
|
this.NumInfo.IsBulleted()
|
|
&& !this.Numbering.CheckFormat(numId, ilvl, Asc.c_oAscNumberingFormat.Bullet))
|
|
{
|
|
numId = null;
|
|
}
|
|
}
|
|
|
|
return new AscWord.NumPr(numId, ilvl);
|
|
};
|
|
CNumberingApplicator.prototype.GetCommonNumId = function()
|
|
{
|
|
let numId = null;
|
|
for (let index = 0, count = this.Paragraphs.length; index < count; ++index)
|
|
{
|
|
let numPr = this.Paragraphs[index].GetNumPr();
|
|
if (numPr)
|
|
{
|
|
if (null === numId)
|
|
numId = numPr.NumId;
|
|
else if (numId !== numPr.NumId)
|
|
return null;
|
|
}
|
|
else
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
return numId;
|
|
};
|
|
CNumberingApplicator.prototype.CreateSingleNumberingLvl = function(ilvl)
|
|
{
|
|
let _ilvl = ilvl ? ilvl : 0;
|
|
|
|
if (!this.NumInfo
|
|
|| !this.NumInfo.Lvl
|
|
|| this.NumInfo.Lvl.length <= _ilvl)
|
|
return null;
|
|
|
|
return AscWord.CNumberingLvl.FromJson(this.NumInfo.Lvl[_ilvl]);
|
|
};
|
|
CNumberingApplicator.prototype.CreateBaseNum = function()
|
|
{
|
|
let num = this.Numbering.CreateNum();
|
|
|
|
if (NumberingType.Bullet === this.NumInfo.Type)
|
|
num.CreateDefault(c_oAscMultiLevelNumbering.Bullet);
|
|
else if (NumberingType.Number === this.NumInfo.Type)
|
|
num.CreateDefault(c_oAscMultiLevelNumbering.Numbered);
|
|
|
|
return num;
|
|
};
|
|
CNumberingApplicator.prototype.ApplyNumPr = function(numId, ilvl)
|
|
{
|
|
// TODO: Надо перенести сюда всю логику подбора уровня по отступам, а в классе параграфа делать простое выставление
|
|
let checkIndents = this.IsCheckIndents();
|
|
for (let index = 0, count = this.Paragraphs.length; index < count; ++index)
|
|
{
|
|
let paragraph = this.Paragraphs[index];
|
|
let oldNumPr = paragraph.GetNumPr();
|
|
|
|
if (oldNumPr)
|
|
paragraph.ApplyNumPr(numId, oldNumPr.Lvl, checkIndents);
|
|
else
|
|
paragraph.ApplyNumPr(numId, ilvl, checkIndents);
|
|
}
|
|
};
|
|
CNumberingApplicator.prototype.ApplyToHeadings = function(numId)
|
|
{
|
|
if (!numId || !this.NumInfo.Headings)
|
|
return;
|
|
|
|
let num = this.Numbering.GetNum(numId);
|
|
let styleManager = this.Document.GetStyleManager();
|
|
if (num)
|
|
{
|
|
num.LinkWithHeadings(styleManager);
|
|
|
|
for (let index = 0, count = this.Paragraphs.length; index < count; ++index)
|
|
{
|
|
let paragraph = this.Paragraphs[index];
|
|
let numPr = paragraph.GetNumPr();
|
|
let iLvl = numPr ? numPr.Lvl : 0;
|
|
paragraph.SetNumPr(null);
|
|
|
|
let pStyle = paragraph.GetParagraphStyle();
|
|
if (!pStyle || -1 === styleManager.GetHeadingLevelById(pStyle))
|
|
paragraph.SetParagraphStyleById(styleManager.GetDefaultHeading(iLvl));
|
|
}
|
|
|
|
this.Document.UpdateStylePanel();
|
|
}
|
|
};
|
|
CNumberingApplicator.prototype.LinkNumWithHeadings = function(num)
|
|
{
|
|
if (!num || !this.NumInfo.Headings)
|
|
return;
|
|
|
|
let styleManager = this.Document.GetStyleManager();
|
|
num.LinkWithHeadings(styleManager);
|
|
this.Document.UpdateStylePanel();
|
|
};
|
|
CNumberingApplicator.prototype.UpdateDocumentOutline = function()
|
|
{
|
|
for (let index = 0, count = this.Paragraphs.length; index < count; ++index)
|
|
{
|
|
this.Paragraphs[index].UpdateDocumentOutline();
|
|
}
|
|
};
|
|
CNumberingApplicator.prototype.MergePrToLvl = function(oldLvl, newLvl)
|
|
{
|
|
if (!oldLvl || !newLvl)
|
|
return;
|
|
|
|
let textPr = oldLvl.GetTextPr().Copy();
|
|
textPr.Merge(newLvl.GetTextPr());
|
|
textPr.RFonts = newLvl.GetTextPr().RFonts.Copy();
|
|
newLvl.SetTextPr(textPr);
|
|
|
|
let paraPr = oldLvl.GetParaPr().Copy();
|
|
paraPr.Merge(newLvl.GetParaPr());
|
|
newLvl.SetParaPr(paraPr);
|
|
|
|
newLvl.SetPStyle(oldLvl.GetPStyle());
|
|
};
|
|
CNumberingApplicator.prototype.IsCheckIndents = function()
|
|
{
|
|
// TODO: Возможно, наоборот, надо тут false возвращать
|
|
if (this.Paragraphs.length <= 1)
|
|
return true;
|
|
|
|
let paraPr = this.Paragraphs[0].Get_CompiledPr2(false).ParaPr;
|
|
let left = paraPr.Ind.Left;
|
|
let first = paraPr.Ind.FirstLine;
|
|
|
|
for (let index = 1, count = this.Paragraphs.length; index < count; ++index)
|
|
{
|
|
let paraPr = this.Paragraphs[index].Get_CompiledPr2(false).ParaPr;
|
|
if (Math.abs(left - paraPr.Ind.Left) > 0.001 || Math.abs(first - paraPr.Ind.FirstLine) > 0.001)
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
};
|
|
//---------------------------------------------------------export---------------------------------------------------
|
|
window["AscWord"].CNumberingApplicator = CNumberingApplicator;
|
|
|
|
})(window);
|