diff --git a/common/Drawings/Metafile.js b/common/Drawings/Metafile.js
index 845a2d1ad7..e3bfb0a7b2 100644
--- a/common/Drawings/Metafile.js
+++ b/common/Drawings/Metafile.js
@@ -837,6 +837,17 @@
this.data[this.pos++] = (c >>> 8) & 0xFF;
}
}
+ this.WriteCustomStringA = function(text)
+ {
+ var encoder = new TextEncoder('utf-8');
+ var encodedText = encoder.encode(text);
+
+ this.WriteULong(encodedText.length);
+
+ for (let i = 0; i < encodedText.length; i++) {
+ this.data[this.pos++] = encodedText[i];
+ }
+ }
this.WriteStringA = function(text)
{
var count = text.length;
diff --git a/common/HistoryCommon.js b/common/HistoryCommon.js
index ea25d141bb..36d35e0e58 100644
--- a/common/HistoryCommon.js
+++ b/common/HistoryCommon.js
@@ -2346,7 +2346,8 @@
window['AscDFH'].historyitem_SdtPr_FormPr = window['AscDFH'].historyitem_type_SdtPr | 22;
window['AscDFH'].historyitem_SdtPr_PictureFormPr = window['AscDFH'].historyitem_type_SdtPr | 23;
window['AscDFH'].historyitem_SdtPr_ComplexFormPr = window['AscDFH'].historyitem_type_SdtPr | 24;
- window['AscDFH'].historyitem_SdtPr_OForm = window['AscDFH'].historyitem_type_SdtPr | 24;
+ window['AscDFH'].historyitem_SdtPr_OForm = window['AscDFH'].historyitem_type_SdtPr | 25;
+ window['AscDFH'].historyitem_SdtPr_DataBinding = window['AscDFH'].historyitem_type_SdtPr | 26;
//------------------------------------------------------------------------------------------------------------------
// Типы изменений в классе CSdtPr
//------------------------------------------------------------------------------------------------------------------
diff --git a/configs/word.json b/configs/word.json
index ef0dfee08a..33505129e6 100644
--- a/configs/word.json
+++ b/configs/word.json
@@ -33,6 +33,7 @@
"word/api.js",
"word/api_plugins.js",
"common/spell/spell.js",
+ "common/zlib/zlib.js",
"word/Editor/Table/TableLook.js",
"cell/utils/utils.js",
"pdf/src/defines.js",
@@ -76,7 +77,7 @@
"common/Drawings/Metafile.js",
"common/libfont/textmeasurer.js",
"common/Drawings/WorkEvents.js",
-
+
"word/Editor/History.js",
"common/Shapes/EditorSettings.js",
@@ -150,13 +151,17 @@
"cell/model/Workbook.js",
"cell/model/Serialize.js",
"cell/model/CellInfo.js",
-
+
+ "word/Editor/custom-xml/custom-xml.js",
+ "word/Editor/custom-xml/custom-xml-manager.js",
+ "word/Editor/custom-xml/data-binding.js",
+
"word/Math/mathTypes.js",
"word/Editor/Styles.js",
"word/Math/math-settings.js",
"word/Editor/StructuredDocumentTags/sdt-settings.js",
"word/Editor/DocumentSettings.js",
-
+
"word/Editor/Paragraph/Run/FontClassification.js",
"word/Editor/Paragraph/Run/FontCalculator.js",
"word/Editor/Paragraph/Run/run-composite-input.js",
@@ -393,7 +398,7 @@
"word/Math/accent.js",
"word/Math/borderBox.js",
"word/Math/mathTrackHandler.js",
-
+
"word/Editor/Styles/style-cache.js",
"word/Editor/Styles/FixedFormDefaults.js",
"word/Editor/Styles/default-styles.js",
diff --git a/tests/word/customXML/customXML.html b/tests/word/customXML/customXML.html
new file mode 100644
index 0000000000..3db4d28ddd
--- /dev/null
+++ b/tests/word/customXML/customXML.html
@@ -0,0 +1,35 @@
+
+
+
+
+
+ Document calculation tests
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+test markup, will be hidden
+
+
diff --git a/tests/word/customXML/customXML.js b/tests/word/customXML/customXML.js
new file mode 100644
index 0000000000..a48c82fa78
--- /dev/null
+++ b/tests/word/customXML/customXML.js
@@ -0,0 +1,795 @@
+/*
+ * (c) Copyright Ascensio System SIA 2010-2023
+ *
+ * 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
+ *
+ */
+
+$(function () {
+
+ function MockZLibEngine ()
+ {
+ this.files = [];
+
+ this.open = function (buf) {
+ //console.log("ZLibFake: Open archive...");
+
+ if (Array.isArray(buf)) {
+ this.files = [];
+ this.data = {};
+ buf.forEach(item => {
+ if (item.path && item.data) {
+ this.files.push(item.path);
+ this.data[item.path] = item.data;
+ }
+ });
+ return this.files;
+ }
+ }
+ this.create = function () {
+ //console.log("ZLibFake: Creating new archive...");
+
+ this.files = [];
+ this.data = {};
+ return true;
+ }
+ this.save = function () {
+ //console.log("ZLibFake: Saving archive...");
+
+ return this.files.map(path => ({
+ path: path,
+ data: this.data[path]
+ }));
+ }
+ this.getFile = function (path) {
+ //console.log(`ZLibFake: Getting file: ${path}`);
+
+ const file = this.data[path] || null;
+ return file ? file : null;
+ }
+ this.addFile = function (path, data) {
+ //console.log(`ZLibFake: Add file: ${path}`);
+
+ if (this.files.indexOf(path) === -1) {
+ this.files.push(path);
+ }
+ this.data[path] = data;
+ return true;
+ }
+ this.removeFile = function (path) {
+ //console.log(`ZLibFake: Removing file: ${path}`);
+
+ const index = this.files.indexOf(path);
+ if (index > -1) {
+ this.files.splice(index, 1);
+ delete this.data[path];
+ return true;
+ }
+ return false;
+ }
+ this.close = function() {
+ //console.log("ZLibFake: Closing archive...");
+
+ this.files = [];
+ this.data = {};
+ }
+ this.getImageBlob = function (path) {
+ // console.log(`ZLibFake: Getting image blob: ${path}`);
+
+ // return new Blob();
+ }
+ this.getPaths = function () {
+ console.log("ZLibFake: Getting all file paths...");
+
+ return this.files;
+ }
+ }
+
+ function MockZLib () {
+ this.engine = new MockZLibEngine();
+ this.files = [];
+
+ this.open = function (buf) {
+ this.files = this.engine.open(buf);
+ return this.files.length > 0;
+ }
+ this.create = function () {
+ return this.engine.create();
+ }
+ this.save = function () {
+ return this.engine.save();
+ }
+ this.getFile = function (path) {
+ return this.engine.getFile(path);
+ }
+ this.addFile = function (path, data) {
+ this.files.push(path);
+ return this.engine.addFile(path, data);
+ }
+ this.removeFile = function (path) {
+ const index = this.files.indexOf(path);
+ if (index > -1) {
+ this.files.splice(index, 1); // Удаляем имя файла
+ }
+
+ return this.engine.removeFile(path);
+ }
+ this.close = function () {
+ return this.engine.close();
+ }
+ this.getImageBlob = function (path) {
+ return this.engine.getImageBlob(path);
+ }
+ this.getPaths = function () {
+ return this.engine.getPaths();
+ }
+ }
+
+ AscCommon.ZLib = MockZLib;
+ let logicDocument = AscTest.CreateLogicDocument();
+ let oXMLManager = logicDocument.getCustomXmlManager();
+ const oCustomXMLData = {
+ 'date': "2000-01-01",
+ 'checkboxTrue': true,
+ 'checkboxFalse': false,
+ 'checkbox0': 0,
+ 'checkbox1': 1,
+ 'checkboxMess': "hello",
+ 'linearXML': '<?xml version="1.0" standalone="yes"?><?mso-application progid="Word.Document"?><pkg:package xmlns:pkg="http://schemas.microsoft.com/office/2006/xmlPackage"><pkg:part pkg:name="/_rels/.rels" pkg:contentType="application/vnd.openxmlformats-package.relationships+xml" pkg:padding="512"><pkg:xmlData><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships></pkg:xmlData></pkg:part><pkg:part pkg:name="/word/document.xml" pkg:contentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"><pkg:xmlData><w:document xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:cx="http://schemas.microsoft.com/office/drawing/2014/chartex" xmlns:cx1="http://schemas.microsoft.com/office/drawing/2015/9/8/chartex" xmlns:cx2="http://schemas.microsoft.com/office/drawing/2015/10/21/chartex" xmlns:cx3="http://schemas.microsoft.com/office/drawing/2016/5/9/chartex" xmlns:cx4="http://schemas.microsoft.com/office/drawing/2016/5/10/chartex" xmlns:cx5="http://schemas.microsoft.com/office/drawing/2016/5/11/chartex" xmlns:cx6="http://schemas.microsoft.com/office/drawing/2016/5/12/chartex" xmlns:cx7="http://schemas.microsoft.com/office/drawing/2016/5/13/chartex" xmlns:cx8="http://schemas.microsoft.com/office/drawing/2016/5/14/chartex" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:aink="http://schemas.microsoft.com/office/drawing/2016/ink" xmlns:am3d="http://schemas.microsoft.com/office/drawing/2017/model3d" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16cex="http://schemas.microsoft.com/office/word/2018/wordml/cex" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" xmlns:w16="http://schemas.microsoft.com/office/word/2018/wordml" xmlns:w16sdtdh="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 w15 w16se w16cid w16 w16cex w16sdtdh wp14"><w:body><w:p w:rsidR="00000000" w:rsidRDefault="001D1115"><w:r><w:rPr><w:lang w:val="en-US"/></w:rPr><w:t>12345+2</w:t></w:r></w:p><w:sectPr w:rsidR="00000000"><w:pgSz w:w="12240" w:h="15840"/><w:pgMar w:top="1134" w:right="850" w:bottom="1134" w:left="1701" w:header="720" w:footer="720" w:gutter="0"/><w:cols w:space="720"/></w:sectPr></w:body></w:document></pkg:xmlData></pkg:part><pkg:part pkg:name="/word/_rels/document.xml.rels" pkg:contentType="application/vnd.openxmlformats-package.relationships+xml" pkg:padding="256"><pkg:xmlData><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/></Relationships></pkg:xmlData></pkg:part><pkg:part pkg:name="/word/styles.xml" pkg:contentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"><pkg:xmlData><w:styles xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16cex="http://schemas.microsoft.com/office/word/2018/wordml/cex" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" xmlns:w16="http://schemas.microsoft.com/office/word/2018/wordml" xmlns:w16sdtdh="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" mc:Ignorable="w14 w15 w16se w16cid w16 w16cex w16sdtdh"><w:docDefaults><w:rPrDefault><w:rPr><w:rFonts w:asciiTheme="minorHAnsi" w:eastAsiaTheme="minorHAnsi" w:hAnsiTheme="minorHAnsi" w:cstheme="minorBidi"/><w:sz w:val="22"/><w:szCs w:val="22"/><w:lang w:val="ru-RU" w:eastAsia="en-US" w:bidi="ar-SA"/></w:rPr></w:rPrDefault><w:pPrDefault><w:pPr><w:spacing w:after="160" w:line="259" w:lineRule="auto"/></w:pPr></w:pPrDefault></w:docDefaults><w:style w:type="paragraph" w:default="1" w:styleId="a"><w:name w:val="Normal"/><w:qFormat/><w:pPr><w:spacing w:after="200" w:line="276" w:lineRule="auto"/></w:pPr></w:style><w:style w:type="character" w:default="1" w:styleId="a0"><w:name w:val="Default Paragraph Font"/><w:uiPriority w:val="1"/><w:semiHidden/><w:unhideWhenUsed/></w:style><w:style w:type="table" w:default="1" w:styleId="a1"><w:name w:val="Normal Table"/><w:uiPriority w:val="99"/><w:semiHidden/><w:unhideWhenUsed/><w:tblPr><w:tblInd w:w="0" w:type="dxa"/><w:tblCellMar><w:top w:w="0" w:type="dxa"/><w:left w:w="108" w:type="dxa"/><w:bottom w:w="0" w:type="dxa"/><w:right w:w="108" w:type="dxa"/></w:tblCellMar></w:tblPr></w:style><w:style w:type="numbering" w:default="1" w:styleId="a2"><w:name w:val="No List"/><w:uiPriority w:val="99"/><w:semiHidden/><w:unhideWhenUsed/></w:style></w:styles></pkg:xmlData></pkg:part></pkg:package>',
+ 'onePicture' : '/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCAEsASwDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9/KKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoooo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',
+ 'twoPicture' : '/9j/4AAQSkZJRgABAQEAYABgAAD/4QAiRXhpZgAATU0AKgAAAAgAAQESAAMAAAABAAEAAAAAAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCAEsASwDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9/KKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoooo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y3t/W79T6m/4Ix/8Em/FP/BWn9q+z8J2K3mmeBNAaK+8Za/EoA0uyLHEUbMCv2mba6RKQeQzkFY3r+xb4IfBPwr+zf8ACTw/4F8E6LZ+HvCnhezSw0zT7VcR28S+55ZiSWZ2JZmZmYkkk/mX/wAE2v8Agpz/AME6f+CY37LGifDHwN8ctBkW1H2rWNWk0LU1utev2UCW6mxbHlsAKmSERUQEhcn3z/iJJ/Yj/wCi9aF/4J9U/wDkau6vVioqjS+Fat9339Fry36Xdk20cNGnKUvbVN3suy009Xa7+7W139xUV8O/8RJP7Ef/AEXrQv8AwT6p/wDI1H/EST+xH/0XrQv/AAT6p/8AI1ch1H3FRXw7/wARJP7Ef/RetC/8E+qf/I1H/EST+xH/ANF60L/wT6p/8jUAfcVFfDv/ABEk/sR/9F60L/wT6p/8jUf8RJP7Ef8A0XrQv/BPqn/yNQB9xUV8O/8AEST+xH/0XrQv/BPqn/yNX2J8LfidoXxq+GugeMPC+oJq3hvxRp8Gq6XepG8a3drPGskUgVwGAZGU4YA88gVXK7c1tP6/yJ5lfl6m9RRRUlBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFfx8/8ABzn/AMpvPjZ/120v/wBNVnX9g1fHv7Tv/BA/9k39sn43638R/iR8KP8AhJPGfiIxNqOo/wDCT6zZ/aDFEkKfure7jiXEcaD5UGcZOSSa550ZOvGotkmvvt/kdFOso0pwe8rfgz+MWiv6/f8AiFx/YT/6Ib/5efiD/wCTqP8AiFx/YT/6Ib/5efiD/wCTq6DnP5AqK/r9/wCIXH9hP/ohv/l5+IP/AJOo/wCIXH9hP/ohv/l5+IP/AJOoA/kCor+v3/iFx/YT/wCiG/8Al5+IP/k6j/iFx/YT/wCiG/8Al5+IP/k6gD+QKiv6/f8AiFx/YT/6Ib/5efiD/wCTqP8AiFx/YT/6Ib/5efiD/wCTqAP5AqK/r9/4hcf2E/8Aohv/AJefiD/5Oo/4hcf2E/8Aohv/AJefiD/5OoA/kY8AeC774k+O9F8O6XD9o1PX7+DTbSLOPMmmkWNFz7swFf3kfCzwLbfC/wCGPhzwzZqqWfh3S7bTIFAwFjhiWNR+Sivjv4Y/8G3P7Fvwc+JHh/xd4c+C66f4g8L6jb6tply3izXLhbe5gkWWJzHJetG+11U7XVlOMEEZFfcVdPto/V1SW/M2/uSj915ff93P7Juv7V7JWXzd3+UbfMKKKK5joCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA/9k=',
+ }
+ const oCustomXMLs = {
+ "withoutContent" : "\n\n\n\"",
+ "date" : "\n\n" + oCustomXMLData.date + "\n\"",
+ 'checkboxTrue': "\n\n" + oCustomXMLData.checkboxTrue + "\n\"",
+ 'checkboxFalse': "\n\n" + oCustomXMLData.checkboxFalse + "\n\"",
+ 'checkbox0': "\n\n" + oCustomXMLData.checkbox0 + "\n\"",
+ 'checkbox1': "\n\n" + oCustomXMLData.checkbox1 + "\n\"",
+ 'checkboxMess': "\n\n" + oCustomXMLData.checkboxMess + "\n\"",
+ 'picture': "\n\n" + oCustomXMLData.onePicture + "\n\"",
+ 'notValidData': oCustomXMLData.onePicture,
+ 'checkboxTrueAnotherXML': "\n " + oCustomXMLData.checkboxTrue + "",
+ }
+
+ function CreateContentControl(isInline, nPos)
+ {
+ let para = AscTest.CreateParagraph();
+
+ logicDocument.AddToContent(nPos, para);
+ para.SetThisElementCurrent();
+ return logicDocument.AddContentControl(isInline ? c_oAscSdtLevelType.Inline : c_oAscSdtLevelType.Block);
+ }
+ function CreateDataBindingForCC(contentControl, prefix, itemId, xpath, checkSum)
+ {
+ let oDataBinding = new AscWord.DataBinding(
+ prefix === undefined ? "xmlns:ns0='http://example.com/picture' " : prefix,
+ itemId === undefined ? "{694325A8-B1C9-407B-A2C2-E2DD1740AA5E}" : itemId,
+ xpath === undefined ? "/ns0:documentData[1]/ns0:simpleText[1]" : xpath,
+ checkSum === undefined ? "Gt6wYg==" : checkSum,
+ );
+
+ contentControl.Pr.DataBinding = oDataBinding;
+ contentControl.checkDataBinding();
+ }
+ function CreateCustomXMLForDocument(strContent, ItemId, Uri)
+ {
+ let oXML = new AscWord.CustomXml();
+
+ oXML.addContentByXMLString(
+ strContent !== undefined
+ ? strContent
+ : oCustomXMLs.withoutContent
+ );
+
+ oXML.itemId = ItemId === undefined
+ ? "{694325A8-B1C9-407B-A2C2-E2DD1740AA5E}"
+ : ItemId;
+
+ oXML.uri = Uri === undefined
+ ? ['http://example.com/picture']
+ : Uri;
+
+ oXMLManager.add(oXML);
+ }
+ function SetPictureToContentControl (oCC, strBase64)
+ {
+ oXMLManager.setContentByDataBinding(oCC.Pr.DataBinding, strBase64);
+ }
+ function MoveCursorToCC(oCC, isToStart)
+ {
+ let paragraph = oCC.GetLastParagraph();
+ if (!paragraph || !(paragraph instanceof AscWord.Paragraph))
+ return;
+
+ paragraph.SetThisElementCurrent();
+
+ if (false === isToStart)
+ paragraph.MoveCursorToEndPos();
+ else
+ paragraph.MoveCursorToStartPos();
+
+ return paragraph;
+ }
+
+ function CreateDateCC(nPos, isInline)
+ {
+ let cc = CreateFilledContentControl(nPos, isInline);
+ let dateTimePr = new AscWord.CSdtDatePickerPr();
+ cc.ApplyDatePickerPr(dateTimePr, true);
+ return cc;
+ }
+ function CreateCheckBoxCC(nPos, isInline)
+ {
+ let cc = CreateFilledContentControl(nPos, isInline)
+ let checkboxPr = new AscWord.CSdtCheckBoxPr();
+ cc.ApplyCheckBoxPr(checkboxPr);
+ return cc;
+ }
+ // поле со списком
+ function CreateComboBox(nPos, isInline)
+ {
+ let cc = CreateFilledContentControl(nPos, isInline);
+ let comboBoxPr = new AscWord.CSdtComboBoxPr();
+ cc.ApplyComboBoxPr(comboBoxPr, true);
+ return cc;
+ }
+ // раскрывающийся список
+ function CreateDropDown(nPos, isInline)
+ {
+ let cc = CreateFilledContentControl(nPos, isInline);
+ let comboBoxPr = new AscWord.CSdtComboBoxPr();
+ cc.ApplyDropDownListPr(comboBoxPr, true);
+ return cc;
+ }
+ function CreatePicture(nPos, isInline)
+ {
+ let cc = CreateFilledContentControl(nPos, isInline);
+ let picturePr = new AscWord.CSdtPictureFormPr();
+ cc.ApplyPicturePr(picturePr);
+ return cc;
+ }
+ function CreateText(nPos, isInline)
+ {
+ let cc = CreateFilledContentControl(nPos, isInline);
+ cc.SetContentControlText(true)
+ return cc;
+ }
+
+ function CreateFilledContentControl(nPos, isInline)
+ {
+ return CreateContentControl(isInline, nPos)
+ }
+ function CheckContentParagraph(assert, oContentArr, arrSample)
+ {
+ for (let i = 0; i < arrSample.length; i++)
+ {
+ let oCurStr = arrSample[i];
+ let oCurContent = oContentArr[i].GetText();
+ assert.strictEqual(oCurStr, oCurContent, oCurContent);
+ }
+ }
+
+ function getCheck(strContent)
+ {
+ return '\n' +
+ '\n' +
+ '\t'+ strContent +'\n' +
+ '';
+ }
+ function Reset()
+ {
+ AscTest.ClearDocument();
+ oXMLManager.xml = []
+ }
+
+ QUnit.testStart( function() { Reset() } );
+
+ QUnit.module("Block content control");
+
+ QUnit.test("Date and CheckBox content control's load/save from/to different CustomXML's", async function (assert)
+ {
+ CreateCustomXMLForDocument(oCustomXMLs.date);
+ CreateCustomXMLForDocument(oCustomXMLs.checkboxTrueAnotherXML, "{694325A8-B1C9-407B-A2C2-E2DD1740AA55}", ["/weather[1]"]);
+
+ let c1 = CreateDateCC(0);
+ CreateDataBindingForCC(c1);
+
+ let oDatePr = c1.GetDatePickerPr();
+ let strDate = oDatePr.GetFullDate();
+ let oDate = new Date(strDate).toDateString();
+ let oStartDate = new Date(oCustomXMLData.date).toDateString();
+
+ assert.strictEqual(oDate, oStartDate, "Date loaded from CustomXml");
+
+ let c2 = CreateCheckBoxCC(1);
+ CreateDataBindingForCC(c2, '', "{694325A8-B1C9-407B-A2C2-E2DD1740AA55}", '/weather[1]', '');
+ let oCHeckBoxPr = c2.GetCheckBoxPr();
+
+ assert.strictEqual(
+ oCHeckBoxPr.Checked,
+ oCustomXMLData.checkboxTrue,
+ "Check load checkbox content from CustomXML with text \"" + oCustomXMLData.checkboxTrue + "\" is true"
+ );
+
+ assert.strictEqual(
+ oXMLManager.getCustomXMLString(oXMLManager.getCustomXml(0)),
+ '\n\n\t01/01/2000\n',
+ "Check saved CustomXML"
+ );
+
+ assert.strictEqual(
+ oXMLManager.getCustomXMLString(oXMLManager.getCustomXml(1)),
+ "\n" + oCustomXMLData.checkboxTrue + "",
+ "Check saved CustomXML"
+ );
+ });
+
+ QUnit.test("Date content control load/save CustomXML", async function (assert)
+ {
+ CreateCustomXMLForDocument(oCustomXMLs.date);
+
+ let c1 = CreateDateCC(0);
+ CreateDataBindingForCC(c1);
+
+ let oDatePr = c1.GetDatePickerPr();
+ let strDate = oDatePr.GetFullDate();
+ let oDate = new Date(strDate).toDateString();
+ let oStartDate = new Date(oCustomXMLData.date).toDateString();
+
+ assert.strictEqual(oDate, oStartDate, "Date loaded from CustomXml");
+
+ assert.strictEqual(
+ oXMLManager.getCustomXMLString(oXMLManager.getCustomXml(0)),
+ '\n\n\t01/01/2000\n',
+ "Check saved CustomXML"
+ );
+ });
+
+ QUnit.test("Checkbox content control load/save CustomXML", async function (assert)
+ {
+ CreateCustomXMLForDocument(oCustomXMLs.checkboxTrue);
+ let c1 = CreateCheckBoxCC(0);
+ CreateDataBindingForCC(c1);
+ let oCHeckBoxPr = c1.GetCheckBoxPr();
+
+ assert.strictEqual(
+ oCHeckBoxPr.Checked,
+ oCustomXMLData.checkboxTrue,
+ "Check load checkbox content from CustomXML with text \"" + oCustomXMLData.checkboxTrue + "\" is true"
+ );
+ Reset();
+
+ CreateCustomXMLForDocument(oCustomXMLs.checkboxFalse);
+ c1 = CreateCheckBoxCC(0);
+ CreateDataBindingForCC(c1);
+ oCHeckBoxPr = c1.GetCheckBoxPr();
+ assert.strictEqual(
+ oCHeckBoxPr.Checked,
+ oCustomXMLData.checkboxFalse,
+ "Check load checkbox content from CustomXML with text \"" + oCustomXMLData.checkboxFalse + "\" is false"
+ );
+ Reset();
+
+ CreateCustomXMLForDocument(oCustomXMLs.checkbox0);
+ c1 = CreateCheckBoxCC(0);
+ CreateDataBindingForCC(c1);
+ oCHeckBoxPr = c1.GetCheckBoxPr();
+ assert.strictEqual(
+ oCHeckBoxPr.Checked,
+ oCustomXMLData.checkboxFalse,
+ "Check load checkbox content from CustomXML with text \"" + oCustomXMLData.checkbox0 + "\" is false"
+ );
+ Reset();
+
+ CreateCustomXMLForDocument(oCustomXMLs.checkbox1);
+ c1 = CreateCheckBoxCC(0);
+ CreateDataBindingForCC(c1);
+ oCHeckBoxPr = c1.GetCheckBoxPr();
+ assert.strictEqual(
+ oCHeckBoxPr.Checked,
+ oCustomXMLData.checkboxTrue,
+ "Check load checkbox content from CustomXML with text \"" + oCustomXMLData.checkbox1 + "\" is true"
+ );
+ Reset();
+
+ CreateCustomXMLForDocument(oCustomXMLs.checkboxMess);
+ c1 = CreateCheckBoxCC(0);
+ CreateDataBindingForCC(c1);
+ oCHeckBoxPr = c1.GetCheckBoxPr();
+ assert.strictEqual(
+ oCHeckBoxPr.Checked,
+ oCustomXMLData.checkboxFalse,
+ "Check load checkbox content from CustomXML with text \"" + oCustomXMLData.checkboxMess + "\" is false"
+ );
+
+ c1.SetCheckBoxChecked(true);
+ assert.strictEqual(
+ oXMLManager.getCustomXMLString(oXMLManager.getCustomXml(0)),
+ getCheck('true'),
+ "Check saved CustomXML"
+ );
+
+ c1.SetCheckBoxChecked(false);
+ assert.strictEqual(
+ oXMLManager.getCustomXMLString(oXMLManager.getCustomXml(0)),
+ getCheck('false'),
+ "Check saved CustomXML"
+ );
+ });
+
+ QUnit.test("ComboBox content control load from/save CustomXML", async function (assert)
+ {
+ CreateCustomXMLForDocument(oCustomXMLs.checkboxMess);
+
+ let c1 = CreateComboBox(0);
+ CreateDataBindingForCC(c1);
+
+ let oValue = c1.GetCurrentParagraph().GetText();
+
+ assert.strictEqual(oValue, "hello ", "Date loaded from CustomXml");
+ assert.strictEqual(
+ oXMLManager.getCustomXMLString(oXMLManager.getCustomXml(0)),
+ '\n\n\thello\n',
+ "Check saved CustomXML"
+ );
+
+ let oPar = c1.GetCurrentParagraph();
+
+ oPar.MoveCursorToEndPos()
+ AscTest.AddTextToParagraph(oPar,'123')
+ oValue = c1.GetCurrentParagraph().GetText();
+
+ assert.strictEqual(oValue, "hello123 ", "Date loaded from CustomXml");
+ });
+
+ QUnit.test("DropDown content control load from/save CustomXML", async function (assert)
+ {
+ CreateCustomXMLForDocument(oCustomXMLs.checkboxMess);
+
+ let c1 = CreateDropDown(0);
+ CreateDataBindingForCC(c1);
+
+ let oValue = c1.GetCurrentParagraph().GetText();
+
+ assert.strictEqual(oValue, "hello ", "Date loaded from CustomXml");
+ assert.strictEqual(
+ oXMLManager.getCustomXMLString(oXMLManager.getCustomXml(0)),
+ '\n\n\thello\n',
+ "Check saved CustomXML"
+ );
+
+ let oPar = c1.GetCurrentParagraph();
+
+ oPar.MoveCursorToEndPos()
+ AscTest.AddTextToParagraph(oPar,'123')
+ oValue = c1.GetCurrentParagraph().GetText();
+
+ assert.strictEqual(oValue, "hello123 ", "Date saved from CustomXml");
+ });
+
+ QUnit.test("Picture content control load from/save CustomXML", async function (assert)
+ {
+ let editor = logicDocument.GetApi();
+ editor.ImageLoader = AscCommon.g_image_loader;
+
+ CreateCustomXMLForDocument(oCustomXMLs.picture);
+ let c1 = CreatePicture(0);
+ CreateDataBindingForCC(c1);
+
+ let strCheckDefaultPicture = '\n\n\t/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCAEsASwDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9/KKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKo+JvE+m+CvD17q+s6hY6TpOmwvc3l7ezrBb2sSDLSSSOQqKACSSQABSclFc0thpNuyL1Ffhj/wAFSv8Ag8T0/wCDPxH/AOES/Zk0Hwv49/sm5ki1bxR4jhuJdJuShZTHZRQTQvKuQD9oLhCB8quGD18of8Rq37U3/Qg/AD/wR6v/APLOphNTXMtipwcHZn9PtFfir/wQV/4OO/jf/wAFSP27v+FX/EDwt8KtH0D/AIRy91f7R4e0y/t7zzYWhCLunvZk2HzGyNmeByK/aqt505RUZP7Suvva/QxhUUnKK6O34J/qFFFFZlhRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFR3d5Fp9pLPPLHDBChkkkkYKkagZLEngADvX4t/wDBY/8A4OzvCn7PY1j4d/s2my8a+OoGe0vPFs8XmaJorgsri3U4+1zKRw2PIGQcy8rWVSsoPl3b6Lf+vN6GtOlKa5tkur2/ryWp+iv/AAUj/wCCrvwd/wCCWnwyXXvibr23VL+KR9H8Oaftm1fWmTAPkxFhhASAZHKoueWzxX8vP/BWv/gvX8Y/+CrniCfTNUuW8FfC6KWOWx8Gabc77feg4luptqNcyZJI3AIvG1AQWPyR8b/jt4y/aU+Jup+M/H3iXV/FvinWZPNvNS1K4aeeU9hk/dVRwqrhVAAAAGK5OojSlK0q2/bov835/ckW6yiuWl9/X/gfL5thRXY/FD9nrx18EtC8Man4w8IeI/DGn+NLE6noU+qWElqmrWobb50JcDemccjsynowJ46ujZtPoc/S5+qX/Bnf/wApff8AuSNW/wDRltX9VVfyq/8ABnf/AMpff+5I1b/0ZbV/VVXZiv4VH/C//S5HJhv4lX/F/wC2xCiiiuM6wooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAK8X/bj/wCCgnwo/wCCdHwfl8a/FfxTbeH9M3+RaWyKZ77VJiCRDbwL88jHaeeFUAlmUAmvUPiEmtSeAdcXw21pH4ibT7gaU13/AKhbvy28kycH5PM2546Zr+IH9v74yfGP40/tX+L7348aprmo/ErS7+XS9Uh1NsHTHhdlNtFGPkiiQ7tqxgLyWGdxJ5alWTq+xho7Xv5eXdrr2ur3vY6adOKp+1nqr2t/n2/Wz2Prf/gsL/wch/Fn/gpxLqHhDw99o+Gnwdk3QnQLK4JvNcjyCG1CcY3jjPkpiMZw3mEB6/OKiv0B/wCCP/8Awbz/ABd/4Kpaja+JJlb4ffCGOfbdeKNRt2MmpKpw8enwHBuGzwZCViX5vnZl8s9WGwtlaHzb/V/l9y7HPXxF7c3yX+S/ruz44/Zy/Zm8fftdfFfTvA/w18Kax4x8U6o37iw06HeyqCA0kjcLFEuRukcqijkkCv6SP+COH/Bql4A/Y3OnePfjt/Y3xR+JIRJ7bR3t/N0Dw5JweEf/AI/JlP8Ay0kUIp+7HlRIf0A/YB/4Jq/CD/gmh8Jx4T+FPheDSlnVDqerXBE+q63IucSXNwQGfksQg2xpuOxFBxXvVdXtY0/4O/f/AC7eu/pscvJKqr1VZdv8+/pt67n86H/B7+oT4/fAMAYA8PaoAB2/0mCvwyr9zf8Ag+B/5OA+Af8A2L2qf+lMFfhlXj5f/Cf+Kf8A6XI9PGfxF/hh/wCko/VL/gzv/wCUvv8A3JGrf+jLav6qq/lV/wCDO/8A5S+/9yRq3/oy2r+qqvaxX8Kj/hf/AKXI8rDfxKv+L/22IUUUVxnWFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABX5Qf8ABb//AINnLX/gqN+0TpXxQ8C+L9C+Hfia4sfsXiX7ZpslxHrTR7Rb3H7thiVY8xsSDuVIuRt5/V+iolTjJqT3W35FxqSinFbPf8z8Zf8Agm5/wZ6fDr9m74jp4t+OPii1+MFzp0qyaboEFg1noqsDnfdKzM9zyBiM7Y+odZAcD9k9L0u20PTLeysreC0s7SJYIIIIxHFBGoCqiqMBVAAAA4AFT0VvKrKUVDoun9fmYRpxjJyW7/r+kFFFFZmh/Oh/wfA/8nAfAP8A7F7VP/SmCvwyr9zf+D4H/k4D4B/9i9qn/pTBX4ZVw5f/AAn/AIp/+lyOvG/xF/hh/wCko/VL/gzv/wCUvv8A3JGrf+jLav6qq/lV/wCDO/8A5S+/9yRq3/oy2r+qqvaxX8Kj/hf/AKXI8nDfxKv+L/22IUUUVxnWFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAH86H/B8D/ycB8A/+xe1T/0pgr8Mq/c3/g+B/wCTgPgH/wBi9qn/AKUwV+GVcOX/AMJ/4p/+lyOvG/xF/hh/6Sj9Uv8Agzv/AOUvv/ckat/6Mtq/qqr+VX/gzv8A+Uvv/ckat/6Mtq/qqr2sV/Co/wCF/wDpcjycN/Eq/wCL/wBtiFFFFcZ1hRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQB/Oh/wfA/8AJwHwD/7F7VP/AEpgr8Mq/c3/AIPgf+TgPgH/ANi9qn/pTBX4ZVw5f/Cf+Kf/AKXI68b/ABF/hh/6Sj9Uv+DO/wD5S+/9yRq3/oy2r+qqv5Vf+DO//lL7/wByRq3/AKMtq/qqr2sV/Co/4X/6XI8nDfxKv+L/ANtiFFFFcZ1hRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQB/Oh/wAHwP8AycB8A/8AsXtU/wDSmCvwyr9zf+D4H/k4D4B/9i9qn/pTBX4ZVw5f/Cf+Kf8A6XI68b/EX+GH/pKP1S/4M7/+Uvv/AHJGrf8Aoy2r+qqv5Vf+DO//AJS+/wDckat/6Mtq/qqr2sV/Co/4X/6XI8nDfxKv+L/22IUUUVxnWFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAH86H/B8D/ycB8A/wDsXtU/9KYK/DKv3N/4Pgf+TgPgH/2L2qf+lMFfhlXDl/8ACf8Ain/6XI68b/EX+GH/AKSj9Uv+DO//AJS+/wDckat/6Mtq/qqr+VX/AIM7/wDlL7/3JGrf+jLav6qq9rFfwqP+F/8ApcjycN/Eq/4v/bYhRRRXGdYUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAfzof8HwP/JwHwD/7F7VP/SmCvwyr9zf+D4H/AJOA+Af/AGL2qf8ApTBX4ZVw5f8Awn/in/6XI68b/EX+GH/pKP1S/wCDO/8A5S+/9yRq3/oy2r+qqv5Vf+DO/wD5S+/9yRq3/oy2r+qqvaxX8Kj/AIX/AOlyPJw38Sr/AIv/AG2IUUUVxnWFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAH86H/B8D/wAnAfAP/sXtU/8ASmCvwyr9zf8Ag+B/5OA+Af8A2L2qf+lMFfhlXDl/8J/4p/8Apcjrxv8AEX+GH/pKP1S/4M7/APlL7/3JGrf+jLav6qq/lV/4M7/+Uvv/AHJGrf8Aoy2r+qqvaxX8Kj/hf/pcjycN/Eq/4v8A22IUUUVxnWFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAH86H/AAfA/wDJwHwD/wCxe1T/ANKYK/DKv3N/4Pgf+TgPgH/2L2qf+lMFfhlXDl/8J/4p/wDpcjrxv8Rf4Yf+ko/VL/gzv/5S+/8Ackat/wCjLav6qq/lV/4M7/8AlL7/ANyRq3/oy2r+qqvaxX8Kj/hf/pcjycN/Eq/4v/bYhRRRXGdYUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAfFv/BVD/ghX8JP+CvHjDwjrfxJ8RfEbRLrwXZ3FjZJ4av7K2jlSZ0djILi1nJIKDG0qMZ4NfKX/ABBU/ss/9D98f/8AweaR/wDKyv1/oqYQjBWiu7+93f4lSm5O8v6tofn/AP8ABNn/AINxPgh/wS3/AGj/APhaHw/8U/FXWNf/ALKuNI+z+IdSsLiz8qYoXbbBZQvvHlrg78cng1+gFFFaSnKSSfTb8/1M1BRba6/8N+gUUUVJQUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAf/2Q==\n'
+
+ assert.strictEqual(
+ oXMLManager.getCustomXMLString(oXMLManager.getCustomXml(0)),
+ strCheckDefaultPicture,
+ "Check load CustomXML"
+ );
+
+ SetPictureToContentControl(c1, oCustomXMLData.twoPicture);
+
+ let strCheckAfterPicture = '\n\n\t/9j/4AAQSkZJRgABAQEAYABgAAD/4QAiRXhpZgAATU0AKgAAAAgAAQESAAMAAAABAAEAAAAAAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCAEsASwDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9/KKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoooo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y3t/W79T6m/4Ix/8Em/FP/BWn9q+z8J2K3mmeBNAaK+8Za/EoA0uyLHEUbMCv2mba6RKQeQzkFY3r+xb4IfBPwr+zf8ACTw/4F8E6LZ+HvCnhezSw0zT7VcR28S+55ZiSWZ2JZmZmYkkk/mX/wAE2v8Agpz/AME6f+CY37LGifDHwN8ctBkW1H2rWNWk0LU1utev2UCW6mxbHlsAKmSERUQEhcn3z/iJJ/Yj/wCi9aF/4J9U/wDkau6vVioqjS+Fat9339Fry36Xdk20cNGnKUvbVN3suy009Xa7+7W139xUV8O/8RJP7Ef/AEXrQv8AwT6p/wDI1H/EST+xH/0XrQv/AAT6p/8AI1ch1H3FRXw7/wARJP7Ef/RetC/8E+qf/I1H/EST+xH/ANF60L/wT6p/8jUAfcVFfDv/ABEk/sR/9F60L/wT6p/8jUf8RJP7Ef8A0XrQv/BPqn/yNQB9xUV8O/8AEST+xH/0XrQv/BPqn/yNX2J8LfidoXxq+GugeMPC+oJq3hvxRp8Gq6XepG8a3drPGskUgVwGAZGU4YA88gVXK7c1tP6/yJ5lfl6m9RRRUlBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFfx8/8ABzn/AMpvPjZ/120v/wBNVnX9g1fHv7Tv/BA/9k39sn43638R/iR8KP8AhJPGfiIxNqOo/wDCT6zZ/aDFEkKfure7jiXEcaD5UGcZOSSa550ZOvGotkmvvt/kdFOso0pwe8rfgz+MWiv6/f8AiFx/YT/6Ib/5efiD/wCTqP8AiFx/YT/6Ib/5efiD/wCTq6DnP5AqK/r9/wCIXH9hP/ohv/l5+IP/AJOo/wCIXH9hP/ohv/l5+IP/AJOoA/kCor+v3/iFx/YT/wCiG/8Al5+IP/k6j/iFx/YT/wCiG/8Al5+IP/k6gD+QKiv6/f8AiFx/YT/6Ib/5efiD/wCTqP8AiFx/YT/6Ib/5efiD/wCTqAP5AqK/r9/4hcf2E/8Aohv/AJefiD/5Oo/4hcf2E/8Aohv/AJefiD/5OoA/kY8AeC774k+O9F8O6XD9o1PX7+DTbSLOPMmmkWNFz7swFf3kfCzwLbfC/wCGPhzwzZqqWfh3S7bTIFAwFjhiWNR+Sivjv4Y/8G3P7Fvwc+JHh/xd4c+C66f4g8L6jb6tply3izXLhbe5gkWWJzHJetG+11U7XVlOMEEZFfcVdPto/V1SW/M2/uSj915ff93P7Juv7V7JWXzd3+UbfMKKKK5joCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA/9k=\n'
+
+ assert.strictEqual(
+ oXMLManager.getCustomXMLString(oXMLManager.getCustomXml(0)),
+ strCheckAfterPicture,
+ "Check saved CustomXML"
+ );
+ });
+
+ QUnit.test("Simple text content control load from/save CustomXML", async function (assert)
+ {
+ CreateCustomXMLForDocument(oCustomXMLs.checkboxMess);
+ let c1 = CreateText(0);
+ CreateDataBindingForCC(c1);
+
+ let p = c1.GetFirstParagraph();
+ let str = p.GetText();
+
+ assert.strictEqual(
+ oXMLManager.getCustomXMLString(oXMLManager.getCustomXml(0)),
+ '\n\n\thello\n',
+ "Check load CustomXML"
+ );
+ });
+
+ QUnit.test("Rich text content control load from/save CustomXML", async function (assert)
+ {
+ CreateCustomXMLForDocument(getCheck(oCustomXMLData.linearXML));
+
+ let c1 = CreateFilledContentControl(0);
+ CreateDataBindingForCC(c1);
+
+ let p = c1.GetFirstParagraph();
+ let strContentInParagraph = p.GetText();
+ assert.strictEqual(
+ strContentInParagraph,
+ '12345+2 ',
+ "Content in Paragraph after load CustomXML"
+ );
+
+ let p1 = MoveCursorToCC(c1);
+ AscTest.AddTextToParagraph(p1, "990")
+ let str = oXMLManager.getCustomXMLString(oXMLManager.getCustomXml(0));
+
+ assert.strictEqual(
+ str,
+ `
+
+\t<?xml version="1.0" standalone="yes"?><?mso-application progid="Word.Document"?><pkg:package xmlns:pkg="http://schemas.microsoft.com/office/2006/xmlPackage"><pkg:part pkg:name="/_rels/.rels" pkg:contentType="application/vnd.openxmlformats-package.relationships+xml" pkg:padding="512"><pkg:xmlData><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships></pkg:xmlData></pkg:part><pkg:part pkg:name="/word/document.xml" pkg:contentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"><pkg:xmlData><w:document xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:cx="http://schemas.microsoft.com/office/drawing/2014/chartex" xmlns:cx1="http://schemas.microsoft.com/office/drawing/2015/9/8/chartex" xmlns:cx2="http://schemas.microsoft.com/office/drawing/2015/10/21/chartex" xmlns:cx3="http://schemas.microsoft.com/office/drawing/2016/5/9/chartex" xmlns:cx4="http://schemas.microsoft.com/office/drawing/2016/5/10/chartex" xmlns:cx5="http://schemas.microsoft.com/office/drawing/2016/5/11/chartex" xmlns:cx6="http://schemas.microsoft.com/office/drawing/2016/5/12/chartex" xmlns:cx7="http://schemas.microsoft.com/office/drawing/2016/5/13/chartex" xmlns:cx8="http://schemas.microsoft.com/office/drawing/2016/5/14/chartex" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:aink="http://schemas.microsoft.com/office/drawing/2016/ink" xmlns:am3d="http://schemas.microsoft.com/office/drawing/2017/model3d" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16cex="http://schemas.microsoft.com/office/word/2018/wordml/cex" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" xmlns:w16="http://schemas.microsoft.com/office/word/2018/wordml" xmlns:w16sdtdh="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 w15 w16se w16cid w16 w16cex w16sdtdh wp14"><w:body><w:p w:rsidR="00000000" w:rsidRDefault="001D1115"><w:r><w:rPr><w:lang w:val="en-US"/></w:rPr><w:t>12345+2</w:t></w:r></w:p><w:sectPr w:rsidR="00000000"><w:pgSz w:w="12240" w:h="15840"/><w:pgMar w:top="1134" w:right="850" w:bottom="1134" w:left="1701" w:header="720" w:footer="720" w:gutter="0"/><w:cols w:space="720"/></w:sectPr></w:body></w:document></pkg:xmlData></pkg:part><pkg:part pkg:name="/word/_rels/document.xml.rels" pkg:contentType="application/vnd.openxmlformats-package.relationships+xml" pkg:padding="256"><pkg:xmlData><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/></Relationships></pkg:xmlData></pkg:part><pkg:part pkg:name="/word/styles.xml" pkg:contentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"><pkg:xmlData><w:styles xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16cex="http://schemas.microsoft.com/office/word/2018/wordml/cex" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" xmlns:w16="http://schemas.microsoft.com/office/word/2018/wordml" xmlns:w16sdtdh="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" mc:Ignorable="w14 w15 w16se w16cid w16 w16cex w16sdtdh"><w:docDefaults><w:rPrDefault><w:rPr><w:rFonts w:asciiTheme="minorHAnsi" w:eastAsiaTheme="minorHAnsi" w:hAnsiTheme="minorHAnsi" w:cstheme="minorBidi"/><w:sz w:val="22"/><w:szCs w:val="22"/><w:lang w:val="ru-RU" w:eastAsia="en-US" w:bidi="ar-SA"/></w:rPr></w:rPrDefault><w:pPrDefault><w:pPr><w:spacing w:after="160" w:line="259" w:lineRule="auto"/></w:pPr></w:pPrDefault></w:docDefaults><w:style w:type="paragraph" w:default="1" w:styleId="a"><w:name w:val="Normal"/><w:qFormat/><w:pPr><w:spacing w:after="200" w:line="276" w:lineRule="auto"/></w:pPr></w:style><w:style w:type="character" w:default="1" w:styleId="a0"><w:name w:val="Default Paragraph Font"/><w:uiPriority w:val="1"/><w:semiHidden/><w:unhideWhenUsed/></w:style><w:style w:type="table" w:default="1" w:styleId="a1"><w:name w:val="Normal Table"/><w:uiPriority w:val="99"/><w:semiHidden/><w:unhideWhenUsed/><w:tblPr><w:tblInd w:w="0" w:type="dxa"/><w:tblCellMar><w:top w:w="0" w:type="dxa"/><w:left w:w="108" w:type="dxa"/><w:bottom w:w="0" w:type="dxa"/><w:right w:w="108" w:type="dxa"/></w:tblCellMar></w:tblPr></w:style><w:style w:type="numbering" w:default="1" w:styleId="a2"><w:name w:val="No List"/><w:uiPriority w:val="99"/><w:semiHidden/><w:unhideWhenUsed/></w:style></w:styles></pkg:xmlData></pkg:part></pkg:package>
+`,
+ "Check load CustomXML"
+ );
+ });
+
+ QUnit.module("Inline content control");
+
+ QUnit.test("Date and CheckBox inline content control's load/save from/to different CustomXML's", async function (assert)
+ {
+ CreateCustomXMLForDocument(oCustomXMLs.date);
+ CreateCustomXMLForDocument(oCustomXMLs.checkboxTrueAnotherXML, "{694325A8-B1C9-407B-A2C2-E2DD1740AA55}", ["/weather[1]"]);
+
+ let c1 = CreateDateCC(0, true);
+ CreateDataBindingForCC(c1);
+
+ let oDatePr = c1.GetDatePickerPr();
+ let strDate = oDatePr.GetFullDate();
+ let oDate = new Date(strDate).toDateString();
+ let oStartDate = new Date(oCustomXMLData.date).toDateString();
+
+ assert.strictEqual(oDate, oStartDate, "Date loaded from CustomXml");
+
+ let c2 = CreateCheckBoxCC(1, true);
+ CreateDataBindingForCC(c2, '', "{694325A8-B1C9-407B-A2C2-E2DD1740AA55}", '/weather[1]', '');
+ let oCHeckBoxPr = c2.GetCheckBoxPr();
+
+ assert.strictEqual(
+ oCHeckBoxPr.Checked,
+ oCustomXMLData.checkboxTrue,
+ "Check load checkbox content from CustomXML with text \"" + oCustomXMLData.checkboxTrue + "\" is true"
+ );
+
+ assert.strictEqual(
+ oXMLManager.getCustomXMLString(oXMLManager.getCustomXml(0)),
+ '\n\n\t01/01/2000\n',
+ "Check saved CustomXML"
+ );
+
+ assert.strictEqual(
+ oXMLManager.getCustomXMLString(oXMLManager.getCustomXml(1)),
+ "\n" + oCustomXMLData.checkboxTrue + "",
+ "Check saved CustomXML"
+ );
+ });
+
+ QUnit.test("Date content control load/save CustomXML", async function (assert)
+ {
+ CreateCustomXMLForDocument(oCustomXMLs.date);
+
+ let c1 = CreateDateCC(0, true);
+ CreateDataBindingForCC(c1);
+
+ let oDatePr = c1.GetDatePickerPr();
+ let strDate = oDatePr.GetFullDate();
+ let oDate = new Date(strDate).toDateString();
+ let oStartDate = new Date(oCustomXMLData.date).toDateString();
+
+ assert.strictEqual(oDate, oStartDate, "Date loaded from CustomXml");
+
+ assert.strictEqual(
+ oXMLManager.getCustomXMLString(oXMLManager.getCustomXml(0)),
+ '\n\n\t01/01/2000\n',
+ "Check saved CustomXML"
+ );
+ });
+
+ QUnit.test("Checkbox content control load/save CustomXML", async function (assert)
+ {
+ CreateCustomXMLForDocument(oCustomXMLs.checkboxTrue);
+ let c1 = CreateCheckBoxCC(0, true);
+ CreateDataBindingForCC(c1);
+ let oCHeckBoxPr = c1.GetCheckBoxPr();
+
+ assert.strictEqual(
+ oCHeckBoxPr.Checked,
+ oCustomXMLData.checkboxTrue,
+ "Check load checkbox content from CustomXML with text \"" + oCustomXMLData.checkboxTrue + "\" is true"
+ );
+ Reset();
+
+ CreateCustomXMLForDocument(oCustomXMLs.checkboxFalse);
+ c1 = CreateCheckBoxCC(0, true);
+ CreateDataBindingForCC(c1);
+ oCHeckBoxPr = c1.GetCheckBoxPr();
+ assert.strictEqual(
+ oCHeckBoxPr.Checked,
+ oCustomXMLData.checkboxFalse,
+ "Check load checkbox content from CustomXML with text \"" + oCustomXMLData.checkboxFalse + "\" is false"
+ );
+ Reset();
+
+ CreateCustomXMLForDocument(oCustomXMLs.checkbox0);
+ c1 = CreateCheckBoxCC(0, true);
+ CreateDataBindingForCC(c1);
+ oCHeckBoxPr = c1.GetCheckBoxPr();
+ assert.strictEqual(
+ oCHeckBoxPr.Checked,
+ oCustomXMLData.checkboxFalse,
+ "Check load checkbox content from CustomXML with text \"" + oCustomXMLData.checkbox0 + "\" is false"
+ );
+ Reset();
+
+ CreateCustomXMLForDocument(oCustomXMLs.checkbox1);
+ c1 = CreateCheckBoxCC(0, true);
+ CreateDataBindingForCC(c1);
+ oCHeckBoxPr = c1.GetCheckBoxPr();
+ assert.strictEqual(
+ oCHeckBoxPr.Checked,
+ oCustomXMLData.checkboxTrue,
+ "Check load checkbox content from CustomXML with text \"" + oCustomXMLData.checkbox1 + "\" is true"
+ );
+ Reset();
+
+ CreateCustomXMLForDocument(oCustomXMLs.checkboxMess);
+ c1 = CreateCheckBoxCC(0, true);
+ CreateDataBindingForCC(c1);
+ oCHeckBoxPr = c1.GetCheckBoxPr();
+ assert.strictEqual(
+ oCHeckBoxPr.Checked,
+ oCustomXMLData.checkboxFalse,
+ "Check load checkbox content from CustomXML with text \"" + oCustomXMLData.checkboxMess + "\" is false"
+ );
+
+ c1.SetCheckBoxChecked(true);
+ assert.strictEqual(
+ oXMLManager.getCustomXMLString(oXMLManager.getCustomXml(0)),
+ getCheck('true'),
+ "Check saved CustomXML"
+ );
+
+ c1.SetCheckBoxChecked(false);
+ assert.strictEqual(
+ oXMLManager.getCustomXMLString(oXMLManager.getCustomXml(0)),
+ getCheck('false'),
+ "Check saved CustomXML"
+ );
+ });
+
+ QUnit.test("ComboBox content control load from/save CustomXML", async function (assert)
+ {
+ CreateCustomXMLForDocument(oCustomXMLs.checkboxMess);
+
+ let c1 = CreateComboBox(0, true);
+
+ CreateDataBindingForCC(c1);
+
+ let oValue = c1.GetInnerText();
+
+ assert.strictEqual(oValue, "hello", "Date loaded from CustomXml");
+ assert.strictEqual(
+ oXMLManager.getCustomXMLString(oXMLManager.getCustomXml(0)),
+ '\n\n\thello\n',
+ "Check saved CustomXML"
+ );
+
+ c1.SelectContentControl();
+ AscTest.EnterText('123')
+ oValue = c1.GetInnerText();
+
+ assert.strictEqual(oValue, "123", "Date loaded from CustomXml");
+ });
+
+ QUnit.test("DropDown content control load from/save CustomXML", async function (assert)
+ {
+ CreateCustomXMLForDocument(oCustomXMLs.checkboxMess);
+
+ let c1 = CreateDropDown(0, true);
+ CreateDataBindingForCC(c1);
+
+ c1.Pr.DropDown.AddItem('123', '123', 1);
+ c1.Pr.DropDown.AddItem('456', '456', 2);
+
+ let oValue = c1.GetInnerText();
+
+ assert.strictEqual(oValue, "hello", "Date loaded from CustomXml");
+ assert.strictEqual(
+ oXMLManager.getCustomXMLString(oXMLManager.getCustomXml(0)),
+ '\n\n\thello\n',
+ "Check saved CustomXML"
+ );
+
+ c1.SelectContentControl();
+ c1.SelectListItem('123')
+ oValue = c1.GetInnerText();
+
+ assert.strictEqual(oValue, "123", "Date saved from CustomXml");
+ });
+
+ QUnit.test("Picture content control load from/save CustomXML", async function (assert)
+ {
+ let editor = logicDocument.GetApi();
+ editor.ImageLoader = AscCommon.g_image_loader;
+
+ CreateCustomXMLForDocument(oCustomXMLs.picture);
+ let c1 = CreatePicture(0, true);
+ CreateDataBindingForCC(c1);
+
+ let strCheckDefaultPicture = '\n\n\t/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCAEsASwDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9/KKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoooo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\n'
+
+ assert.strictEqual(
+ oXMLManager.getCustomXMLString(oXMLManager.getCustomXml(0)),
+ strCheckDefaultPicture,
+ "Check load CustomXML"
+ );
+
+ SetPictureToContentControl(c1, oCustomXMLData.twoPicture);
+
+ let strCheckAfterPicture = '\n\n\t/9j/4AAQSkZJRgABAQEAYABgAAD/4QAiRXhpZgAATU0AKgAAAAgAAQESAAMAAAABAAEAAAAAAAD/2wBDAAIBAQIBAQICAgICAgICAwUDAwMDAwYEBAMFBwYHBwcGBwcICQsJCAgKCAcHCg0KCgsMDAwMBwkODw0MDgsMDAz/2wBDAQICAgMDAwYDAwYMCAcIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAz/wAARCAEsASwDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9/KKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoooo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y3t/W79T6m/4Ix/8Em/FP/BWn9q+z8J2K3mmeBNAaK+8Za/EoA0uyLHEUbMCv2mba6RKQeQzkFY3r+xb4IfBPwr+zf8ACTw/4F8E6LZ+HvCnhezSw0zT7VcR28S+55ZiSWZ2JZmZmYkkk/mX/wAE2v8Agpz/AME6f+CY37LGifDHwN8ctBkW1H2rWNWk0LU1utev2UCW6mxbHlsAKmSERUQEhcn3z/iJJ/Yj/wCi9aF/4J9U/wDkau6vVioqjS+Fat9339Fry36Xdk20cNGnKUvbVN3suy009Xa7+7W139xUV8O/8RJP7Ef/AEXrQv8AwT6p/wDI1H/EST+xH/0XrQv/AAT6p/8AI1ch1H3FRXw7/wARJP7Ef/RetC/8E+qf/I1H/EST+xH/ANF60L/wT6p/8jUAfcVFfDv/ABEk/sR/9F60L/wT6p/8jUf8RJP7Ef8A0XrQv/BPqn/yNQB9xUV8O/8AEST+xH/0XrQv/BPqn/yNX2J8LfidoXxq+GugeMPC+oJq3hvxRp8Gq6XepG8a3drPGskUgVwGAZGU4YA88gVXK7c1tP6/yJ5lfl6m9RRRUlBRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFfx8/8ABzn/AMpvPjZ/120v/wBNVnX9g1fHv7Tv/BA/9k39sn43638R/iR8KP8AhJPGfiIxNqOo/wDCT6zZ/aDFEkKfure7jiXEcaD5UGcZOSSa550ZOvGotkmvvt/kdFOso0pwe8rfgz+MWiv6/f8AiFx/YT/6Ib/5efiD/wCTqP8AiFx/YT/6Ib/5efiD/wCTq6DnP5AqK/r9/wCIXH9hP/ohv/l5+IP/AJOo/wCIXH9hP/ohv/l5+IP/AJOoA/kCor+v3/iFx/YT/wCiG/8Al5+IP/k6j/iFx/YT/wCiG/8Al5+IP/k6gD+QKiv6/f8AiFx/YT/6Ib/5efiD/wCTqP8AiFx/YT/6Ib/5efiD/wCTqAP5AqK/r9/4hcf2E/8Aohv/AJefiD/5Oo/4hcf2E/8Aohv/AJefiD/5OoA/kY8AeC774k+O9F8O6XD9o1PX7+DTbSLOPMmmkWNFz7swFf3kfCzwLbfC/wCGPhzwzZqqWfh3S7bTIFAwFjhiWNR+Sivjv4Y/8G3P7Fvwc+JHh/xd4c+C66f4g8L6jb6tply3izXLhbe5gkWWJzHJetG+11U7XVlOMEEZFfcVdPto/V1SW/M2/uSj915ff93P7Juv7V7JWXzd3+UbfMKKKK5joCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA/9k=\n'
+
+ assert.strictEqual(
+ oXMLManager.getCustomXMLString(oXMLManager.getCustomXml(0)),
+ strCheckAfterPicture,
+ "Check saved CustomXML"
+ );
+ });
+
+ QUnit.test("Simple text content control load from/save CustomXML", async function (assert)
+ {
+ CreateCustomXMLForDocument(oCustomXMLs.checkboxMess);
+ let c1 = CreateText(0, true);
+ CreateDataBindingForCC(c1);
+
+
+
+ assert.strictEqual(
+ oXMLManager.getCustomXMLString(oXMLManager.getCustomXml(0)),
+ '\n\n\thello\n',
+ "Check load CustomXML"
+ );
+ });
+
+});
diff --git a/word/Editor/Document.js b/word/Editor/Document.js
index 39cc89ccea..e064537c58 100644
--- a/word/Editor/Document.js
+++ b/word/Editor/Document.js
@@ -411,7 +411,7 @@ function CDocumentRecalculateState()
this.UseRecursion = true;
this.Continue = false; // параметр сигнализирующий, о том что нужно продолжить пересчет (для нерекурсивного метода)
-
+
this.ScrollToTarget = true;
}
@@ -1865,9 +1865,9 @@ function CDocument(DrawingDocument, isMainLogicDocument)
this.Content[0] = new AscWord.Paragraph(this);
this.Content[0].Set_DocumentNext(null);
this.Content[0].Set_DocumentPrev(null);
-
+
this.Background = new AscWord.DocumentBackground();
-
+
this.CurPos =
{
X : 0,
@@ -2175,6 +2175,8 @@ function CDocument(DrawingDocument, isMainLogicDocument)
this.AutoCorrectSettings = new AscCommon.CAutoCorrectSettings();
+ this.customXml = new AscWord.CustomXmlManager(this);
+
// Контролируем изменения интерфейса
this.ChangedStyles = []; // Объект с Id стилями, которые были изменены/удалены/добавлены
this.TurnOffPanelStyles = 0; // == 0 - можно обновлять панельку со стилями, != 0 - нельзя обновлять
@@ -2309,7 +2311,7 @@ CDocument.prototype.sendEvent = function()
{
if (!this.MainDocument || !this.Api)
return;
-
+
this.Api.sendEvent.apply(this.Api, arguments);
};
CDocument.prototype.UpdateDefaultsDependingOnCompatibility = function()
@@ -2606,7 +2608,7 @@ CDocument.prototype.StartAction = function(nDescription, oSelectionState, flags)
this.Action.Redraw.Start = undefined;
this.Action.Redraw.End = undefined;
this.Action.Additional = {};
-
+
if (undefined !== flags && null !== flags)
{
this.Action.Recalculate = !!(flags & ACTION_FLAGS.RECALCULATE);
@@ -2780,11 +2782,11 @@ CDocument.prototype.FinalizeAction = function(checkEmptyAction)
this.Action.Depth--;
return true;
}
-
+
this.private_CheckAdditionalOnFinalize();
this.private_CheckEmptyPointsInAction(checkEmptyAction);
this.private_CheckActionLock();
-
+
let actionCompleted = true;
if (this.Action.CancelAction)
{
@@ -2793,13 +2795,13 @@ CDocument.prototype.FinalizeAction = function(checkEmptyAction)
{
arrChanges = arrChanges.concat(this.History.Undo());
}
-
+
if (arrChanges.length)
this.RecalculateByChanges(arrChanges);
-
+
actionCompleted = false;
}
-
+
if (this.Action.PointsCount)
{
if (this.Action.Recalculate)
@@ -2891,7 +2893,7 @@ CDocument.prototype.CheckActionLock = function()
{
if (!this.IsActionStarted())
return;
-
+
this.Action.CheckLock = true;
};
CDocument.prototype.StartUndoRedoAction = function()
@@ -2958,12 +2960,12 @@ CDocument.prototype.private_CheckEmptyPointsInAction = function(checkEmptyAction
{
if (false === checkEmptyAction)
return;
-
+
for (let pointIndex = 0, pointCount = this.Action.PointsCount; pointIndex < pointCount; ++pointIndex)
{
if (!this.History.Is_LastPointEmpty())
break;
-
+
this.History.Remove_LastPoint();
--this.Action.PointsCount;
}
@@ -2972,18 +2974,18 @@ CDocument.prototype.private_CheckActionLock = function()
{
if (!this.Action.CheckLock || !this.Action.PointsCount || this.Action.CancelAction)
return;
-
+
if (!this.StartSelectionLockCheck())
{
this.Action.CancelAction = true;
return;
}
-
+
this.History.checkLock(this.Action.PointsCount);
-
+
if (this.EndSelectionLockCheck())
this.Action.CancelAction = true;
-
+
// TODO: Если сервер нам запрещает делать действие, то мы делаем Undo из совместки. Но там делается отмена
// только для одной точки, а в действии их может быть несколько. Надо доработать этот момент (но в текущий
// момент данная проверка не вызывается для случаев, где в действии более одной точки)
@@ -3299,7 +3301,7 @@ CDocument.prototype.private_Recalculate = function(_RecalcData, isForceStrictRec
var RecalcData = History.Get_RecalcData(_RecalcData);
History.Reset_RecalcIndex();
-
+
if (RecalcData.ResetCache)
this.Reset_RecalculateCache();
@@ -4572,7 +4574,7 @@ CDocument.prototype.Recalculate_PageColumn = function()
else
this.CurPage = PageIndex; // TODO: переделать
}
-
+
if (docpostype_Content === this.GetDocPosType() && ((true !== this.Selection.Use && Index === this.CurPos.ContentPos + 1) || (true === this.Selection.Use && Index === (Math.max(this.Selection.EndPos, this.Selection.StartPos) + 1))))
this.UpdateCursorOnRecalculate();
}
@@ -5264,7 +5266,7 @@ CDocument.prototype.private_RecalculateFlowParagraph = function(RecalcIn
var TempElement = this.Content[TempIndex];
TempElement.Reset(TempElement.X, TempElement.Y, TempElement.XLimit, TempElement.YLimit, PageIndex, ColumnIndex, ColumnsCount);
}
-
+
Index += FlowCount - 1;
RecalcResult = recalcresult_NextElement;
}
@@ -5512,7 +5514,7 @@ CDocument.prototype.CheckViewPosition = function()
}
this.FullRecalc.ScrollToTarget = false;
-
+
let anchorPos = this.ViewPosition.AnchorPos;
let alignTop = this.ViewPosition.AlignTop;
let distance = this.ViewPosition.Distance;
@@ -5644,9 +5646,9 @@ CDocument.prototype.Draw = function(nPageInd
// Определим секцию
var Page_StartPos = this.Pages[nPageIndex].Pos;
var SectPr = this.SectionsInfo.Get_SectPr(Page_StartPos).SectPr;
-
+
this.Background.draw(pGraphics, SectPr, this.GetTheme(), this.GetColorMap());
-
+
// Рисуем границы вокруг страницы (если границы надо рисовать под текстом)
if (section_borders_ZOrderBack === SectPr.Get_Borders_ZOrder())
this.DrawPageBorders(pGraphics, SectPr, nPageIndex);
@@ -5661,7 +5663,7 @@ CDocument.prototype.Draw = function(nPageInd
else if (!this.IsViewMode())
pGraphics.End_GlobalAlpha();
}
-
+
this.DrawingObjects.drawBehindDoc(nPageIndex, pGraphics);
this.Footnotes.Draw(nPageIndex, pGraphics);
@@ -5936,7 +5938,7 @@ CDocument.prototype.setBackgroundColor = function(color, unifill)
{
let oldValue = this.Background.copy();
let newValue = new AscWord.DocumentBackground(color, unifill, null);
-
+
AscCommon.History.Add(new CChangesDocumentPageColor(this, oldValue, newValue));
this.Background = newValue;
};
@@ -6433,7 +6435,7 @@ CDocument.prototype.AddToParagraph = function(oParaItem, bRecalculate)
this.RemoveSelectedNumberingOnTextAdd();
this.Controller.AddToParagraph(oParaItem, bRecalculate);
-
+
if (para_TextPr === oParaItem.Type)
this.setMergeFormatComplexFieldOnApplyTextPr();
};
@@ -6473,7 +6475,7 @@ CDocument.prototype.RemoveSelectedNumberingOnTextAdd = function()
CDocument.prototype.setMergeFormatComplexFieldOnApplyTextPr = function()
{
let complexField = this.GetCurrentComplexField();
-
+
// Word doesn't add MERGEFORMAT for all field types (for example PAGE)
// So we add it to some specific types
if (!complexField
@@ -6483,7 +6485,7 @@ CDocument.prototype.setMergeFormatComplexFieldOnApplyTextPr = function()
|| !complexField.CheckType(AscWord.fieldtype_REF)
|| !this.Action.Start)
return;
-
+
// We don't check selection lock, because this method should be called when other action was started
let state = this.SaveDocumentState();
this.StartAction(AscDFH.historydescription_Document_ComplexField_MergeFormat);
@@ -8328,7 +8330,7 @@ CDocument.prototype.OnEndTextDrag = function(NearPos, bCopy)
arrParagraphs[0].AddTrackMoveMark(true, true, this.TrackMoveId);
}
}
-
+
if (!bCopy)
{
// TODO: Проверить, зачем тут посылается isOnAddText=true. Когда выделены ячейки таблицы точно нужно посылать false
@@ -8812,7 +8814,7 @@ CDocument.prototype.OnKeyDown = function(e)
{
if (this.Api.isTargetHandMode() && !this.IsInFormField())
this.Api.asc_setViewerTargetType("select");
-
+
this.SelectAll();
bUpdateSelection = false;
bRetValue = keydownresult_PreventAll;
@@ -10162,7 +10164,7 @@ CDocument.prototype.CorrectEnterText = function(oldValue, newValue)
let state = this.SaveDocumentState(false);
let startPos = paragraph.getCurrentPos();
let endPos = startPos;
-
+
let paraSearchPos = new CParagraphSearchPos();
let maxShifts = oldCodePoints.length;
@@ -10172,12 +10174,12 @@ CDocument.prototype.CorrectEnterText = function(oldValue, newValue)
{
paraSearchPos.Reset();
paragraph.Get_LeftPos(paraSearchPos, endPos);
-
+
if (!paraSearchPos.IsFound())
break;
-
+
endPos = paraSearchPos.GetPos().Copy();
-
+
paragraph.SetSelectionContentPos(startPos, endPos, false);
selectedText = paragraph.GetSelectedText(true);
@@ -10192,7 +10194,7 @@ CDocument.prototype.CorrectEnterText = function(oldValue, newValue)
this.LoadDocumentState(state);
return false;
}
-
+
this.StartAction(AscDFH.historydescription_Document_CorrectEnterText);
@@ -11523,16 +11525,16 @@ CDocument.prototype.SetSectionPageNumFormat = function(format)
let curHdrFtr = this.HdrFtr.CurHdrFtr;
if (!curHdrFtr)
return;
-
+
let curPage = curHdrFtr.RecalcInfo.CurPage;
if (-1 === curPage)
return;
-
+
let startIndex = this.Pages[curPage].Pos;
let sectPr = this.SectionsInfo.Get_SectPr(startIndex).SectPr;
-
+
sectPr.SetPageNumFormat(format);
-
+
this.Recalculate();
this.UpdateSelection();
this.UpdateInterface();
@@ -11545,7 +11547,7 @@ CDocument.prototype.isHeaderEditing = function()
{
if (docpostype_HdrFtr !== this.GetDocPosType())
return false;
-
+
let hdrFtr = this.HdrFtr.Get_CurHdrFtr();
return hdrFtr && AscCommon.hdrftr_Header === hdrFtr.Type;
};
@@ -11553,7 +11555,7 @@ CDocument.prototype.isFooterEditing = function()
{
if (docpostype_HdrFtr !== this.GetDocPosType())
return false;
-
+
let hdrFtr = this.HdrFtr.Get_CurHdrFtr();
return hdrFtr && AscCommon.hdrftr_Footer === hdrFtr.Type;
};
@@ -12434,7 +12436,7 @@ CDocument.prototype.Document_UpdateCopyCutState = function()
// Во время работы селекта не обновляем состояние
if (true === this.Selection.Start)
return;
-
+
let canCopy = this.Can_CopyCut();
let canCut = canCopy;
if (this.IsFillingFormMode() && canCut)
@@ -12503,7 +12505,7 @@ CDocument.prototype.GetWatermark = function()
let header = this.Get_SectionHdrFtr(this.CurPage, pageInfo.bFirst, pageInfo.bFirst.bEven).Header;
if (header)
return header.FindWatermark();
-
+
return null;
}
else
@@ -12513,21 +12515,21 @@ CDocument.prototype.GetWatermark = function()
let header = sectPr.Get_Header_Default();
if (header)
return header.FindWatermark();
-
+
return null;
}
};
CDocument.prototype.GetWatermarkProps = function()
{
let watermark = this.GetWatermark();
-
+
let props = new Asc.CAscWatermarkProperties();
props.put_Api(this.Api);
if (watermark)
props = watermark.GetWatermarkProps();
else
props.put_Type(Asc.c_oAscWatermarkType.None);
-
+
return props;
};
CDocument.prototype.GetHeaderForWatermark = function()
@@ -12538,7 +12540,7 @@ CDocument.prototype.GetHeaderForWatermark = function()
let header = this.Get_SectionHdrFtr(this.CurPage, pageInfo.bFirst, pageInfo.bFirst.bEven).Header;
if (header)
return header;
-
+
return this.Create_SectionHdrFtr(hdrftr_Header, this.CurPage);
}
else
@@ -12548,7 +12550,7 @@ CDocument.prototype.GetHeaderForWatermark = function()
let header = sectPr.Get_Header_Default();
if (header)
return header;
-
+
header = new CHeaderFooter(this.HdrFtr, this, this.DrawingDocument, hdrftr_Header);
sectPr.Set_Header_Default(header);
return header;
@@ -12577,10 +12579,10 @@ CDocument.prototype.SetWatermarkPropsAction = function(oProps)
this.RemoveSelection(true);
watermark.Remove_FromDocument(false);
}
-
+
if (Asc.c_oAscWatermarkType.None === oProps.get_Type())
return;
-
+
let oWatermark = this.DrawingObjects.createWatermark(oProps);
if (oWatermark)
{
@@ -13746,7 +13748,7 @@ CDocument.prototype.HideCurrentComment = function()
{
if (!this.Comments.Is_Use() || !this.Comments.Get_CurrentId())
return;
-
+
this.SelectComment(null, false);
this.Api.sync_HideComment();
};
@@ -14443,12 +14445,12 @@ CDocument.prototype.UpdateCursorOnRecalculate = function()
let isLockScroll = false;
if ((this.FullRecalc.Id && !this.FullRecalc.ScrollToTarget) || this.ViewPosition)
isLockScroll = true;
-
+
if (isLockScroll)
this.Api.asc_LockScrollToTarget(true);
-
+
this.private_UpdateCursorXY(true, true);
-
+
if (isLockScroll)
this.Api.asc_LockScrollToTarget(false);
};
@@ -16097,7 +16099,7 @@ CDocument.prototype.private_GetElementPageIndexByXY = function(ElementPos, X, Y,
StartColumn = 0;
EndColumn = Math.min(ElementPagesCount - ElementStartColumn + (PageIndex - ElementStartPage) * ColumnsCount, ColumnsCount - 1);
}
-
+
if (!PageSection.Columns[EndColumn])
return 0;
@@ -16644,12 +16646,12 @@ CDocument.prototype.SetDocumentReadMode = function(nW, nH, nScale)
{
oRun.Recalc_CompiledPr(true);
});
-
+
this.GetAllParagraphs().forEach(function(paragraph)
{
paragraph.RecalcCompiledPr();
});
-
+
this.GetAllTables().forEach(function(table)
{
table.Recalc_CompiledPr();
@@ -16665,12 +16667,12 @@ CDocument.prototype.SetDocumentPrintMode = function()
{
oRun.Recalc_CompiledPr(true);
});
-
+
this.GetAllParagraphs().forEach(function(paragraph)
{
paragraph.RecalcCompiledPr();
});
-
+
this.GetAllTables().forEach(function(table)
{
table.Recalc_CompiledPr();
@@ -17331,7 +17333,7 @@ CDocument.prototype.Get_MailMergedDocument = function(_nStartIndex, _nEndIndex)
LogicDocument.theme = this.theme.createDuplicate();
LogicDocument.clrSchemeMap = this.clrSchemeMap.createDuplicate();
-
+
LogicDocument.Background = this.Background.copy();
var FieldsManager = this.FieldsManager;
@@ -18220,7 +18222,7 @@ CDocument.prototype.AddFootnote = function(sText)
if (this.IsSelectionLocked(changestype_Paragraph_Content))
return null
-
+
this.StartAction(AscDFH.historydescription_Document_AddFootnote);
let footnote = this._addFootnote(sText);
this.Recalculate();
@@ -18240,12 +18242,12 @@ CDocument.prototype._addFootnote = function(text)
this.MoveCursorRight(false, false, false);
this.RemoveSelection();
}
-
+
if (text)
this.AddToParagraph(new AscWord.CRunFootnoteReference(oFootnote, text));
else
this.AddToParagraph(new AscWord.CRunFootnoteReference(oFootnote));
-
+
this.SetDocPosType(docpostype_Footnotes);
this.Footnotes.Set_CurrentElement(true, 0, oFootnote);
}
@@ -18459,7 +18461,7 @@ CDocument.prototype.AddEndnote = function(sText)
if (this.IsSelectionLocked(changestype_Paragraph_Content))
return null;
-
+
this.StartAction(AscDFH.historydescription_Document_AddEndnote);
let endnote = this._addEndnote(sText);
this.Recalculate();
@@ -18474,18 +18476,18 @@ CDocument.prototype._addEndnote = function(text)
{
oEndnote = this.Endnotes.CreateEndnote();
oEndnote.AddDefaultEndnoteContent(text);
-
+
if (true === this.IsSelectionUse())
{
this.MoveCursorRight(false, false, false);
this.RemoveSelection();
}
-
+
if (text)
this.AddToParagraph(new AscWord.CRunEndnoteReference(oEndnote, text));
else
this.AddToParagraph(new AscWord.CRunEndnoteReference(oEndnote));
-
+
this.SetDocPosType(docpostype_Endnotes);
this.Endnotes.Set_CurrentElement(true, 0, oEndnote);
}
@@ -18809,7 +18811,7 @@ CDocument.prototype.controller_AddNewParagraph = function(bRecalculate, bForceAd
var ItemReviewType = Item.GetReviewType();
// Создаем новый параграф
var NewParagraph = new AscWord.Paragraph();
-
+
let firstPara, secondPara;
if (Item.IsCursorAtBegin())
{
@@ -18822,7 +18824,7 @@ CDocument.prototype.controller_AddNewParagraph = function(bRecalculate, bForceAd
var nContentPos = this.CurPos.ContentPos;
this.AddToContent(nContentPos, NewParagraph);
this.CurPos.ContentPos = nContentPos + 1;
-
+
firstPara = NewParagraph;
secondPara = Item;
}
@@ -18885,11 +18887,11 @@ CDocument.prototype.controller_AddNewParagraph = function(bRecalculate, bForceAd
var nContentPos = this.CurPos.ContentPos + 1;
this.AddToContent(nContentPos, NewParagraph);
this.CurPos.ContentPos = nContentPos;
-
+
firstPara = Item;
secondPara = NewParagraph;
}
-
+
if (this.IsTrackRevisions())
{
firstPara.RemovePrChange();
@@ -18919,19 +18921,19 @@ CDocument.prototype.controller_AddNewParagraph = function(bRecalculate, bForceAd
{
// Если мы находимся в начале первого параграфа первой ячейки, и
// данная таблица - первый элемент, тогда добавляем параграф до таблицы.
-
+
let newPos = -1;
if (Item.IsCursorAtBegin(true) && (0 === this.CurPos.ContentPos || !this.Content[this.CurPos.ContentPos - 1].IsParagraph()))
newPos = this.CurPos.ContentPos;
else if (Item.IsCursorAtEnd() && (this.Content.length - 1 === this.CurPos.ContentPos || !this.Content[this.CurPos.ContentPos + 1].IsParagraph()))
newPos = this.CurPos.ContentPos + 1;
-
+
if (-1 !== newPos)
{
let newParagraph = new AscWord.Paragraph();
this.Internal_Content_Add(newPos, newParagraph);
this.CurPos.ContentPos = newPos;
-
+
if (this.IsTrackRevisions())
{
newParagraph.RemovePrChange();
@@ -21712,7 +21714,7 @@ CDocument.prototype.controller_UpdateSelectionState = function()
this.private_CheckCurPage();
this.RecalculateCurPos();
}
-
+
this.private_UpdateTracks(true, false);
this.DrawingDocument.TargetEnd();
@@ -22141,7 +22143,7 @@ CDocument.prototype.IsFillingOFormMode = function()
{
if (!this.IsFillingFormMode())
return false;
-
+
let api = this.GetApi();
return !!(api.DocInfo && api.DocInfo.isFormatWithForms());
};
@@ -22169,7 +22171,7 @@ CDocument.prototype.IsInFormField = function(isAllowComplexForm, isCheckCurrentU
if (oInlineSdt && oInlineSdt.IsContentControlEquation())
return false;
-
+
if (isCheckCurrentUser
&& oInlineSdt
&& (!oInlineSdt.IsComplexForm() || isAllowComplexForm))
@@ -22417,7 +22419,7 @@ CDocument.prototype.RemoveContentControlWrapper = function(Id)
let contentControl = this.TableId.Get_ById(Id);
if (!contentControl)
return;
-
+
if (contentControl.IsForm())
contentControl.RemoveFormPr();
@@ -22708,7 +22710,7 @@ CDocument.prototype.AddFieldWithInstruction = function(instructionLine, textPr)
var oParagraph = this.GetCurrentParagraph(false, false, {ReplacePlaceHolder : true});
if (!oParagraph)
return null;
-
+
return this.addFieldWithInstructionToParagraph(oParagraph, instructionLine, textPr);
};
CDocument.prototype.addFieldWithInstructionToParagraph = function(paragraph, instructionLine, textPr, forceUpdate)
@@ -22716,18 +22718,18 @@ CDocument.prototype.addFieldWithInstructionToParagraph = function(paragraph, ins
let beginChar = new ParaFieldChar(fldchartype_Begin, this);
let separateChar = new ParaFieldChar(fldchartype_Separate, this);
let endChar = new ParaFieldChar(fldchartype_End, this);
-
+
var run = new AscWord.Run();
run.AddToContent(-1, beginChar);
run.AddInstrText(instructionLine);
run.AddToContent(-1, separateChar);
run.AddToContent(-1, endChar);
paragraph.Add(run);
-
+
beginChar.SetRun(run);
separateChar.SetRun(run);
endChar.SetRun(run);
-
+
let complexField = beginChar.GetComplexField();
complexField.SetBeginChar(beginChar);
complexField.SetInstructionLine(instructionLine);
@@ -22740,10 +22742,10 @@ CDocument.prototype.addFieldWithInstructionToParagraph = function(paragraph, ins
let pos = run.GetElementPosition(endChar);
run.AddText(value, pos);
}
-
+
if (textPr)
run.SetPr(textPr);
-
+
return complexField;
};
CDocument.prototype.AddDateTime = function(oPr)
@@ -22823,7 +22825,7 @@ CDocument.prototype.AddRefToParagraph = function(oParagraph, nType, bHyperlink,
let bookmarkName = oParagraph.AddBookmarkForRef();
if (bookmarkName)
this.private_AddRefToBookmark(bookmarkName, nType, bHyperlink, bAboveBelow, sSeparator);
-
+
this.UpdateInterface();
this.UpdateSelection();
this.FinalizeAction();
@@ -23200,7 +23202,7 @@ CDocument.prototype.GetAllFields = function(isUseSelection)
this.RemoveSelection();
arrFields = this.GetCurrentComplexFields();
this.LoadDocumentState(state);
-
+
this.Controller.GetAllFields(isUseSelection, arrFields);
}
else
@@ -23263,7 +23265,7 @@ CDocument.prototype.AddAddinField = function(data)
this.RemoveSelection();
let textPr = this.GetDirectTextPr();
-
+
let field = this.AddFieldWithInstruction(" ADDIN " + instruction + " ", textPr);
if (field)
{
@@ -24769,14 +24771,14 @@ CDocument.prototype.AddCaption = function(oPr)
let targetElement = this.GetCurrentTable();
if (!targetElement)
targetElement = this.GetCurrentParagraph();
-
+
let docContent = targetElement ? targetElement.GetParent() : null;
if (docContent)
{
let targetPos = targetElement.GetIndex();
if (!oPr.get_Before() || -1 === targetPos)
++targetPos;
-
+
NewParagraph = new AscWord.Paragraph();
this.RemoveSelection();
docContent.AddToContent(targetPos, NewParagraph);
@@ -24787,7 +24789,7 @@ CDocument.prototype.AddCaption = function(oPr)
let captionStyleId = this.Styles.GetStyleIdByName("Caption", true);
if (captionStyleId)
NewParagraph.SetParagraphStyleById(captionStyleId);
-
+
var NewRun;
var nCurPos = 0;
var oComplexField;
@@ -27335,6 +27337,13 @@ CDocument.prototype.isPreventedPreDelete = function()
{
return this.PreventPreDelete;
};
+/**
+ * @returns {AscWord.CustomXmlManager}
+ */
+CDocument.prototype.getCustomXmlManager = function()
+{
+ return this.customXml;
+};
function CDocumentSelectionState()
{
diff --git a/word/Editor/Serialize2.js b/word/Editor/Serialize2.js
index 85a075532e..98dee2e930 100644
--- a/word/Editor/Serialize2.js
+++ b/word/Editor/Serialize2.js
@@ -1130,6 +1130,8 @@ var c_oSerSdt = {
TextFormPrFormatVal : 81,
TextFormPrFormatSymbols : 82,
+ StoreItemCheckSum : 85,
+
ComplexFormPr : 90,
ComplexFormPrType : 91,
OformMaster : 92
@@ -1880,8 +1882,10 @@ function BinaryFileWriter(doc, bMailMergeDocx, bMailMergeHtml, isCompatible, opt
pptx_content_writer.BinaryFileWriter.ImportFromMemory(old);
}});
}
- if (this.Document.CustomXmls.length > 0) {
- this.WriteTable(c_oSerTableTypes.Customs, new BinaryCustomsTableWriter(this.memory, this.Document, this.Document.CustomXmls));
+
+ let customXmlManager = this.Document.getCustomXmlManager();
+ if (customXmlManager.getCount() > 0) {
+ this.WriteTable(c_oSerTableTypes.Customs, new BinaryCustomsTableWriter(this.memory, this.Document, customXmlManager));
}
//Write Settings
this.WriteTable(c_oSerTableTypes.Settings, new BinarySettingsTableWriter(this.memory, this.Document, this.saveParams));
@@ -6530,12 +6534,18 @@ function BinaryDocumentTableWriter(memory, doc, oMapCommentId, oNumIdMap, copyPa
// if (oSdt.EndPr) {
// this.bs.WriteItem(c_oSerSdt.EndPr, function(){oThis.brPrs.Write_rPr(oSdt.EndPr, null, null);});
// }
- if (0 === type) {
+
+ if (0 === type)
+ {
var oInnerDocument = new BinaryDocumentTableWriter(this.memory, this.Document, this.oMapCommentId, this.oNumIdMap, this.copyParams, this.saveParams, this.oBinaryHeaderFooterTableWriter);
this.bs.WriteItem(c_oSerSdt.Content, function(){oInnerDocument.WriteDocumentContent(oSdt.Content);});
- } else if (1 === type) {
+ }
+ else if (1 === type)
+ {
this.bs.WriteItem(c_oSerSdt.Content, function(){oThis.WriteParagraphContent(oSdt, false, false);});
}
+
+
};
this.WriteSdtPr = function (val, oSdt)
{
@@ -6553,9 +6563,9 @@ function BinaryDocumentTableWriter(memory, doc, oMapCommentId, oNumIdMap, copyPa
rPr.Color = val.Color;
oThis.bs.WriteItem(c_oSerSdt.Color, function (){oThis.brPrs.Write_rPr(rPr, null, null);});
}
- // if (null != val.DataBinding) {
- // oThis.bs.WriteItem(c_oSerSdt.DataBinding, function (){oThis.WriteSdtPrDataBinding(val.DataBinding);});
- // }
+ if (null != val.DataBinding) {
+ oThis.bs.WriteItem(c_oSerSdt.DataBinding, function (){oThis.WriteSdtPrDataBinding(val.DataBinding);});
+ }
// if (null != val.DocPartList) {
// oThis.bs.WriteItem(c_oSerSdt.DocPartList, function (){oThis.WriteDocPartList(val.DocPartList);});
// }
@@ -6691,17 +6701,25 @@ function BinaryDocumentTableWriter(memory, doc, oMapCommentId, oNumIdMap, copyPa
this.WriteSdtPrDataBinding = function (val)
{
var oThis = this;
- if (null != val.PrefixMappings) {
+ if (null != val.prefixMappings) {
this.memory.WriteByte(c_oSerSdt.PrefixMappings);
- this.memory.WriteString2(val.PrefixMappings);
+ this.memory.WriteString2(val.prefixMappings);
}
- if (null != val.StoreItemID) {
+ if (null != val.storeItemID) {
this.memory.WriteByte(c_oSerSdt.StoreItemID);
- this.memory.WriteString2(val.StoreItemID);
+ this.memory.WriteString2(val.storeItemID);
}
- if (null != val.XPath) {
+ if (null != val.xpath) {
this.memory.WriteByte(c_oSerSdt.XPath);
- this.memory.WriteString2(val.XPath);
+ this.memory.WriteString2(val.xpath);
+ }
+ if (null !== val.storeItemCheckSum)
+ {
+ //let strCustomXmlContent = this.Document.customXml.getContentByDataBinding(val);
+ //val.recalculateCheckSum(strCustomXmlContent);
+
+ this.memory.WriteByte(c_oSerSdt.StoreItemCheckSum);
+ this.memory.WriteString2(val.storeItemCheckSum);
}
};
this.WriteSdtPrDate = function (val)
@@ -7566,12 +7584,14 @@ function BinaryNotesTableWriter(memory, doc, oNumIdMap, oMapCommentId, copyParam
this.bs.WriteItem(c_oSerNotes.NoteContent, function(){dtw.WriteDocumentContent(note);});
};
};
-function BinaryCustomsTableWriter(memory, doc, CustomXmls)
+
+function BinaryCustomsTableWriter(memory, doc, customXmlManager)
{
this.memory = memory;
this.Document = doc;
this.bs = new BinaryCommonWriter(this.memory);
- this.CustomXmls = CustomXmls;
+ this.customXmlManager = customXmlManager;
+
this.Write = function()
{
var oThis = this;
@@ -7580,25 +7600,26 @@ function BinaryCustomsTableWriter(memory, doc, CustomXmls)
this.WriteCustomXmls = function()
{
var oThis = this;
- for (var i = 0; i < this.CustomXmls.length; ++i) {
- this.bs.WriteItem(c_oSerCustoms.Custom, function() {oThis.WriteCustomXml(oThis.CustomXmls[i]);});
+ for (var i = 0, count = this.customXmlManager.getCount(); i < count; ++i) {
+ this.bs.WriteItem(c_oSerCustoms.Custom, function() {oThis.WriteCustomXml(oThis.customXmlManager.getCustomXml(i));});
}
};
this.WriteCustomXml = function(customXml) {
var oThis = this;
- for(var i = 0; i < customXml.Uri.length; ++i){
+ for(var i = 0; i < customXml.uri.length; ++i){
this.bs.WriteItem(c_oSerCustoms.Uri, function () {
- oThis.memory.WriteString3(customXml.Uri[i]);
+ oThis.memory.WriteString3(customXml.uri[i]);
});
}
- if (null !== customXml.ItemId) {
+ if (null !== customXml.itemId) {
this.bs.WriteItem(c_oSerCustoms.ItemId, function() {
- oThis.memory.WriteString3(customXml.ItemId);
+ oThis.memory.WriteString3(customXml.itemId);
});
}
- if (null !== customXml.Content) {
+ if (null !== customXml.content) {
this.bs.WriteItem(c_oSerCustoms.ContentA, function() {
- oThis.memory.WriteBuffer(customXml.Content, 0, customXml.Content.length)
+ let str = customXmlManager.getCustomXMLString(customXml);
+ oThis.memory.WriteCustomStringA(str);
});
}
};
@@ -7892,7 +7913,7 @@ function BinaryFileReader(doc, openParams)
break;
case c_oSerTableTypes.Customs:
this.stream.Seek2(mtiOffBits);
- res = (new Binary_CustomsTableReader(this.Document, this.oReadResult, this.stream, this.Document.CustomXmls)).Read();
+ res = (new Binary_CustomsTableReader(this.Document, this.oReadResult, this.stream)).Read();
break;
case c_oSerTableTypes.Glossary:
if(!this.oReadResult.bCopyPaste || this.oReadResult.isDocumentPasting()) {
@@ -11230,6 +11251,7 @@ function Binary_DocumentTableReader(doc, oReadResult, openParams, stream, curNot
res = this.bcr.Read1(length, function(t, l){
return oThis.ReadSdt(t,l, oSdt, 0);
});
+ oSdt.checkDataBinding();
Content.push(oSdt);
} else if ( c_oSerParType.Background === type ) {
res = this.bcr.Read2(length, function(t, l){
@@ -11572,6 +11594,7 @@ function Binary_DocumentTableReader(doc, oReadResult, openParams, stream, curNot
res = this.bcr.Read1(length, function(t, l){
return oThis.ReadSdt(t,l, oSdt, 1, oSdt);
});
+ oSdt.checkDataBinding();
if (oSdt.IsEmpty())
oSdt.ReplaceContentWithPlaceHolder();
paragraphContent.AddToContentToEnd(oSdt);
@@ -12881,20 +12904,25 @@ function Binary_DocumentTableReader(doc, oReadResult, openParams, stream, curNot
if (oSdtContent.length > 0) {
oSdt.Content.ReplaceContent(oSdtContent);
}
- } else if (1 === typeContainer) {
+ }
+ else if (1 === typeContainer) {
res = this.bcr.Read1(length, function(t, l) {
return oThis.ReadParagraphContent(t, l, container);
});
- } else if (2 === typeContainer) {
+ }
+ else if (2 === typeContainer) {
res = this.bcr.Read1(length, function(t, l) {
return oThis.Read_TableContent(t, l, container);
});
- } else if (3 === typeContainer) {
+ }
+ else if (3 === typeContainer) {
res = this.bcr.Read1(length, function(t, l) {
return oThis.ReadRowContent(t, l, container);
});
}
- } else {
+ }
+ else
+ {
res = c_oSerConstants.ReadUnknown;
}
return res;
@@ -12930,12 +12958,14 @@ function Binary_DocumentTableReader(doc, oReadResult, openParams, stream, curNot
if(textPr.Color){
oSdtPr.Color = textPr.Color;
}
- // } else if (c_oSerSdt.DataBinding === type) {
- // oSdtPr.DataBinding = {};
- // res = this.bcr.Read1(length, function(t, l) {
- // return oThis.ReadSdtPrDataBinding(t, l, oSdtPr.DataBinding);
- // });
- } else if (c_oSerSdt.PrDate === type) {
+ }
+ else if (c_oSerSdt.DataBinding === type) {
+ oSdtPr.DataBinding = new AscWord.DataBinding();
+ res = this.bcr.Read1(length, function(t, l) {
+ return oThis.ReadSdtPrDataBinding(t, l, oSdtPr.DataBinding);
+ });
+ }
+ else if (c_oSerSdt.PrDate === type) {
var datePicker = new AscWord.CSdtDatePickerPr();
res = this.bcr.Read1(length, function(t, l) {
return oThis.ReadSdtPrDate(t, l, datePicker);
@@ -13064,13 +13094,14 @@ function Binary_DocumentTableReader(doc, oReadResult, openParams, stream, curNot
};
this.ReadSdtPrDataBinding = function(type, length, val) {
var res = c_oSerConstants.ReadOk;
- var oThis = this;
if (c_oSerSdt.PrefixMappings === type) {
- val.PrefixMappings = this.stream.GetString2LE(length);
+ val.prefixMappings = this.stream.GetString2LE(length);
} else if (c_oSerSdt.StoreItemID === type) {
- val.StoreItemID = this.stream.GetString2LE(length);
+ val.storeItemID = this.stream.GetString2LE(length);
} else if (c_oSerSdt.XPath === type) {
- val.XPath = this.stream.GetString2LE(length);
+ val.xpath = this.stream.GetString2LE(length);
+ } else if (c_oSerSdt.StoreItemCheckSum === type) {
+ val.storeItemCheckSum = this.stream.GetString2LE(length)
} else {
res = c_oSerConstants.ReadUnknown;
}
@@ -16027,11 +16058,12 @@ function Binary_OtherTableReader(doc, oReadResult, stream)
return res;
};
};
-function Binary_CustomsTableReader(doc, oReadResult, stream, CustomXmls) {
+
+function Binary_CustomsTableReader(doc, oReadResult, stream) {
this.Document = doc;
this.oReadResult = oReadResult;
this.stream = stream;
- this.CustomXmls = CustomXmls;
+ this.customXmlManager = doc.getCustomXmlManager();
this.bcr = new Binary_CommonReader(this.stream);
this.Read = function() {
var oThis = this;
@@ -16043,11 +16075,14 @@ function Binary_CustomsTableReader(doc, oReadResult, stream, CustomXmls) {
var res = c_oSerConstants.ReadOk;
var oThis = this;
if (c_oSerCustoms.Custom === type) {
- var custom = {Uri: [], ItemId: null, Content: null};
+
+ var custom = new AscWord.CustomXml();
+
res = this.bcr.Read1(length, function(t, l) {
return oThis.ReadCustomContent(t, l, custom);
});
- this.CustomXmls.push(custom);
+
+ this.customXmlManager.add(custom);
}
else
res = c_oSerConstants.ReadUnknown;
@@ -16056,11 +16091,11 @@ function Binary_CustomsTableReader(doc, oReadResult, stream, CustomXmls) {
this.ReadCustomContent = function(type, length, custom) {
var res = c_oSerConstants.ReadOk;
if (c_oSerCustoms.Uri === type) {
- custom.Uri.push(this.stream.GetString2LE(length));
+ custom.uri.push(this.stream.GetString2LE(length));
} else if (c_oSerCustoms.ItemId === type) {
- custom.ItemId = this.stream.GetString2LE(length);
+ custom.itemId = this.stream.GetString2LE(length);
} else if (c_oSerCustoms.ContentA === type) {
- custom.Content = this.stream.GetBuffer(length);
+ custom.addContent(this.stream.GetBuffer(length))
} else
res = c_oSerConstants.ReadUnknown;
return res;
diff --git a/word/Editor/StructuredDocumentTags/BlockLevel.js b/word/Editor/StructuredDocumentTags/BlockLevel.js
index d690eb6bd5..24c8726033 100644
--- a/word/Editor/StructuredDocumentTags/BlockLevel.js
+++ b/word/Editor/StructuredDocumentTags/BlockLevel.js
@@ -562,6 +562,8 @@ CBlockLevelSdt.prototype.Remove = function(nCount, isRemoveWholeElement, bRemove
return true;
}
+ this.SetContentByDataBinding(this);
+
return bResult;
};
CBlockLevelSdt.prototype.Is_Empty = function()
@@ -594,6 +596,17 @@ CBlockLevelSdt.prototype.Add = function(oParaItem)
this.Content.AddToParagraph(oParaItem);
}
+ if (this.Pr.DataBinding)
+ {
+ var nContentPos = this.Content.CurPos.ContentPos;
+ var Item = this.Content.Content[nContentPos];
+
+ if (this.Pr.Text)
+ this.SetContentByDataBinding(Item.GetText());
+ else
+ this.SetContentByDataBinding(this)
+ }
+
if (isRemoveWrapper)
this.RemoveContentControlWrapper();
};
@@ -1462,6 +1475,9 @@ CBlockLevelSdt.prototype.SetPr = function(oPr)
if (undefined !== oPr.Color)
this.SetColor(oPr.Color);
+
+ if (undefined !== oPr.DataBinding)
+ this.setDataBinding(oPr.DataBinding);
};
/**
* Выставляем настройки текста по умолчанию для данного контрола
@@ -1559,6 +1575,60 @@ CBlockLevelSdt.prototype.SetColor = function(oColor)
this.Pr.Color = oColor;
}
};
+CBlockLevelSdt.prototype.fillContentWithDataBinding = function(content)
+{
+ let logicDocument = this.GetLogicDocument();
+
+ if (this.IsCheckBox())
+ {
+ let checkBoxPr = new AscWord.CSdtCheckBoxPr();
+
+ if (content === "true" || content === "1")
+ checkBoxPr.SetChecked(true);
+ else if (content === "false" || content === "0")
+ checkBoxPr.SetChecked(false);
+
+ this.SetCheckBoxPr(checkBoxPr)
+ }
+ else if (this.IsDatePicker())
+ {
+ let datePr = new AscWord.CSdtDatePickerPr();
+ datePr.SetFullDate(content);
+ this.SetDatePickerPr(datePr);
+ this.private_UpdateDatePickerContent();
+ }
+ else if (this.IsDropDownList() || this.IsComboBox() || this.Pr.Text === true)
+ {
+ let oRun = new ParaRun();
+ oRun.AddText(content);
+
+ // now style reset todo
+ this.Content.Remove_FromContent(0, this.Content.Content.length);
+ this.AddNewParagraph();
+ this.Content.AddText(content);
+ }
+ else
+ {
+ let oParent = this.Parent;
+ if (oParent instanceof CDocumentContent)
+ oParent = oParent.Parent
+
+ // if parent element is rich text content control - skip
+ if (oParent instanceof CBlockLevelSdt && oParent.GetSpecificType() === Asc.c_oAscContentControlSpecificType.None)
+ return;
+
+ let customXmlManager = logicDocument.getCustomXmlManager();
+ let arrContent = customXmlManager.proceedLinearXMl(content);
+
+ this.Content.RemoveFromContent(0, this.Content.Content.length);
+ this.Content.AddContent(arrContent);
+ this.Content.Recalculate(true);
+ }
+};
+CBlockLevelSdt.prototype.GetDataBinding = function ()
+{
+ return this.Pr.DataBinding;
+};
CBlockLevelSdt.prototype.GetColor = function()
{
return this.Pr.Color;
@@ -2011,6 +2081,8 @@ CBlockLevelSdt.prototype.private_UpdateCheckBoxContent = function()
oRun.SetRFontsCS({Index : -1, Name : this.Pr.CheckBox.UncheckedFont});
oRun.SetRFontsEastAsia({Index : -1, Name : this.Pr.CheckBox.UncheckedFont});
}
+
+ this.SetContentByDataBinding(isChecked ? "true" : "false");
};
/**
* Проверяем, является ли данный класс специальным контейнером для картинки
@@ -2276,6 +2348,8 @@ CBlockLevelSdt.prototype.SelectListItem = function(sValue)
oRun.AddText(sText);
}
}
+
+ this.SetContentByDataBinding(sText);
};
CBlockLevelSdt.prototype.private_UpdateListContent = function()
{
@@ -2420,6 +2494,16 @@ CBlockLevelSdt.prototype.private_UpdateDatePickerContent = function()
if (oRun)
oRun.AddText(sText);
+
+ this.SetContentByDataBinding(sText);
+};
+CBlockLevelSdt.prototype.SetContentByDataBinding = function (inputData)
+{
+ if (this.Pr.DataBinding)
+ {
+ let CustomManager = this.LogicDocument.getCustomXmlManager();
+ CustomManager.setContentByDataBinding(this.Pr.DataBinding, inputData);
+ }
};
CBlockLevelSdt.prototype.Document_Is_SelectionLocked = function(CheckType, bCheckInner)
{
diff --git a/word/Editor/StructuredDocumentTags/InlineLevel.js b/word/Editor/StructuredDocumentTags/InlineLevel.js
index 97b5e198a7..13617b6eec 100644
--- a/word/Editor/StructuredDocumentTags/InlineLevel.js
+++ b/word/Editor/StructuredDocumentTags/InlineLevel.js
@@ -150,6 +150,8 @@ CInlineLevelSdt.prototype.Add = function(Item)
oNextForm.SetThisElementCurrentInParagraph();
oNextForm.MoveCursorToStartPos();
}
+
+ this.SetContentByDataBinding(this.Pr.Text ? this.Content[0].GetText() : this);
if (!this.IsForm() && this.IsContentControlTemporary())
this.RemoveContentControlWrapper();
@@ -908,6 +910,8 @@ CInlineLevelSdt.prototype.Remove = function(nDirection, bOnAddText)
result = true;
}
+ this.SetContentByDataBinding(this.Content[0].GetText());
+
return result;
};
CInlineLevelSdt.prototype.Shift_Range = function(Dx, Dy, _CurLine, _CurRange, _CurPage)
@@ -1648,6 +1652,9 @@ CInlineLevelSdt.prototype.SetPr = function(oPr)
if(undefined !== oPr.OForm)
this.SetOForm(oPr.OForm);
+
+ if (undefined !== oPr.DataBinding)
+ this.setDataBinding(oPr.DataBinding);
};
/**
* Выставляем настройки текста по умолчанию для данного контрола
@@ -1990,6 +1997,7 @@ CInlineLevelSdt.prototype.ToggleCheckBox = function(isChecked)
return;
this.SetCheckBoxChecked(!this.Pr.CheckBox.Checked);
+ this.SetContentByDataBinding(this.Pr.CheckBox.Checked ? "true" : "false");
};
CInlineLevelSdt.prototype.SetCheckBoxChecked = function(isChecked)
{
@@ -2088,6 +2096,8 @@ CInlineLevelSdt.prototype.private_UpdateCheckBoxContent = function()
oRun.SetRFontsCS({Index : -1, Name : this.Pr.CheckBox.UncheckedFont});
oRun.SetRFontsEastAsia({Index : -1, Name : this.Pr.CheckBox.UncheckedFont});
}
+
+ this.SetContentByDataBinding(isChecked ? "true" : "false");
};
/**
* Проверяем, является ли данный класс специальным контейнером для картинки
@@ -2371,6 +2381,8 @@ CInlineLevelSdt.prototype.SelectListItem = function(sValue)
oRun.AddText(sText);
}
}
+
+ this.SetContentByDataBinding(sText);
};
CInlineLevelSdt.prototype.private_UpdateListContent = function()
{
@@ -2488,13 +2500,27 @@ CInlineLevelSdt.prototype.private_UpdateDatePickerContent = function()
if (oRun)
oRun.AddText(sText);
-
+
+ this.SetContentByDataBinding(sText);
+
if (isTemporary)
{
this.Pr.Temporary = true;
this.RemoveContentControlWrapper();
}
};
+CInlineLevelSdt.prototype.SetContentByDataBinding = function (inputData)
+{
+ if (this.Pr.DataBinding)
+ {
+ let oLogicDocument = this.GetParagraph().GetLogicDocument();
+ if (oLogicDocument)
+ {
+ let CustomManager = oLogicDocument.getCustomXmlManager();
+ CustomManager.setContentByDataBinding(this.Pr.DataBinding, inputData);
+ }
+ }
+};
/**
* Является ли данный контейнер специальной текстовой формой
* @returns {boolean}
@@ -3763,6 +3789,48 @@ CInlineLevelSdt.prototype.CorrectSingleLineFormContent = function()
}
}
};
+CInlineLevelSdt.prototype.fillContentWithDataBinding = function(content)
+{
+ let logicDocument = this.GetLogicDocument();
+
+ if (this.IsCheckBox())
+ {
+ let checkBoxPr = new AscWord.CSdtCheckBoxPr();
+
+ if (content === "true" || content === "1")
+ checkBoxPr.SetChecked(true);
+ else if (content === "false" || content === "0")
+ checkBoxPr.SetChecked(false);
+
+ this.SetCheckBoxPr(checkBoxPr)
+ }
+ else if (this.IsDatePicker())
+ {
+ let datePr = new AscWord.CSdtDatePickerPr();
+ datePr.SetFullDate(content);
+ this.SetDatePickerPr(datePr);
+ this.private_UpdateDatePickerContent();
+ }
+ else if (this.IsDropDownList() || this.IsComboBox())
+ {
+ this.ReplacePlaceHolderWithContent();
+ let oRun = this.private_UpdateListContent();
+ if (oRun)
+ oRun.AddText(content);
+ }
+ else if (this.Pr.Text === true)
+ {
+ return
+ }
+ else
+ {
+ let customXmlManager = logicDocument.getCustomXmlManager();
+ let arrContent = customXmlManager.proceedLinearXMl(content);
+
+ this.SetParagraph(arrContent[0]);
+ }
+};
+
//--------------------------------------------------------export--------------------------------------------------------
window['AscCommonWord'] = window['AscCommonWord'] || {};
diff --git a/word/Editor/StructuredDocumentTags/SdtBase.js b/word/Editor/StructuredDocumentTags/SdtBase.js
index 685ba535b5..9ab98f9202 100644
--- a/word/Editor/StructuredDocumentTags/SdtBase.js
+++ b/word/Editor/StructuredDocumentTags/SdtBase.js
@@ -1124,4 +1124,52 @@ CSdtBase.prototype.IsHideContentControlTrack = function()
return Asc.c_oAscSdtAppearance.Hidden === this.GetAppearance();
};
+CSdtBase.prototype.setDataBinding = function(dataBinding)
+{
+ AscCommon.History.Add(new CChangesSdtPrDataBinding(this, this.Pr.DataBinding, dataBinding));
+ this.Pr.DataBinding = dataBinding;
+};
+CSdtBase.prototype.getDataBinding = function()
+{
+ return this.Pr.DataBinding;
+};
+/**
+ * Проверяем, есть ли привязанные данные, и если есть заполняем ими содержимое контрола
+ */
+CSdtBase.prototype.checkDataBinding = function()
+{
+ let logicDocument = this.GetLogicDocument();
+ if (!logicDocument || !this.Pr.DataBinding)
+ return;
+
+ let content = logicDocument.getCustomXmlManager().getContentByDataBinding(this.Pr.DataBinding, this);
+ if (!content)
+ return;
+
+ if (this.IsPicture())
+ {
+ let allDrawings = this.GetAllDrawingObjects();
+ if (!allDrawings.length)
+ return;
+
+ let drawing = allDrawings[0];
+ let imageData = "data:image/jpeg;base64," + content;
+ let editor = logicDocument.GetApi();
+ editor.ImageLoader.LoadImagesWithCallback([imageData], function(){}, 0, true);
+
+ let w = drawing.getXfrmExtX();
+ let h = drawing.getXfrmExtY();
+
+ let imageShape = logicDocument.DrawingObjects.createImage(imageData, 0, 0, w, h);
+ imageShape.setParent(drawing);
+ drawing.Set_GraphicObject(imageShape);
+ }
+ else
+ {
+ this.fillContentWithDataBinding(content);
+ }
+};
+CSdtBase.prototype.fillContentWithDataBinding = function(content)
+{
+};
diff --git a/word/Editor/StructuredDocumentTags/SdtPr.js b/word/Editor/StructuredDocumentTags/SdtPr.js
index 0adbc4b9ca..5401e4ac53 100644
--- a/word/Editor/StructuredDocumentTags/SdtPr.js
+++ b/word/Editor/StructuredDocumentTags/SdtPr.js
@@ -39,6 +39,8 @@ function CSdtPr()
this.Tag = undefined;
this.Label = undefined;
this.Lock = undefined;
+
+ this.DataBinding = undefined;
this.DocPartObj = {
Gallery : undefined,
@@ -84,6 +86,9 @@ CSdtPr.prototype.Copy = function()
oPr.Appearance = this.Appearance;
oPr.Color = (this.Color ? this.Color.Copy() : undefined);
+ if (this.DataBinding)
+ oPr.DataBinding = this.DataBinding.copy();
+
if (this.CheckBox)
oPr.CheckBox = this.CheckBox.Copy();
@@ -263,6 +268,12 @@ CSdtPr.prototype.Write_ToBinary = function(Writer)
this.ComplexFormPr.WriteToBinary(Writer);
Flags |= (1 << 22);
}
+
+ if (this.DataBinding)
+ {
+ this.DataBinding.toBinary(Writer);
+ Flags |= (1 << 23);
+ }
var EndPos = Writer.GetCurPosition();
Writer.Seek(StartPos);
@@ -368,6 +379,9 @@ CSdtPr.prototype.Read_FromBinary = function(Reader)
this.ComplexFormPr = new AscWord.CSdtComplexFormPr();
this.ComplexFormPr.ReadFromBinary(Reader);
}
+
+ if (Flags & (1 << 23))
+ this.DataBinding = AscWord.DataBinding.fromBinary(Reader);
};
CSdtPr.prototype.IsBuiltInDocPart = function()
{
diff --git a/word/Editor/StructuredDocumentTags/SdtPrChanges.js b/word/Editor/StructuredDocumentTags/SdtPrChanges.js
index e2e237ad40..1e80f77d28 100644
--- a/word/Editor/StructuredDocumentTags/SdtPrChanges.js
+++ b/word/Editor/StructuredDocumentTags/SdtPrChanges.js
@@ -56,6 +56,8 @@ AscDFH.changesFactory[AscDFH.historyitem_SdtPr_TextForm] = CChangesSdtPr
AscDFH.changesFactory[AscDFH.historyitem_SdtPr_FormPr] = CChangesSdtPrFormPr;
AscDFH.changesFactory[AscDFH.historyitem_SdtPr_PictureFormPr] = CChangesSdtPrPictureFormPr;
AscDFH.changesFactory[AscDFH.historyitem_SdtPr_ComplexFormPr] = CChangesSdtPrComplexFormPr;
+AscDFH.changesFactory[AscDFH.historyitem_SdtPr_OForm] = CChangesSdtPrOForm;
+AscDFH.changesFactory[AscDFH.historyitem_SdtPr_DataBinding] = CChangesSdtPrDataBinding;
//----------------------------------------------------------------------------------------------------------------------
// Карта зависимости изменений
//----------------------------------------------------------------------------------------------------------------------
@@ -83,6 +85,9 @@ AscDFH.changesRelationMap[AscDFH.historyitem_SdtPr_Appearance] = [
AscDFH.changesRelationMap[AscDFH.historyitem_SdtPr_Color] = [
AscDFH.historyitem_SdtPr_Color
];
+AscDFH.changesRelationMap[AscDFH.historyitem_SdtPr_DataBinding] = [
+ AscDFH.historyitem_SdtPr_DataBinding
+];
AscDFH.changesRelationMap[AscDFH.historyitem_SdtPr_CheckBox] = [
AscDFH.historyitem_SdtPr_CheckBox,
AscDFH.historyitem_SdtPr_CheckBox_Checked
@@ -138,7 +143,7 @@ function private_SdtPrChangesCheckLock(lockData)
{
if (lockData && lockData.isFillingForm())
lockData.setLock(true);
-
+
if (this instanceof AscWord.CInlineLevelSdt)
private_ParagraphContentChangesCheckLock.apply(this, arguments);
}
@@ -427,6 +432,30 @@ CChangesSdtPrColor.prototype.IsNeedRecalculate = function()
return false;
};
CChangesSdtPrColor.prototype.CheckLock = private_SdtPrChangesCheckLock;
+/**
+ * @constructor
+ * @extends {AscDFH.CChangesBaseObjectProperty}
+ */
+function CChangesSdtPrDataBinding(Class, Old, New)
+{
+ AscDFH.CChangesBaseObjectProperty.call(this, Class, Old, New);
+}
+CChangesSdtPrDataBinding.prototype = Object.create(AscDFH.CChangesBaseObjectProperty.prototype);
+CChangesSdtPrDataBinding.prototype.constructor = CChangesSdtPrDataBinding;
+CChangesSdtPrDataBinding.prototype.Type = AscDFH.historyitem_SdtPr_DataBinding;
+CChangesSdtPrDataBinding.prototype.private_SetValue = function(Value)
+{
+ this.Class.Pr.DataBinding = Value;
+};
+CChangesSdtPrDataBinding.prototype.private_CreateObject = function()
+{
+ return new AscWord.DataBinding();
+};
+CChangesSdtPrDataBinding.prototype.IsNeedRecalculate = function()
+{
+ return true;
+};
+
/**
* @constructor
* @extends {AscDFH.CChangesBaseObjectProperty}
diff --git a/word/Editor/custom-xml/custom-xml-manager.js b/word/Editor/custom-xml/custom-xml-manager.js
new file mode 100644
index 0000000000..f0ffbfee2a
--- /dev/null
+++ b/word/Editor/custom-xml/custom-xml-manager.js
@@ -0,0 +1,413 @@
+/*
+ * (c) Copyright Ascensio System SIA 2010-2023
+ *
+ * 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)
+{
+ /**
+ * Класс представляющий менеджер CustomXMLs
+ * @param {AscWord.CDocument} document
+ * @constructor
+ */
+ function CustomXmlManager(document)
+ {
+ this.document = document;
+ this.xml = [];
+ this.saveCCs = [];
+ }
+ CustomXmlManager.prototype.add = function(customXml)
+ {
+ // TODO: Надо будет сделать этот метод с сохранением в историю, когда
+ // будем реализовывать возможность добавления таких xml во время работы
+ this.xml.push(customXml);
+ };
+ CustomXmlManager.prototype.getCount = function()
+ {
+ return this.xml.length;
+ };
+ CustomXmlManager.prototype.getCustomXml = function(index)
+ {
+ return this.xml[index];
+ };
+
+ /**
+ * Find element/attribute of CustomXMl by xpath string
+ * @param root {CustomXMLContent}
+ * @param xpath {string}
+ * @return {{attribute: string, content: CustomXMLContent}}
+ */
+ CustomXmlManager.prototype.findElementByXPath = function (root, xpath)
+ {
+ let arrParts = xpath.split('/');
+ let currentElement = root;
+
+ arrParts.shift(); // Убираем пустой первый элемент
+
+ for (let i = 0; i < arrParts.length; i++)
+ {
+ let namespaceAndTag,
+ index,
+ tagName,
+ part = arrParts[i];
+
+ if (part.includes("@"))
+ {
+ let strAttributeName = part.slice(1);
+ return {
+ content: currentElement,
+ attribute: strAttributeName,
+ };
+ }
+ else if (part.includes("["))
+ {
+ namespaceAndTag = part.split('[')[0];
+ let partBeforeCloseBracket = part.split(']')[0];
+ index = partBeforeCloseBracket.slice(-1) - 1;
+ }
+ else
+ {
+ namespaceAndTag = part;
+ index = 0;
+ }
+
+ tagName = namespaceAndTag.includes(":")
+ ? namespaceAndTag.split(':')[1]
+ : namespaceAndTag;
+
+ let matchingChildren = currentElement.content.filter(function (child) {
+ let arr = child.name.split(":");
+
+ if (arr.length > 1)
+ return arr[1] === tagName;
+ else
+ return arr[0] === tagName;
+ });
+
+ if (matchingChildren.length <= index)
+ break; // Элемент не найден
+
+ currentElement = matchingChildren[index];
+ }
+
+ return {
+ content: currentElement,
+ attribute: undefined,
+ };
+ };
+ /**
+ * Get custom xml data of content control by data binding property
+ * @param dataBinding {window.AscWord.DataBinding}
+ * @param oContentLink {CBlockLevelSdt | CInlineLevelSdt}
+ * @return {string | undefined}
+ */
+ CustomXmlManager.prototype.getContentByDataBinding = function(dataBinding, oContentLink)
+ {
+ for (let i = 0; i < this.xml.length; ++i)
+ {
+ let customXml = this.xml[i];
+ customXml.oContentLink = oContentLink;
+
+ if (dataBinding.storeItemID === customXml.itemId || customXml.checkUrl(dataBinding.prefixMappings))
+ {
+ let xPath = dataBinding.xpath;
+ let oFindEl = this.findElementByXPath(customXml.content, xPath);
+ let content = oFindEl.content;
+ let strAttribute = oFindEl.attribute;
+
+ return (undefined !== strAttribute)
+ ? content.attribute[strAttribute]
+ : content.textContent;
+ }
+ }
+ };
+ /**
+ * Set custom xml data of content control by data binding property
+ * @param {window.AscWord.DataBinding} dataBinding
+ * @param data {string | CBlockLevelSdt}
+ */
+ CustomXmlManager.prototype.setContentByDataBinding = function (dataBinding, data)
+ {
+ for (let i = 0; i < this.xml.length; ++i)
+ {
+ let customXml = this.xml[i];
+
+ if (dataBinding.storeItemID === customXml.itemId)
+ {
+ let xPath = dataBinding.xpath;
+ let oFindEl = this.findElementByXPath(customXml.content, xPath);
+ let oContent = oFindEl.content;
+ let strAttribute = oFindEl.attribute;
+
+ if (data instanceof AscCommonWord.CBlockLevelSdt)
+ {
+ // recording changes every time a control with formatted text changes is not efficient
+ // save which control needs to be processed, and update CustomXML field for rich text when save document
+ if (!this.saveCCs.includes(data))
+ this.saveCCs.push(data);
+
+ return;
+ }
+
+ if (strAttribute)
+ oContent.setAttribute(strAttribute, data);
+ else
+ oContent.setTextContent(data);
+ }
+ }
+ };
+ /**
+ * Write linear xml data of content control in CustomXML
+ * @param oCC {CBlockLevelSdt}
+ */
+ CustomXmlManager.prototype.updateRichTextCustomXML = function (oCC)
+ {
+ function replaceSubstring(originalString, startPoint, endPoint, insertionString)
+ {
+ if (startPoint < 0 || endPoint >= originalString.length || startPoint > endPoint)
+ return originalString;
+
+ const prefix = originalString.substring(0, startPoint);
+ const suffix = originalString.substring(endPoint + 1);
+
+ return prefix + insertionString + suffix;
+ }
+
+ AscFormat.ExecuteNoHistory(function() {
+ let doc = new AscWord.CDocument(null, false);
+ let oSdtContent = oCC.GetContent().Copy();
+ let jsZlib = new AscCommon.ZLib();
+
+ doc.ReplaceContent(oSdtContent.Content);
+ jsZlib.create();
+ doc.toZip(jsZlib, new AscCommon.XmlWriterContext(AscCommon.c_oEditorId.Word));
+
+ let openDoc = new AscCommon.openXml.OpenXmlPackage(jsZlib, null);
+ let outputUString = "";
+ let arrPath = jsZlib.getPaths();
+
+ arrPath.forEach(function(path)
+ {
+ if ((path === "_rels/.rels" || path === "word/document.xml" || path === "word/_rels/document.xml.rels") && !path.includes("glossary"))
+ {
+ let ctfBytes = jsZlib.getFile(path);
+ let ctfText = AscCommon.UTF8ArrayToString(ctfBytes, 0, ctfBytes.length);
+ let type = openDoc.getContentType(path);
+
+ if (path === "word/_rels/document.xml.rels")
+ {
+ let text = '';
+ let arrRelationships = openDoc.getRelationships();
+
+ for (let i = 0; i < arrRelationships.length; i++)
+ {
+ let relation = arrRelationships[i];
+ let relId = relation.relationshipId;
+ let relType = relation.relationshipType;
+ let relTarget = relation.target;
+
+ if (i === 0)
+ {
+ relType = relType.replace("relationships\/officeDocument", "relationships\/styles");
+ relTarget = relTarget.replace("word/document.xml", "styles.xml");
+ }
+
+ text += ""
+ }
+
+ let nStart = ctfText.indexOf("", 0) + "".length;
+ let nEnd = ctfText.indexOf("", nStart) - 1;
+ ctfText = replaceSubstring(ctfText, nStart, nEnd, text);
+ }
+
+ outputUString += " " +
+ "" + ctfText.replace("", "").replace("\n", "") + ""
+ }
+ });
+
+ outputUString = outputUString.replace("pkg:contentType=\"application/xml\"", "pkg:contentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml\"");
+ outputUString += "";
+ outputUString = outputUString.replaceAll("<", "<");
+ outputUString = outputUString.replaceAll(">", ">");
+ this.setContentByDataBinding(oCC.Pr.DataBinding, outputUString);
+ }, this, []);
+ };
+ /**
+ * Proceed linear xml from CustomXMl attribute or element for fill content control
+ * @param strLinearXML {string}
+ * @return {[]} Return array of CC content
+ */
+ CustomXmlManager.prototype.proceedLinearXMl = function (strLinearXML)
+ {
+ strLinearXML = strLinearXML.replaceAll("<", "<");
+ strLinearXML = strLinearXML.replaceAll(">", ">");
+ strLinearXML = strLinearXML.replaceAll("", "");
+ strLinearXML = strLinearXML.replaceAll("", "");
+
+ // при записи в атрибут больше проблем, изменить подход если в будущем еще будут проблемы c html entry
+ strLinearXML = strLinearXML.replaceAll("
", "");
+ strLinearXML = strLinearXML.replaceAll("&", "&");
+ strLinearXML = strLinearXML.replaceAll(""", "\"");
+ strLinearXML = strLinearXML.replaceAll("'", "'");
+
+ let zLib = new AscCommon.ZLib;
+ zLib.create();
+ zLib.addFile('[Content_Types].xml', new TextEncoder("utf-8").encode('' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ ''));
+
+ let nPos = 0;
+ while (true)
+ {
+ let nStartPos = nPos = strLinearXML.indexOf('', nStartPos);
+ let strText = strLinearXML.substring(nStartPos, nEndPos);
+
+ let nPosStartName = strText.indexOf('name="', 0) + 'name="'.length;
+ let nPosEndName = strText.indexOf('"', nPosStartName);
+ let name = strText.substring(nPosStartName, nPosEndName);
+
+ let nDataStartPos = strText.indexOf('', 0);
+ let nDataEndPos;
+
+ if (nDataStartPos !== -1)
+ {
+ nDataStartPos = nDataStartPos + ''.length;
+ nDataEndPos = strText.indexOf('', nDataStartPos);
+ }
+ else
+ {
+ nDataStartPos = strText.indexOf('', 0);
+ if (nDataStartPos !== -1)
+ nDataStartPos += ''.length;
+ nDataEndPos = strText.indexOf('', nDataStartPos);
+ }
+
+ if (nStartPos === -1 || nEndPos === -1)
+ continue;
+
+ let data = strText.substring(nDataStartPos, nDataEndPos).trim();
+
+ if (name[0] === "/")
+ name = name.substring(1, name.length);
+
+ zLib.addFile(name, new TextEncoder("utf-8").encode(data));
+ }
+
+ let arr = zLib.save();
+ let draw = this.document.DrawingDocument;
+ let Doc = new CDocument(draw, false);
+ let xmlParserContext = new AscCommon.XmlParserContext();
+ let jsZlib = new AscCommon.ZLib();
+
+ xmlParserContext.DrawingDocument = draw;
+
+ if (!jsZlib.open(arr))
+ return [];
+
+ let oBinaryFileReader = new AscCommonWord.BinaryFileReader(Doc, {});
+ oBinaryFileReader.PreLoadPrepare();
+
+ Doc.fromZip(jsZlib, xmlParserContext, oBinaryFileReader.oReadResult);
+
+ oBinaryFileReader.PostLoadPrepare(xmlParserContext);
+ jsZlib.close();
+
+ return Doc.Content;
+ };
+ /**
+ * Get CustomXML text
+ * @param oCustomXMl {AscWord.CustomXml}
+ * @return {string}
+ */
+ CustomXmlManager.prototype.getCustomXMLString = function(oCustomXMl)
+ {
+ this.updateCustomXMlFromRichTextCCs();
+ return oCustomXMl.getText();
+ };
+ /**
+ * Go through all edited rich text content controls and save it's content in CustomXML
+ */
+ CustomXmlManager.prototype.updateCustomXMlFromRichTextCCs = function ()
+ {
+ for (let i = 0; i < this.saveCCs.length; i++)
+ {
+ this.updateRichTextCustomXML(this.saveCCs[i]);
+ }
+ };
+
+ //--------------------------------------------------------export----------------------------------------------------
+ window['AscWord'] = window['AscWord'] || {};
+ window['AscWord'].CustomXmlManager = CustomXmlManager;
+
+})(window);
diff --git a/word/Editor/custom-xml/custom-xml.js b/word/Editor/custom-xml/custom-xml.js
new file mode 100644
index 0000000000..98ed20c2be
--- /dev/null
+++ b/word/Editor/custom-xml/custom-xml.js
@@ -0,0 +1,231 @@
+/*
+ * (c) Copyright Ascensio System SIA 2010-2023
+ *
+ * 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)
+{
+ /**
+ * @param {array} [uri]
+ * @param {string} [itemId]
+ * @param {CustomXMLContent} [content]
+ * @param [oContentLink]
+ *
+ * Класс представляющий CustomXML
+ * @constructor
+ */
+ function CustomXml(uri, itemId, content, oContentLink)
+ {
+ this.uri = uri ? uri : [];
+ this.itemId = itemId ? itemId : "";
+ this.content = content ? content : null;
+ this.oContentLink = oContentLink ? oContentLink : null;
+ }
+
+ /**
+ * Get CustomXML data by string
+ * @return {string}
+ */
+ CustomXml.prototype.getText = function ()
+ {
+ return this.content.getStringFromBuffer();
+ };
+ /**
+ * Find url in uri array
+ * @return {boolean}
+ */
+ CustomXml.prototype.checkUrl = function (str)
+ {
+ if (!str)
+ return false;
+
+ for (let i = 0; i < this.uri.length; i++)
+ {
+ if (str.includes(this.uri[i]))
+ return true;
+ }
+ return false;
+ }
+ /**
+ * Add content of CustomXML
+ * @param arrData {array}
+ */
+ CustomXml.prototype.addContent = function (arrData)
+ {
+ let strContent = "".fromUtf8(arrData),
+ strCustomXml = strContent.slice(strContent.indexOf("<"), strContent.length); // Skip "L"
+
+ this.addContentByXMLString(strCustomXml);
+ };
+ CustomXml.prototype.addContentByXMLString = function (strCustomXml)
+ {
+ let oStax = new StaxParser(strCustomXml),
+ rootContent = new CustomXMLContent(null);
+
+ while (oStax.Read())
+ {
+ switch (oStax.GetEventType()) {
+ case EasySAXEvent.CHARACTERS:
+ rootContent.addTextContent(oStax.text);
+ break;
+ case EasySAXEvent.END_ELEMENT:
+ rootContent = rootContent.getParent();
+ break;
+ case EasySAXEvent.START_ELEMENT:
+ let name = oStax.GetName();
+ let childElement = rootContent.addContent(name);
+
+ while (oStax.MoveToNextAttribute())
+ {
+ let attributeName = oStax.GetName();
+ let attributeValue = oStax.GetValue();
+ childElement.addAttribute(attributeName, attributeValue);
+ }
+
+ rootContent = childElement;
+ break;
+ }
+ }
+
+ this.content = rootContent;
+ }
+
+ function CustomXMLContent(parent, name)
+ {
+ this.parent = parent;
+ this.name = name ? name : "";
+ this.content = [];
+ this.attribute = {};
+ this.textContent = "";
+
+ this.addAttribute = function (name, value)
+ {
+ this.attribute[name] = value;
+ };
+ this.addContent = function (name)
+ {
+ let newItem = new CustomXMLContent(this, name);
+
+ this.content.push(newItem);
+ return newItem;
+ };
+ this.getParent = function ()
+ {
+ if (this.parent)
+ return this.parent;
+
+ return null;
+ };
+ this.addTextContent = function (text)
+ {
+ if (text !== "")
+ this.textContent += text;
+ };
+ this.setTextContent = function (str)
+ {
+ this.textContent = str;
+ };
+ this.setAttribute = function (attribute, value)
+ {
+ this.attribute[attribute] = value;
+ };
+ this.getBuffer = function ()
+ {
+ let writer = new AscCommon.CMemory();
+ let nTab = 0;
+
+ function Write(content)
+ {
+ let current = null;
+
+ if (!content.name)
+ {
+ writer.WriteXmlString("\x00\n");
+ current = content.content[0];
+ }
+ else
+ {
+ current = content;
+ }
+
+ for (let i = 0; i < nTab; i++)
+ {
+ writer.WriteXmlString(" ");
+ }
+
+ writer.WriteXmlNodeStart(current.name);
+
+ let atr = Object.keys(current.attribute)
+
+ for (let i = 0; i < atr.length; i++)
+ {
+ let cur = atr[i];
+ writer.WriteXmlAttributeStringEncode(cur, current.attribute[cur]);
+ }
+
+ writer.WriteXmlAttributesEnd();
+
+ for (let i = 0; i < current.content.length; i++)
+ {
+ nTab++;
+ if (i === 0)
+ writer.WriteXmlString("\n");
+ let curContent = current.content[i];
+ Write(curContent);
+ nTab--;
+ writer.WriteXmlString("\n");
+ }
+
+ if (current.textContent)
+ writer.WriteXmlString(current.textContent.toString().trim());
+
+ writer.WriteXmlNodeEnd(current.name);
+ }
+
+ Write(this);
+ return writer;
+ };
+ this.getStringFromBuffer = function ()
+ {
+ let buffer = this.getBuffer();
+ let str = AscCommon.UTF8ArrayToString(buffer.data, 1);
+ str = str.replaceAll(""", "\"");
+ str = str.replaceAll("&", "&");
+ return str;
+ };
+ }
+
+ //--------------------------------------------------------export----------------------------------------------------
+ window['AscWord'] = window['AscWord'] || {};
+ window['AscWord'].CustomXml = CustomXml;
+
+})(window);
diff --git a/word/Editor/custom-xml/data-binding.js b/word/Editor/custom-xml/data-binding.js
new file mode 100644
index 0000000000..fbb4e2df41
--- /dev/null
+++ b/word/Editor/custom-xml/data-binding.js
@@ -0,0 +1,108 @@
+/*
+ * (c) Copyright Ascensio System SIA 2010-2023
+ *
+ * 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)
+{
+ /**
+ * @constructor
+ */
+ function DataBinding(prefix, itemID, xpath, checkSum)
+ {
+ this.prefixMappings = prefix ? prefix : undefined;
+ this.storeItemID = itemID ? itemID : undefined;
+ this.xpath = xpath ? xpath : undefined;
+ this.storeItemCheckSum = checkSum ? checkSum : undefined;
+ }
+ DataBinding.prototype.copy = function()
+ {
+ return new DataBinding(this.prefixMappings, this.storeItemID, this.xpath, this.storeItemCheckSum);
+ };
+ DataBinding.prototype.recalculateCheckSum = function (stringOfCustomXMlContent)
+ {
+ };
+ DataBinding.prototype.toBinary = function(writer)
+ {
+ return this.Write_ToBinary(writer);
+ };
+ DataBinding.fromBinary = function(reader)
+ {
+ let data = new DataBinding();
+ data.Read_FromBinary(reader);
+ return data;
+ };
+ DataBinding.prototype.Write_ToBinary = function(writer)
+ {
+ let startPos = writer.GetCurPosition();
+ writer.Skip(4);
+ let flags = 0;
+
+ if (undefined !== this.prefixMappings)
+ {
+ writer.WriteString2(this.prefixMappings);
+ flags |= 1;
+ }
+
+ if (undefined !== this.storeItemID)
+ {
+ writer.WriteLong(this.storeItemID);
+ flags |= 2;
+ }
+
+ if (undefined !== this.xpath)
+ {
+ writer.WriteString2(this.xpath);
+ flags |= 4;
+ }
+
+ let endPos = startPos.GetCurPosition();
+ writer.Seek(startPos);
+ writer.WriteLong(flags);
+ writer.Seek(endPos);
+ };
+ DataBinding.prototype.Read_FromBinary = function(reader)
+ {
+ let flags = reader.GetLong();
+ if (flags & 1)
+ this.prefixMappings = reader.GetString2();
+ if (flags & 2)
+ this.storeItemID = reader.GetString2();
+ if (flags & 4)
+ this.xpath = reader.GetString2();
+ };
+
+ //--------------------------------------------------------export----------------------------------------------------
+ window['AscWord'] = window['AscWord'] || {};
+ window['AscWord'].DataBinding = DataBinding;
+
+})(window);
diff --git a/word/api.js b/word/api.js
index b42913d1d7..7771edfac8 100644
--- a/word/api.js
+++ b/word/api.js
@@ -10749,6 +10749,12 @@ background-repeat: no-repeat;\
oApi.WordControl.m_oLogicDocument.SetImageProps(oImagePr);
oCC.SetShowingPlcHdr(false);
+ if (oCC.Pr.DataBinding)
+ {
+ let CustomManager = oApi.WordControl.m_oLogicDocument.getCustomXmlManager();
+ CustomManager.setContentByDataBinding(oCC.Pr.DataBinding, oDrawingObjects.selectedObjects[0].getPictureBase64Data().ImageUrl.replace("data:image/png;base64,", ""));
+ }
+
if (oCC.IsPictureForm())
{
oCC.UpdatePictureFormLayout();