From 773facf88ab1e51baf24ecf5201786d0b40478ce Mon Sep 17 00:00:00 2001 From: EvgeniyIgol Date: Wed, 23 Aug 2023 16:18:11 +0300 Subject: [PATCH 01/22] Add CustomXML processing - add basic dataBinding set for CBlockLevelSdt --- word/Editor/Document.js | 42 ++++ word/Editor/Serialize2.js | 231 +++++++++++++++++- .../StructuredDocumentTags/BlockLevel.js | 37 +++ word/Editor/StructuredDocumentTags/SdtPr.js | 4 + .../StructuredDocumentTags/SdtPrChanges.js | 30 +++ 5 files changed, 335 insertions(+), 9 deletions(-) diff --git a/word/Editor/Document.js b/word/Editor/Document.js index aeb9c7631e..6397ae5fe4 100644 --- a/word/Editor/Document.js +++ b/word/Editor/Document.js @@ -27137,6 +27137,48 @@ CDocument.prototype.IsCheckFormPlaceholder = function() return this.CheckFormPlaceHolder; }; +CDocument.prototype.FindInCustomXML = function(oDataBindings) +{ + for (let i = 0; i < this.CustomXmls.length; i++) + { + let oCurCustomXml = this.CustomXmls[i]; + + // этот атрибут может быть опущен, так искать плохо + if (oDataBindings.StoreItemID === oCurCustomXml.ItemId) + { + let xPath = oDataBindings.XPath; + + function findElementsByXPath(root, xpath) { + var parts = xpath.split('/'); + parts.shift(); // Убираем пустой первый элемент + + var currentElement = root; + + for (var i = 0; i < parts.length; i++) { + var part = parts[i]; + var namespaceAndTag = part.split('[')[0]; + var index = parseInt(part.split('[')[1].slice(0, -1)) - 1; + var tagName = namespaceAndTag.split(':')[1]; + + var matchingChildren = currentElement.children.filter(function (child) { + return child.tagName.split(":")[1] === tagName; + }); + + if (matchingChildren.length <= index) { + return null; // Элемент не найден + } + + currentElement = matchingChildren[index]; + } + + return currentElement.textContent; + } + + return findElementsByXPath(oCurCustomXml.Content, xPath); + } + } +} + function CDocumentSelectionState() { this.Id = null; diff --git a/word/Editor/Serialize2.js b/word/Editor/Serialize2.js index 1bf523ee3d..79d6f83158 100644 --- a/word/Editor/Serialize2.js +++ b/word/Editor/Serialize2.js @@ -12960,21 +12960,22 @@ function Binary_DocumentTableReader(doc, oReadResult, openParams, stream, curNot oSdtContentReader.oCurComments = this.oCurComments; oSdtContentReader.Read(length, oSdtContent); this.nCurCommentsCount = oSdtContentReader.nCurCommentsCount; - if (oSdtContent.length > 0) { - oSdt.Content.ReplaceContent(oSdtContent); - } + oSdt.SetContent(oSdtContent.length > 0 ? oSdtContent : []); } else if (1 === typeContainer) { res = this.bcr.Read1(length, function(t, l) { return oThis.ReadParagraphContent(t, l, container); }); + oSdt.SetContent() } else if (2 === typeContainer) { res = this.bcr.Read1(length, function(t, l) { return oThis.Read_TableContent(t, l, container); }); + oSdt.SetContent() } else if (3 === typeContainer) { res = this.bcr.Read1(length, function(t, l) { return oThis.ReadRowContent(t, l, container); }); + oSdt.SetContent() } } else { res = c_oSerConstants.ReadUnknown; @@ -13012,12 +13013,15 @@ 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 = {}; + 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); @@ -16109,6 +16113,212 @@ function Binary_OtherTableReader(doc, oReadResult, stream) return res; }; }; + +function parseBinaryXML(binaryArray) { + binaryArray = new Uint8Array(binaryArray); + let currentIndex = 0; + + function parseTextContent() { + let textContent = ""; + let nStart = currentIndex; + + while (binaryArray[currentIndex] !== 60) { // Знак "<" означает начало нового тега + currentIndex++; + } + + return new TextDecoder().decode(binaryArray.slice(nStart, currentIndex)); + } + + function parseTag() + { + const startTag = binaryArray.indexOf(60, currentIndex); // < + let endTag = binaryArray.indexOf(32, startTag); // " " + let nEndTag = binaryArray.indexOf(62, startTag); // > + let nETag = binaryArray.indexOf(47, startTag); // / + + let isClose = false; + + if (nEndTag < endTag) + endTag = nEndTag; + + if (nETag < endTag) + endTag = nETag; + + if (startTag === -1 || endTag === -1) { + return null; + } + + const tagName = new TextDecoder().decode(binaryArray.slice(startTag + 1, endTag)); + + currentIndex = endTag; + + return tagName; + } + + function parseAttributes() { + if (binaryArray[currentIndex] === 62) + return {}; + const attributes = {}; + + while ( + binaryArray[currentIndex] === 9 || + binaryArray[currentIndex] === 10 || // символ перехода на новую строку + binaryArray[currentIndex] === 13 || // символ возврата каретки + binaryArray[currentIndex] === 32 + ) { + currentIndex++; + } + + while (binaryArray[currentIndex] !== 62 && binaryArray[currentIndex] !== 47 && binaryArray[currentIndex] !== 63) { + const attributeNameStart = currentIndex; + while (binaryArray[currentIndex] !== 32 && binaryArray[currentIndex] !== 9 && binaryArray[currentIndex] !== 61) { + currentIndex++; + } + + const attributeName = new TextDecoder().decode(binaryArray.slice(attributeNameStart, currentIndex)); + + while (binaryArray[currentIndex] !== 34) { + currentIndex++; + } + currentIndex++; // пропускаем кавычку + + const attributeValueStart = currentIndex; + while (binaryArray[currentIndex] !== 34) { + currentIndex++; + } + + const attributeValue = new TextDecoder().decode(binaryArray.slice(attributeValueStart, currentIndex)); + + attributes[attributeName] = attributeValue; + currentIndex++; // пропускаем кавычку и пробел + + // Пропускаем символы перехода на новую строку и табуляции + while ( + binaryArray[currentIndex] === 10 || + binaryArray[currentIndex] === 13 || + binaryArray[currentIndex] === 9 || + binaryArray[currentIndex] === 32 + ) { + currentIndex++; + } + } + + return attributes; + } + + + function parseElement() { + const tagName = parseTag(); + let textContent = ""; + + if (!tagName) + return null; + + const attributes = parseAttributes(); + const children = []; + + while ( + binaryArray[currentIndex] === 9 || + binaryArray[currentIndex] === 10 || // символ перехода на новую строку + binaryArray[currentIndex] === 13 || // символ возврата каретки + binaryArray[currentIndex] === 32 + ) { + currentIndex++; + } + + if (binaryArray[currentIndex] === 47 && binaryArray[currentIndex+1] === 62) + { + currentIndex++; + currentIndex++; + return { + tagName: tagName, + attributes: attributes, + children: children, + textContent: textContent, + }; + } + + if (binaryArray[currentIndex] === 63 && binaryArray[currentIndex + 1] === 62) + { + currentIndex++; + currentIndex++; + return { + tagName: tagName, + attributes: attributes, + children: [parseElement()], + textContent: textContent, + }; + } + + if (binaryArray[currentIndex] === 62) + { + currentIndex++; + + while ( + binaryArray[currentIndex] === 9 || + binaryArray[currentIndex] === 10 || // символ перехода на новую строку + binaryArray[currentIndex] === 13 || // символ возврата каретки + binaryArray[currentIndex] === 32 + ) { + currentIndex++; + } + + if (binaryArray[currentIndex] !== 60) + { + textContent = parseTextContent(); + currentIndex += 2; // пропускаем + } + else + { + while (currentIndex < binaryArray.length) + { + if (binaryArray[currentIndex] === 60 && binaryArray[currentIndex + 1] !== 47) + { + const child = parseElement(); + if (child) + { + children.push(child); + } + } + else if (binaryArray[currentIndex] === 60 && binaryArray[currentIndex + 1] === 47) + { + currentIndex += 2; // пропускаем + break; + } + else + { + // Пропускаем символы перехода на новую строку и табуляции + if (binaryArray[currentIndex] !== 10 && binaryArray[currentIndex] !== 9) + { + currentIndex++; + } + else + { + currentIndex++; + while (binaryArray[currentIndex] === 10 || binaryArray[currentIndex] === 9) + { + currentIndex++; + } + } + } + } + } + } + + return { + tagName: tagName, + attributes: attributes, + children: children, + textContent: textContent, + }; + } + + return parseElement(); +} function Binary_CustomsTableReader(doc, oReadResult, stream, CustomXmls) { this.Document = doc; this.oReadResult = oReadResult; @@ -16129,6 +16339,9 @@ function Binary_CustomsTableReader(doc, oReadResult, stream, CustomXmls) { res = this.bcr.Read1(length, function(t, l) { return oThis.ReadCustomContent(t, l, custom); }); + + custom.Content = parseBinaryXML(custom.Content); + this.CustomXmls.push(custom); } else diff --git a/word/Editor/StructuredDocumentTags/BlockLevel.js b/word/Editor/StructuredDocumentTags/BlockLevel.js index 644cc52a69..7426d9df5a 100644 --- a/word/Editor/StructuredDocumentTags/BlockLevel.js +++ b/word/Editor/StructuredDocumentTags/BlockLevel.js @@ -1452,6 +1452,9 @@ CBlockLevelSdt.prototype.SetPr = function(oPr) if (undefined !== oPr.Color) this.SetColor(oPr.Color); + + if (undefined !== oPr.DataBinding) + this.SetDataBinding(oPr.DataBinding); }; /** * Выставляем настройки текста по умолчанию для данного контрола @@ -1549,6 +1552,40 @@ CBlockLevelSdt.prototype.SetColor = function(oColor) this.Pr.Color = oColor; } }; +CBlockLevelSdt.prototype.SetDataBinding = function (oDataBinding) +{ + History.Add(new CChangesSdtPrDataBinding(this, this.Pr.oDataBinding, oDataBinding)); + this.Pr.DataBinding = oDataBinding; +}; +CBlockLevelSdt.prototype.SetContent = function (oContent) +{ + if (this.Pr.DataBinding) + { + this.SetContentFromDataBindings() + } + else + { + this.Content.ReplaceContent(oContent); + } + +} +CBlockLevelSdt.prototype.SetContentFromDataBindings = function () +{ + if (!this.Pr.DataBinding) + return; + + let oTextContent = this.LogicDocument.FindInCustomXML(this.Pr.DataBinding); + let oParagraph = new Paragraph(this.LogicDocument.DrawingDocument); + let oParaRun = new ParaRun(oParagraph); + oParaRun.AddText(oTextContent); + oParagraph.Add_ToContent(0, oParaRun); + this.Content.Remove_FromContent(0, 1, false); + this.Content.ReplaceContent([oParagraph]); +} +CBlockLevelSdt.prototype.GetDataBinding = function () +{ + return this.Pr.DataBinding; +}; CBlockLevelSdt.prototype.GetColor = function() { return this.Pr.Color; diff --git a/word/Editor/StructuredDocumentTags/SdtPr.js b/word/Editor/StructuredDocumentTags/SdtPr.js index 9c84555096..158cc0549c 100644 --- a/word/Editor/StructuredDocumentTags/SdtPr.js +++ b/word/Editor/StructuredDocumentTags/SdtPr.js @@ -44,6 +44,7 @@ function CSdtPr() this.Tag = undefined; this.Label = undefined; this.Lock = undefined; + this.DataBinding = undefined; this.DocPartObj = { Gallery : undefined, @@ -89,6 +90,9 @@ CSdtPr.prototype.Copy = function() oPr.Appearance = this.Appearance; oPr.Color = (this.Color ? this.Color.Copy() : undefined); + if (this.DataBinding) + oPr.DataBinding = this.DataBinding; + if (this.CheckBox) oPr.CheckBox = this.CheckBox.Copy(); diff --git a/word/Editor/StructuredDocumentTags/SdtPrChanges.js b/word/Editor/StructuredDocumentTags/SdtPrChanges.js index dddced7738..6358aaf92e 100644 --- a/word/Editor/StructuredDocumentTags/SdtPrChanges.js +++ b/word/Editor/StructuredDocumentTags/SdtPrChanges.js @@ -45,6 +45,7 @@ AscDFH.changesFactory[AscDFH.historyitem_SdtPr_Lock] = CChangesSdtPr AscDFH.changesFactory[AscDFH.historyitem_SdtPr_DocPartObj] = CChangesSdtPrDocPartObj; AscDFH.changesFactory[AscDFH.historyitem_SdtPr_Appearance] = CChangesSdtPrAppearance; AscDFH.changesFactory[AscDFH.historyitem_SdtPr_Color] = CChangesSdtPrColor; +AscDFH.changesFactory[AscDFH.historyitem_SdtPr_DataBinding] = CChangesSdtPrDataBinding; AscDFH.changesFactory[AscDFH.historyitem_SdtPr_CheckBox] = CChangesSdtPrCheckBox; AscDFH.changesFactory[AscDFH.historyitem_SdtPr_CheckBox_Checked] = CChangesSdtPrCheckBoxChecked; AscDFH.changesFactory[AscDFH.historyitem_SdtPr_Picture] = CChangesSdtPrPicture; @@ -88,6 +89,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 @@ -415,6 +419,32 @@ CChangesSdtPrColor.prototype.IsNeedRecalculate = function() { return false; }; + +/** + * @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 {}; +}; +CChangesSdtPrDataBinding.prototype.IsNeedRecalculate = function() +{ + return false; +}; + + /** * @constructor * @extends {AscDFH.CChangesBaseObjectProperty} From 6f3bf788abfb95ee2a55ee08b1972dfb715f641d Mon Sep 17 00:00:00 2001 From: EvgeniyIgol Date: Thu, 31 Aug 2023 16:06:28 +0300 Subject: [PATCH 02/22] Add ability to read/write CustomXML for simple text --- word/Editor/Document.js | 61 ++- word/Editor/Serialize2.js | 362 +++++++----------- .../StructuredDocumentTags/BlockLevel.js | 25 +- .../StructuredDocumentTags/InlineLevel.js | 56 +++ 4 files changed, 284 insertions(+), 220 deletions(-) diff --git a/word/Editor/Document.js b/word/Editor/Document.js index 6397ae5fe4..81b91100d9 100644 --- a/word/Editor/Document.js +++ b/word/Editor/Document.js @@ -27136,7 +27136,55 @@ CDocument.prototype.IsCheckFormPlaceholder = function() return this.CheckFormPlaceHolder; }; +CDocument.prototype.WriteCustomXML = function(oDataBindings, ContentToWrite) +{ + for (let i = 0; i < this.CustomXmls.length; i++) + { + let oCurCustomXml = this.CustomXmls[i]; + + if (oDataBindings.StoreItemID === oCurCustomXml.ItemId) + { + let xPath = oDataBindings.XPath; + + function findElementsByXPath(root, xpath) { + var parts = xpath.split('/'); + parts.shift(); // Убираем пустой первый элемент + var currentElement = root; + + for (var i = 0; i < parts.length; i++) { + var part = parts[i]; + var namespaceAndTag = part.split('[')[0]; + var index = parseInt(part.split('[')[1].slice(0, -1)) - 1; + var tagName = namespaceAndTag.split(':')[1]; + + var 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) { + return null; // Элемент не найден + } + + currentElement = matchingChildren[index]; + } + + return currentElement.textContent = ContentToWrite; + } + + return findElementsByXPath(oCurCustomXml.Content, xPath); + } + } +} CDocument.prototype.FindInCustomXML = function(oDataBindings) { for (let i = 0; i < this.CustomXmls.length; i++) @@ -27160,8 +27208,17 @@ CDocument.prototype.FindInCustomXML = function(oDataBindings) var index = parseInt(part.split('[')[1].slice(0, -1)) - 1; var tagName = namespaceAndTag.split(':')[1]; - var matchingChildren = currentElement.children.filter(function (child) { - return child.tagName.split(":")[1] === tagName; + var 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) { diff --git a/word/Editor/Serialize2.js b/word/Editor/Serialize2.js index 79d6f83158..9546c09b10 100644 --- a/word/Editor/Serialize2.js +++ b/word/Editor/Serialize2.js @@ -6491,12 +6491,23 @@ 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 (oSdt.Pr.DataBinding) + { + this.Document.WriteCustomXML(oSdt.Pr.DataBinding, oSdt.Content.Content[0].GetText()); + } + + 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) { @@ -6514,9 +6525,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);}); // } @@ -7544,8 +7555,10 @@ function BinaryCustomsTableWriter(memory, doc, CustomXmls) }); } if (null !== customXml.Content) { + let mem = this.bs.memory; this.bs.WriteItem(c_oSerCustoms.ContentA, function() { - oThis.memory.WriteBuffer(customXml.Content, 0, customXml.Content.length) + let buffer = customXml.Content.GetBuffer(); + oThis.memory.WriteBuffer(buffer.data, 1, buffer.pos); }); } }; @@ -12961,23 +12974,31 @@ function Binary_DocumentTableReader(doc, oReadResult, openParams, stream, curNot oSdtContentReader.Read(length, oSdtContent); this.nCurCommentsCount = oSdtContentReader.nCurCommentsCount; oSdt.SetContent(oSdtContent.length > 0 ? oSdtContent : []); - } else if (1 === typeContainer) { + } + else if (1 === typeContainer) + { res = this.bcr.Read1(length, function(t, l) { return oThis.ReadParagraphContent(t, l, container); }); - oSdt.SetContent() - } else if (2 === typeContainer) { + oSdt.SetContent(); + } + else if (2 === typeContainer) + { res = this.bcr.Read1(length, function(t, l) { return oThis.Read_TableContent(t, l, container); }); - oSdt.SetContent() - } else if (3 === typeContainer) { + oSdt.SetContent(); + } + else if (3 === typeContainer) + { res = this.bcr.Read1(length, function(t, l) { return oThis.ReadRowContent(t, l, container); }); - oSdt.SetContent() + oSdt.SetContent(); } - } else { + } + else + { res = c_oSerConstants.ReadUnknown; } return res; @@ -16114,233 +16135,146 @@ function Binary_OtherTableReader(doc, oReadResult, stream) }; }; -function parseBinaryXML(binaryArray) { - binaryArray = new Uint8Array(binaryArray); - let currentIndex = 0; - - function parseTextContent() { - let textContent = ""; - let nStart = currentIndex; - - while (binaryArray[currentIndex] !== 60) { // Знак "<" означает начало нового тега - currentIndex++; - } - - return new TextDecoder().decode(binaryArray.slice(nStart, currentIndex)); - } - - function parseTag() - { - const startTag = binaryArray.indexOf(60, currentIndex); // < - let endTag = binaryArray.indexOf(32, startTag); // " " - let nEndTag = binaryArray.indexOf(62, startTag); // > - let nETag = binaryArray.indexOf(47, startTag); // / - - let isClose = false; - - if (nEndTag < endTag) - endTag = nEndTag; +function Binary_CustomsTableReader(doc, oReadResult, stream, CustomXmls) { + this.Document = doc; + this.oReadResult = oReadResult; + this.stream = stream; + this.CustomXmls = CustomXmls; + this.bcr = new Binary_CommonReader(this.stream); + this.Read = function() { + var oThis = this; + return this.bcr.ReadTable(function(t, l) { + return oThis.ReadCustom(t, l); + }); + }; + this.ReadCustom = function(type, length) { + var res = c_oSerConstants.ReadOk; + var oThis = this; - if (nETag < endTag) - endTag = nETag; + if (c_oSerCustoms.Custom === type) { + var custom = {Uri: [], ItemId: null, Content: null}; + res = this.bcr.Read1(length, function(t, l) { + return oThis.ReadCustomContent(t, l, custom); + }); - if (startTag === -1 || endTag === -1) { - return null; - } + let two = String.fromCharCode.apply(String, custom.Content); + console.log(two) + let one = new StaxParser(two); + let curCont = null; - const tagName = new TextDecoder().decode(binaryArray.slice(startTag + 1, endTag)); + function CustomXMLItem(par, name) + { + this.parent = par; + this.content = []; + this.name = name ? name : ""; + this.attribute = {}; + this.textContent = ""; + this.current = undefined; + + this.AddAttribute = function (name, value) + { + this.attribute[name] = value; + } + this.AddContent = function (name) + { + let one = new CustomXMLItem(this, name); + curCont = one; + this.content.push(one); + } + this.GetParent = function () + { + if (this.parent) + return this.parent; - currentIndex = endTag; + return null; + } + this.SetParent = function (oPar) + { + this.parent = oPar; + } + this.AddTextContent = function (text) + { + if (text !== "") + this.textContent += text; + } + this.GetBuffer = function() + { + let writer = new AscCommon.CMemory(); - return tagName; - } + function Write(content) + { + let current = null; - function parseAttributes() { - if (binaryArray[currentIndex] === 62) - return {}; - const attributes = {}; + if (!content.name) + { + writer.WriteXmlString("\x8B\x00\x00\x00"); + current = content.content[0]; + } + else + { + current = content; + } - while ( - binaryArray[currentIndex] === 9 || - binaryArray[currentIndex] === 10 || // символ перехода на новую строку - binaryArray[currentIndex] === 13 || // символ возврата каретки - binaryArray[currentIndex] === 32 - ) { - currentIndex++; - } + writer.WriteXmlNodeStart(current.name); - while (binaryArray[currentIndex] !== 62 && binaryArray[currentIndex] !== 47 && binaryArray[currentIndex] !== 63) { - const attributeNameStart = currentIndex; - while (binaryArray[currentIndex] !== 32 && binaryArray[currentIndex] !== 9 && binaryArray[currentIndex] !== 61) { - currentIndex++; - } + let atr = Object.keys(current.attribute) - const attributeName = new TextDecoder().decode(binaryArray.slice(attributeNameStart, currentIndex)); + for (let i = 0; i < atr.length; i++) + { + let cur = atr[i]; + writer.WriteXmlAttributeStringEncode(cur, current.attribute[cur]); + } + writer.WriteXmlAttributesEnd(); + writer.WriteXmlString("\r\n"); - while (binaryArray[currentIndex] !== 34) { - currentIndex++; - } - currentIndex++; // пропускаем кавычку - const attributeValueStart = currentIndex; - while (binaryArray[currentIndex] !== 34) { - currentIndex++; - } + for (let i = 0; i < current.content.length; i++) + { + let curContent = current.content[i]; + Write(curContent); + } - const attributeValue = new TextDecoder().decode(binaryArray.slice(attributeValueStart, currentIndex)); + if (current.textContent) + { + writer.WriteXmlString(current.textContent); + } - attributes[attributeName] = attributeValue; - currentIndex++; // пропускаем кавычку и пробел + writer.WriteXmlNodeEnd(current.name); + writer.WriteXmlString("\r\n"); + } - // Пропускаем символы перехода на новую строку и табуляции - while ( - binaryArray[currentIndex] === 10 || - binaryArray[currentIndex] === 13 || - binaryArray[currentIndex] === 9 || - binaryArray[currentIndex] === 32 - ) { - currentIndex++; + Write(this); + return writer; + } } - } - - return attributes; - } - - - function parseElement() { - const tagName = parseTag(); - let textContent = ""; - - if (!tagName) - return null; - - const attributes = parseAttributes(); - const children = []; - - while ( - binaryArray[currentIndex] === 9 || - binaryArray[currentIndex] === 10 || // символ перехода на новую строку - binaryArray[currentIndex] === 13 || // символ возврата каретки - binaryArray[currentIndex] === 32 - ) { - currentIndex++; - } - if (binaryArray[currentIndex] === 47 && binaryArray[currentIndex+1] === 62) - { - currentIndex++; - currentIndex++; - return { - tagName: tagName, - attributes: attributes, - children: children, - textContent: textContent, - }; - } + let ParCont = new CustomXMLItem(null); - if (binaryArray[currentIndex] === 63 && binaryArray[currentIndex + 1] === 62) - { - currentIndex++; - currentIndex++; - return { - tagName: tagName, - attributes: attributes, - children: [parseElement()], - textContent: textContent, - }; - } - - if (binaryArray[currentIndex] === 62) - { - currentIndex++; - - while ( - binaryArray[currentIndex] === 9 || - binaryArray[currentIndex] === 10 || // символ перехода на новую строку - binaryArray[currentIndex] === 13 || // символ возврата каретки - binaryArray[currentIndex] === 32 - ) { - currentIndex++; - } + curCont = ParCont; - if (binaryArray[currentIndex] !== 60) + while(one.Read()) { - textContent = parseTextContent(); - currentIndex += 2; // пропускаем - } - else - { - while (currentIndex < binaryArray.length) + switch (one.GetEventType()) { - if (binaryArray[currentIndex] === 60 && binaryArray[currentIndex + 1] !== 47) - { - const child = parseElement(); - if (child) + case EasySAXEvent.CHARACTERS: curCont.AddTextContent(one.text.trim().replace(/\s/g,'')); break; + case EasySAXEvent.END_ELEMENT: curCont = curCont.parent; break; + case EasySAXEvent.START_ELEMENT: + let name = one.GetName(); + curCont.AddContent(name) + + while (one.MoveToNextAttribute()) { - children.push(child); + let nameAttrib = one.GetName(); + let valueAttrib = one.GetValue(); + curCont.AddAttribute(nameAttrib, valueAttrib); } - } - else if (binaryArray[currentIndex] === 60 && binaryArray[currentIndex + 1] === 47) - { - currentIndex += 2; // пропускаем break; - } - else - { - // Пропускаем символы перехода на новую строку и табуляции - if (binaryArray[currentIndex] !== 10 && binaryArray[currentIndex] !== 9) - { - currentIndex++; - } - else - { - currentIndex++; - while (binaryArray[currentIndex] === 10 || binaryArray[currentIndex] === 9) - { - currentIndex++; - } - } - } } } - } - - return { - tagName: tagName, - attributes: attributes, - children: children, - textContent: textContent, - }; - } - - return parseElement(); -} -function Binary_CustomsTableReader(doc, oReadResult, stream, CustomXmls) { - this.Document = doc; - this.oReadResult = oReadResult; - this.stream = stream; - this.CustomXmls = CustomXmls; - this.bcr = new Binary_CommonReader(this.stream); - this.Read = function() { - var oThis = this; - return this.bcr.ReadTable(function(t, l) { - return oThis.ReadCustom(t, l); - }); - }; - this.ReadCustom = function(type, length) { - var res = c_oSerConstants.ReadOk; - var oThis = this; - if (c_oSerCustoms.Custom === type) { - var custom = {Uri: [], ItemId: null, Content: null}; - res = this.bcr.Read1(length, function(t, l) { - return oThis.ReadCustomContent(t, l, custom); - }); - custom.Content = parseBinaryXML(custom.Content); + debugger + console.log(ParCont); + custom.Content = ParCont; this.CustomXmls.push(custom); } diff --git a/word/Editor/StructuredDocumentTags/BlockLevel.js b/word/Editor/StructuredDocumentTags/BlockLevel.js index 7426d9df5a..ea18fe501f 100644 --- a/word/Editor/StructuredDocumentTags/BlockLevel.js +++ b/word/Editor/StructuredDocumentTags/BlockLevel.js @@ -1575,12 +1575,29 @@ CBlockLevelSdt.prototype.SetContentFromDataBindings = function () return; let oTextContent = this.LogicDocument.FindInCustomXML(this.Pr.DataBinding); + + if (!oTextContent) + return; + let oParagraph = new Paragraph(this.LogicDocument.DrawingDocument); let oParaRun = new ParaRun(oParagraph); - oParaRun.AddText(oTextContent); - oParagraph.Add_ToContent(0, oParaRun); - this.Content.Remove_FromContent(0, 1, false); - this.Content.ReplaceContent([oParagraph]); + + + if (this.IsPicture()) + { + let oPicture = new ParaDrawing(null, null, null, this.LogicDocument.DrawingDocument, this.LogicDocument, this.Parent); + //Paragraph + //Run + // ParaDrawing + //var oDrawing = new Object(); + } + else + { + oParaRun.AddText(oTextContent); + oParagraph.Add_ToContent(0, oParaRun); + this.Content.Remove_FromContent(0, 1, false); + this.Content.ReplaceContent([oParagraph]); + } } CBlockLevelSdt.prototype.GetDataBinding = function () { diff --git a/word/Editor/StructuredDocumentTags/InlineLevel.js b/word/Editor/StructuredDocumentTags/InlineLevel.js index effd152cf2..5531662f90 100644 --- a/word/Editor/StructuredDocumentTags/InlineLevel.js +++ b/word/Editor/StructuredDocumentTags/InlineLevel.js @@ -1634,6 +1634,9 @@ CInlineLevelSdt.prototype.SetPr = function(oPr) if(undefined !== oPr.OForm) this.SetOForm(oPr.OForm); + + if (undefined !== oPr.DataBinding) + this.SetDataBinding(oPr.DataBinding); }; /** * Выставляем настройки текста по умолчанию для данного контрола @@ -3727,6 +3730,59 @@ CInlineLevelSdt.prototype.CorrectSingleLineFormContent = function() } } }; +CInlineLevelSdt.prototype.SetContentFromCustomXML = function() +{ + let run = new ParaRun(this.Paragraph); + +} +CInlineLevelSdt.prototype.SetDataBinding = function (oDataBinding) +{ + History.Add(new CChangesSdtPrDataBinding(this, this.Pr.oDataBinding, oDataBinding)); + this.Pr.DataBinding = oDataBinding; +}; +CInlineLevelSdt.prototype.SetContent = function (oContent) +{ + if (this.Pr.DataBinding) + { + this.SetContentFromDataBindings() + } + else + { + //this.Content.ReplaceContent(oContent); + } +} + +CInlineLevelSdt.prototype.SetContentFromDataBindings = function () +{ + if (!this.Pr.DataBinding) + return; + + let oTextContent = this.LogicDocument.FindInCustomXML(this.Pr.DataBinding); + + if (!oTextContent) + return; + + let oParagraph = new Paragraph(this.LogicDocument.DrawingDocument); + let oParaRun = new ParaRun(oParagraph); + + + if (this.IsPicture()) + { + let oPicture = new ParaDrawing(null, null, null, this.LogicDocument.DrawingDocument, this.LogicDocument, this.Parent); + //Paragraph + //Run + // ParaDrawing + //var oDrawing = new Object(); + } + else + { + oParaRun.AddText(oTextContent); + oParagraph.Add_ToContent(0, oParaRun); + this.Content.Remove_FromContent(0, 1, false); + this.Content.ReplaceContent([oParagraph]); + } +} + //--------------------------------------------------------export-------------------------------------------------------- window['AscCommonWord'] = window['AscCommonWord'] || {}; From 5067bf95e8be15d189bca65fddea255c02e52ac3 Mon Sep 17 00:00:00 2001 From: EvgeniyIgol Date: Thu, 31 Aug 2023 18:02:39 +0300 Subject: [PATCH 03/22] Add ContentControl picture processing - Add base process of CustomXML picture ContentControl --- .../StructuredDocumentTags/BlockLevel.js | 18 ++++++++++++------ word/Native/api.js | 1 + 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/word/Editor/StructuredDocumentTags/BlockLevel.js b/word/Editor/StructuredDocumentTags/BlockLevel.js index ea18fe501f..193dc2c5ac 100644 --- a/word/Editor/StructuredDocumentTags/BlockLevel.js +++ b/word/Editor/StructuredDocumentTags/BlockLevel.js @@ -1581,20 +1581,26 @@ CBlockLevelSdt.prototype.SetContentFromDataBindings = function () let oParagraph = new Paragraph(this.LogicDocument.DrawingDocument); let oParaRun = new ParaRun(oParagraph); + oParagraph.Add_ToContent(0, oParaRun); + debugger if (this.IsPicture()) { - let oPicture = new ParaDrawing(null, null, null, this.LogicDocument.DrawingDocument, this.LogicDocument, this.Parent); - //Paragraph - //Run - // ParaDrawing - //var oDrawing = new Object(); + oTextContent = "data:image/jpeg;base64," + oTextContent; + + let oDrawing = new ParaDrawing(10 * 36000, 10 * 36000, null, this.LogicDocument.DrawingDocument,this.LogicDocument, null); + let oImage = this.LogicDocument.DrawingObjects.createImage(oTextContent, 0, 0, 10 * 36000, 10 * 36000); + oImage.setParent(oDrawing); + oDrawing.Set_GraphicObject(oImage); + + oParaRun.Add_ToContent(0, oDrawing, false); + this.Content.Remove_FromContent(0, 1, false); + this.Content.ReplaceContent([oParagraph]); } else { oParaRun.AddText(oTextContent); - oParagraph.Add_ToContent(0, oParaRun); this.Content.Remove_FromContent(0, 1, false); this.Content.ReplaceContent([oParagraph]); } diff --git a/word/Native/api.js b/word/Native/api.js index dc6ad3c5b4..de4c2fcf61 100644 --- a/word/Native/api.js +++ b/word/Native/api.js @@ -977,6 +977,7 @@ Asc['asc_docs_api'].prototype["Call_Menu_Event"] = function(type, _params) } case 9 : // ASC_MENU_EVENT_TYPE_IMAGE { + debugger var _imagePr = new Asc.asc_CImgProperty(); while (_continue) { From 8817070bbf456ec4498672ffd45a9cb067eebace Mon Sep 17 00:00:00 2001 From: KirillovIlya Date: Tue, 5 Sep 2023 18:00:46 +0300 Subject: [PATCH 04/22] [de] Fix loading image from custom xml --- .../StructuredDocumentTags/BlockLevel.js | 34 +++++++++++++------ 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/word/Editor/StructuredDocumentTags/BlockLevel.js b/word/Editor/StructuredDocumentTags/BlockLevel.js index 193dc2c5ac..454ff91b01 100644 --- a/word/Editor/StructuredDocumentTags/BlockLevel.js +++ b/word/Editor/StructuredDocumentTags/BlockLevel.js @@ -1571,30 +1571,42 @@ CBlockLevelSdt.prototype.SetContent = function (oContent) } CBlockLevelSdt.prototype.SetContentFromDataBindings = function () { - if (!this.Pr.DataBinding) + let logicDocument = this.GetLogicDocument(); + if (!logicDocument || !this.Pr.DataBinding) return; - let oTextContent = this.LogicDocument.FindInCustomXML(this.Pr.DataBinding); + let oTextContent = logicDocument.FindInCustomXML(this.Pr.DataBinding); if (!oTextContent) return; - let oParagraph = new Paragraph(this.LogicDocument.DrawingDocument); - let oParaRun = new ParaRun(oParagraph); + let oParagraph = new AscWord.CParagraph(logicDocument.GetDrawingDocument()); + let oParaRun = new AscWord.CRun(); oParagraph.Add_ToContent(0, oParaRun); debugger if (this.IsPicture()) { - oTextContent = "data:image/jpeg;base64," + oTextContent; - - let oDrawing = new ParaDrawing(10 * 36000, 10 * 36000, null, this.LogicDocument.DrawingDocument,this.LogicDocument, null); - let oImage = this.LogicDocument.DrawingObjects.createImage(oTextContent, 0, 0, 10 * 36000, 10 * 36000); - oImage.setParent(oDrawing); - oDrawing.Set_GraphicObject(oImage); + // let allDrawings = this.GetAllDrawingObjects(); + // if (!allDrawings.length) + // return; + // + // let drawing = allDrawings[0]; + + let imageData = "data:image/jpeg;base64," + oTextContent; + let editor = logicDocument.GetApi(); + editor.ImageLoader.LoadImagesWithCallback([imageData], function(){}, 0, true); + + let w = 100; // 10 * 3600 + let h = 100; // 10 * 3600 - oParaRun.Add_ToContent(0, oDrawing, false); + let drawing = new ParaDrawing(w, h, null, logicDocument.GetDrawingDocument()); + let imageShape = logicDocument.DrawingObjects.createImage(imageData, 0, 0, w, h); + imageShape.setParent(drawing); + drawing.Set_GraphicObject(imageShape); + + oParaRun.Add_ToContent(0, drawing, false); this.Content.Remove_FromContent(0, 1, false); this.Content.ReplaceContent([oParagraph]); } From 8971425ffe7c9584c9aaa7fec8a200dd959a244a Mon Sep 17 00:00:00 2001 From: Ilya Kirillov Date: Wed, 6 Sep 2023 18:50:25 +0500 Subject: [PATCH 05/22] [de] Implement DataBinding class --- word/Editor/custom-xml/data-binding.js | 96 ++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 word/Editor/custom-xml/data-binding.js diff --git a/word/Editor/custom-xml/data-binding.js b/word/Editor/custom-xml/data-binding.js new file mode 100644 index 0000000000..f311542ee9 --- /dev/null +++ b/word/Editor/custom-xml/data-binding.js @@ -0,0 +1,96 @@ +/* + * (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) + { + this.prefixMappings = prefix ? prefix : undefined; + this.storeItemID = itemID ? itemID : undefined; + this.xpath = xpath ? xpath : undefined; + } + DataBinding.prototype.copy = function() + { + return new DataBinding(this.prefixMappings, this.storeItemID, this.xpath); + }; + DataBinding.prototype.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.fromBinary = function(reader) + { + let data = new DataBinding(); + + let flags = reader.GetLong(); + if (flags & 1) + data.prefixMappings = reader.GetString2(); + if (flags & 2) + data.storeItemID = reader.GetString2(); + if (flags & 4) + data.xpath = reader.GetString2(); + }; + + //--------------------------------------------------------export---------------------------------------------------- + window['AscWord'] = window['AscWord'] || {}; + window['AscWord'].DataBinding = DataBinding; + +})(window); From 2edc52c097aa7b6a88e299c164960bd3ac721943 Mon Sep 17 00:00:00 2001 From: Ilya Kirillov Date: Wed, 6 Sep 2023 21:26:59 +0500 Subject: [PATCH 06/22] [de] Refactor work with custom xml --- configs/word.json | 5 +- word/Editor/Document.js | 61 ++------- word/Editor/Serialize2.js | 47 +++---- .../StructuredDocumentTags/BlockLevel.js | 4 +- word/Editor/StructuredDocumentTags/SdtPr.js | 12 +- word/Editor/custom-xml/custom-xml-manager.js | 116 ++++++++++++++++++ word/Editor/custom-xml/custom-xml.js | 51 ++++++++ 7 files changed, 217 insertions(+), 79 deletions(-) create mode 100644 word/Editor/custom-xml/custom-xml-manager.js create mode 100644 word/Editor/custom-xml/custom-xml.js diff --git a/configs/word.json b/configs/word.json index d0be5162dd..6e1b869f90 100644 --- a/configs/word.json +++ b/configs/word.json @@ -132,7 +132,10 @@ "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/Editor/Paragraph/Run/FontClassification.js", "word/Editor/Paragraph/Run/FontCalculator.js", "word/Editor/Paragraph/Run/RunAutoCorrect.js", diff --git a/word/Editor/Document.js b/word/Editor/Document.js index 81b91100d9..e295bb39cc 100644 --- a/word/Editor/Document.js +++ b/word/Editor/Document.js @@ -2152,6 +2152,8 @@ function CDocument(DrawingDocument, isMainLogicDocument) this.GlossaryDocument = new CGlossaryDocument(this); this.AutoCorrectSettings = new AscCommon.CAutoCorrectSettings(); + + this.customXml = new AscWord.CustomXmlManager(this); // Контролируем изменения интерфейса this.ChangedStyles = []; // Объект с Id стилями, которые были изменены/удалены/добавлены @@ -27142,9 +27144,9 @@ CDocument.prototype.WriteCustomXML = function(oDataBindings, ContentToWrite) { let oCurCustomXml = this.CustomXmls[i]; - if (oDataBindings.StoreItemID === oCurCustomXml.ItemId) + if (oDataBindings.storeItemID === oCurCustomXml.ItemId) { - let xPath = oDataBindings.XPath; + let xPath = oDataBindings.xpath; function findElementsByXPath(root, xpath) { var parts = xpath.split('/'); @@ -27185,56 +27187,13 @@ CDocument.prototype.WriteCustomXML = function(oDataBindings, ContentToWrite) } } } -CDocument.prototype.FindInCustomXML = function(oDataBindings) +/** + * @returns {AscWord.CustomXmlManager} + */ +CDocument.prototype.getCustomXmlManager = function() { - for (let i = 0; i < this.CustomXmls.length; i++) - { - let oCurCustomXml = this.CustomXmls[i]; - - // этот атрибут может быть опущен, так искать плохо - if (oDataBindings.StoreItemID === oCurCustomXml.ItemId) - { - let xPath = oDataBindings.XPath; - - function findElementsByXPath(root, xpath) { - var parts = xpath.split('/'); - parts.shift(); // Убираем пустой первый элемент - - var currentElement = root; - - for (var i = 0; i < parts.length; i++) { - var part = parts[i]; - var namespaceAndTag = part.split('[')[0]; - var index = parseInt(part.split('[')[1].slice(0, -1)) - 1; - var tagName = namespaceAndTag.split(':')[1]; - - var 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) { - return null; // Элемент не найден - } - - currentElement = matchingChildren[index]; - } - - return currentElement.textContent; - } - - return findElementsByXPath(oCurCustomXml.Content, xPath); - } - } -} + return this.customXml; +}; function CDocumentSelectionState() { diff --git a/word/Editor/Serialize2.js b/word/Editor/Serialize2.js index 9546c09b10..c938b0df49 100644 --- a/word/Editor/Serialize2.js +++ b/word/Editor/Serialize2.js @@ -1863,8 +1863,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)); @@ -6663,17 +6665,17 @@ 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); } }; this.WriteSdtPrDate = function (val) @@ -7524,12 +7526,13 @@ 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; @@ -7538,8 +7541,8 @@ 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) { @@ -7852,7 +7855,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()) { @@ -13035,9 +13038,8 @@ function Binary_DocumentTableReader(doc, oReadResult, openParams, stream, curNot oSdtPr.Color = textPr.Color; } } - else if (c_oSerSdt.DataBinding === type) - { - oSdtPr.DataBinding = {}; + 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); }); @@ -13171,13 +13173,12 @@ 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 { res = c_oSerConstants.ReadUnknown; } @@ -16135,11 +16136,11 @@ function Binary_OtherTableReader(doc, oReadResult, stream) }; }; -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; @@ -16276,7 +16277,7 @@ function Binary_CustomsTableReader(doc, oReadResult, stream, CustomXmls) { console.log(ParCont); custom.Content = ParCont; - this.CustomXmls.push(custom); + this.customXmlManager.add(custom); } else res = c_oSerConstants.ReadUnknown; diff --git a/word/Editor/StructuredDocumentTags/BlockLevel.js b/word/Editor/StructuredDocumentTags/BlockLevel.js index 454ff91b01..fd8a8f99c6 100644 --- a/word/Editor/StructuredDocumentTags/BlockLevel.js +++ b/word/Editor/StructuredDocumentTags/BlockLevel.js @@ -1575,7 +1575,7 @@ CBlockLevelSdt.prototype.SetContentFromDataBindings = function () if (!logicDocument || !this.Pr.DataBinding) return; - let oTextContent = logicDocument.FindInCustomXML(this.Pr.DataBinding); + let oTextContent = logicDocument.getCustomXmlManager().getContentByDataBinding(this.Pr.DataBinding); if (!oTextContent) return; @@ -1584,8 +1584,6 @@ CBlockLevelSdt.prototype.SetContentFromDataBindings = function () let oParaRun = new AscWord.CRun(); oParagraph.Add_ToContent(0, oParaRun); - debugger - if (this.IsPicture()) { // let allDrawings = this.GetAllDrawingObjects(); diff --git a/word/Editor/StructuredDocumentTags/SdtPr.js b/word/Editor/StructuredDocumentTags/SdtPr.js index 158cc0549c..5fb3b1b145 100644 --- a/word/Editor/StructuredDocumentTags/SdtPr.js +++ b/word/Editor/StructuredDocumentTags/SdtPr.js @@ -44,6 +44,7 @@ function CSdtPr() this.Tag = undefined; this.Label = undefined; this.Lock = undefined; + this.DataBinding = undefined; this.DocPartObj = { @@ -91,7 +92,7 @@ CSdtPr.prototype.Copy = function() oPr.Color = (this.Color ? this.Color.Copy() : undefined); if (this.DataBinding) - oPr.DataBinding = this.DataBinding; + oPr.DataBinding = this.DataBinding.copy(); if (this.CheckBox) oPr.CheckBox = this.CheckBox.Copy(); @@ -272,6 +273,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); @@ -377,6 +384,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/custom-xml/custom-xml-manager.js b/word/Editor/custom-xml/custom-xml-manager.js new file mode 100644 index 0000000000..fdebb9667e --- /dev/null +++ b/word/Editor/custom-xml/custom-xml-manager.js @@ -0,0 +1,116 @@ +/* + * (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 {AscWord.CDocument} document + * @constructor + */ + function CustomXmlManager(document) + { + this.document = document; + this.xml = []; + } + 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]; + }; + CustomXmlManager.prototype.getContentByDataBinding = function(dataBinding) + { + for (let i = 0; i < this.xml.length; ++i) + { + let customXml = this.xml[i]; + + // этот атрибут может быть опущен, так искать плохо + if (dataBinding.storeItemID === customXml.ItemId) + { + let xPath = dataBinding.xpath; + + function findElementsByXPath(root, xpath) { + var parts = xpath.split('/'); + parts.shift(); // Убираем пустой первый элемент + + var currentElement = root; + + for (var i = 0; i < parts.length; i++) { + var part = parts[i]; + var namespaceAndTag = part.split('[')[0]; + var index = parseInt(part.split('[')[1].slice(0, -1)) - 1; + var tagName = namespaceAndTag.split(':')[1]; + + var 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) { + return null; // Элемент не найден + } + + currentElement = matchingChildren[index]; + } + + return currentElement.textContent; + } + + return findElementsByXPath(customXml.Content, xPath); + } + } + }; + + //--------------------------------------------------------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..0ea2d0ec6c --- /dev/null +++ b/word/Editor/custom-xml/custom-xml.js @@ -0,0 +1,51 @@ +/* + * (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 CustomXml() + { + this.uri = []; + this.itemID = ""; + this.content = null; + } + + //--------------------------------------------------------export---------------------------------------------------- + window['AscWord'] = window['AscWord'] || {}; + window['AscWord'].CustomXml = CustomXml; + +})(window); From a877c419843b0f953cde74b53c4af9cdc9dab474 Mon Sep 17 00:00:00 2001 From: Ilya Kirillov Date: Thu, 7 Sep 2023 14:45:18 +0500 Subject: [PATCH 07/22] [de] Rework filling the content control with binded data --- word/Editor/Serialize2.js | 18 +++-- .../StructuredDocumentTags/BlockLevel.js | 66 +++---------------- .../StructuredDocumentTags/InlineLevel.js | 52 ++------------- word/Editor/StructuredDocumentTags/SdtBase.js | 39 +++++++++++ 4 files changed, 63 insertions(+), 112 deletions(-) diff --git a/word/Editor/Serialize2.js b/word/Editor/Serialize2.js index c938b0df49..2d49498aa9 100644 --- a/word/Editor/Serialize2.js +++ b/word/Editor/Serialize2.js @@ -11327,6 +11327,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 ) { // oThis.Document.Background = {Color: null, Unifill: null, shape: null}; @@ -11670,6 +11671,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); @@ -12976,28 +12978,24 @@ function Binary_DocumentTableReader(doc, oReadResult, openParams, stream, curNot oSdtContentReader.oCurComments = this.oCurComments; oSdtContentReader.Read(length, oSdtContent); this.nCurCommentsCount = oSdtContentReader.nCurCommentsCount; - oSdt.SetContent(oSdtContent.length > 0 ? oSdtContent : []); + 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); }); - oSdt.SetContent(); } - else if (2 === typeContainer) - { + else if (2 === typeContainer) { res = this.bcr.Read1(length, function(t, l) { return oThis.Read_TableContent(t, l, container); }); - oSdt.SetContent(); } - else if (3 === typeContainer) - { + else if (3 === typeContainer) { res = this.bcr.Read1(length, function(t, l) { return oThis.ReadRowContent(t, l, container); }); - oSdt.SetContent(); } } else diff --git a/word/Editor/StructuredDocumentTags/BlockLevel.js b/word/Editor/StructuredDocumentTags/BlockLevel.js index fd8a8f99c6..32cd9f596c 100644 --- a/word/Editor/StructuredDocumentTags/BlockLevel.js +++ b/word/Editor/StructuredDocumentTags/BlockLevel.js @@ -1557,64 +1557,18 @@ CBlockLevelSdt.prototype.SetDataBinding = function (oDataBinding) History.Add(new CChangesSdtPrDataBinding(this, this.Pr.oDataBinding, oDataBinding)); this.Pr.DataBinding = oDataBinding; }; -CBlockLevelSdt.prototype.SetContent = function (oContent) -{ - if (this.Pr.DataBinding) - { - this.SetContentFromDataBindings() - } - else - { - this.Content.ReplaceContent(oContent); - } - -} -CBlockLevelSdt.prototype.SetContentFromDataBindings = function () +CBlockLevelSdt.prototype.fillContentWithDataBinding = function(content) { let logicDocument = this.GetLogicDocument(); - if (!logicDocument || !this.Pr.DataBinding) - return; - - let oTextContent = logicDocument.getCustomXmlManager().getContentByDataBinding(this.Pr.DataBinding); - - if (!oTextContent) - return; - - let oParagraph = new AscWord.CParagraph(logicDocument.GetDrawingDocument()); - let oParaRun = new AscWord.CRun(); - oParagraph.Add_ToContent(0, oParaRun); - - if (this.IsPicture()) - { - // let allDrawings = this.GetAllDrawingObjects(); - // if (!allDrawings.length) - // return; - // - // let drawing = allDrawings[0]; - - let imageData = "data:image/jpeg;base64," + oTextContent; - let editor = logicDocument.GetApi(); - editor.ImageLoader.LoadImagesWithCallback([imageData], function(){}, 0, true); - - let w = 100; // 10 * 3600 - let h = 100; // 10 * 3600 - - let drawing = new ParaDrawing(w, h, null, logicDocument.GetDrawingDocument()); - let imageShape = logicDocument.DrawingObjects.createImage(imageData, 0, 0, w, h); - imageShape.setParent(drawing); - drawing.Set_GraphicObject(imageShape); - - oParaRun.Add_ToContent(0, drawing, false); - this.Content.Remove_FromContent(0, 1, false); - this.Content.ReplaceContent([oParagraph]); - } - else - { - oParaRun.AddText(oTextContent); - this.Content.Remove_FromContent(0, 1, false); - this.Content.ReplaceContent([oParagraph]); - } -} + + let paragraph = new AscWord.CParagraph(logicDocument.GetDrawingDocument()); + this.Content.ClearContent(false); + this.Content.AddToContent(0, paragraph); + + let run = new AscWord.CRun(); + run.AddText(content); + paragraph.AddToContent(0, run); +}; CBlockLevelSdt.prototype.GetDataBinding = function () { return this.Pr.DataBinding; diff --git a/word/Editor/StructuredDocumentTags/InlineLevel.js b/word/Editor/StructuredDocumentTags/InlineLevel.js index 5531662f90..4c17802cee 100644 --- a/word/Editor/StructuredDocumentTags/InlineLevel.js +++ b/word/Editor/StructuredDocumentTags/InlineLevel.js @@ -3730,58 +3730,18 @@ CInlineLevelSdt.prototype.CorrectSingleLineFormContent = function() } } }; -CInlineLevelSdt.prototype.SetContentFromCustomXML = function() -{ - let run = new ParaRun(this.Paragraph); - -} CInlineLevelSdt.prototype.SetDataBinding = function (oDataBinding) { History.Add(new CChangesSdtPrDataBinding(this, this.Pr.oDataBinding, oDataBinding)); this.Pr.DataBinding = oDataBinding; }; -CInlineLevelSdt.prototype.SetContent = function (oContent) +CInlineLevelSdt.prototype.fillContentWithDataBinding = function(content) { - if (this.Pr.DataBinding) - { - this.SetContentFromDataBindings() - } - else - { - //this.Content.ReplaceContent(oContent); - } -} - -CInlineLevelSdt.prototype.SetContentFromDataBindings = function () -{ - if (!this.Pr.DataBinding) - return; - - let oTextContent = this.LogicDocument.FindInCustomXML(this.Pr.DataBinding); - - if (!oTextContent) - return; - - let oParagraph = new Paragraph(this.LogicDocument.DrawingDocument); - let oParaRun = new ParaRun(oParagraph); - - - if (this.IsPicture()) - { - let oPicture = new ParaDrawing(null, null, null, this.LogicDocument.DrawingDocument, this.LogicDocument, this.Parent); - //Paragraph - //Run - // ParaDrawing - //var oDrawing = new Object(); - } - else - { - oParaRun.AddText(oTextContent); - oParagraph.Add_ToContent(0, oParaRun); - this.Content.Remove_FromContent(0, 1, false); - this.Content.ReplaceContent([oParagraph]); - } -} + let run = new AscWord.CRun(); + run.AddText(content); + this.ClearContent(); + this.AddToContent(0, run); +}; //--------------------------------------------------------export-------------------------------------------------------- diff --git a/word/Editor/StructuredDocumentTags/SdtBase.js b/word/Editor/StructuredDocumentTags/SdtBase.js index 3fd06490d7..9f72200185 100644 --- a/word/Editor/StructuredDocumentTags/SdtBase.js +++ b/word/Editor/StructuredDocumentTags/SdtBase.js @@ -1071,4 +1071,43 @@ CSdtBase.prototype.IsHideContentControlTrack = function() return Asc.c_oAscSdtAppearance.Hidden === this.GetAppearance(); }; +/** + * Проверяем, есть ли привязанные данные, и если есть заполняем ими содержимое контрола + */ +CSdtBase.prototype.checkDataBinding = function() +{ + let logicDocument = this.GetLogicDocument(); + if (!logicDocument || !this.Pr.DataBinding) + return; + + let content = logicDocument.getCustomXmlManager().getContentByDataBinding(this.Pr.DataBinding); + 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) +{ +}; From 609c9e2561b4963e381dcd1001e382fadc4d158d Mon Sep 17 00:00:00 2001 From: Ilya Kirillov Date: Thu, 7 Sep 2023 14:58:26 +0500 Subject: [PATCH 08/22] [de] Fix problems with history change for data-binding --- common/HistoryCommon.js | 3 ++- .../StructuredDocumentTags/BlockLevel.js | 7 +------ .../StructuredDocumentTags/InlineLevel.js | 7 +------ word/Editor/StructuredDocumentTags/SdtBase.js | 9 +++++++++ .../StructuredDocumentTags/SdtPrChanges.js | 8 ++++---- word/Editor/custom-xml/data-binding.js | 20 +++++++++++++------ 6 files changed, 31 insertions(+), 23 deletions(-) diff --git a/common/HistoryCommon.js b/common/HistoryCommon.js index c553f0e71b..4551592e29 100644 --- a/common/HistoryCommon.js +++ b/common/HistoryCommon.js @@ -2235,7 +2235,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/word/Editor/StructuredDocumentTags/BlockLevel.js b/word/Editor/StructuredDocumentTags/BlockLevel.js index 32cd9f596c..672b115dbe 100644 --- a/word/Editor/StructuredDocumentTags/BlockLevel.js +++ b/word/Editor/StructuredDocumentTags/BlockLevel.js @@ -1454,7 +1454,7 @@ CBlockLevelSdt.prototype.SetPr = function(oPr) this.SetColor(oPr.Color); if (undefined !== oPr.DataBinding) - this.SetDataBinding(oPr.DataBinding); + this.setDataBinding(oPr.DataBinding); }; /** * Выставляем настройки текста по умолчанию для данного контрола @@ -1552,11 +1552,6 @@ CBlockLevelSdt.prototype.SetColor = function(oColor) this.Pr.Color = oColor; } }; -CBlockLevelSdt.prototype.SetDataBinding = function (oDataBinding) -{ - History.Add(new CChangesSdtPrDataBinding(this, this.Pr.oDataBinding, oDataBinding)); - this.Pr.DataBinding = oDataBinding; -}; CBlockLevelSdt.prototype.fillContentWithDataBinding = function(content) { let logicDocument = this.GetLogicDocument(); diff --git a/word/Editor/StructuredDocumentTags/InlineLevel.js b/word/Editor/StructuredDocumentTags/InlineLevel.js index 4c17802cee..d624539d16 100644 --- a/word/Editor/StructuredDocumentTags/InlineLevel.js +++ b/word/Editor/StructuredDocumentTags/InlineLevel.js @@ -1636,7 +1636,7 @@ CInlineLevelSdt.prototype.SetPr = function(oPr) this.SetOForm(oPr.OForm); if (undefined !== oPr.DataBinding) - this.SetDataBinding(oPr.DataBinding); + this.setDataBinding(oPr.DataBinding); }; /** * Выставляем настройки текста по умолчанию для данного контрола @@ -3730,11 +3730,6 @@ CInlineLevelSdt.prototype.CorrectSingleLineFormContent = function() } } }; -CInlineLevelSdt.prototype.SetDataBinding = function (oDataBinding) -{ - History.Add(new CChangesSdtPrDataBinding(this, this.Pr.oDataBinding, oDataBinding)); - this.Pr.DataBinding = oDataBinding; -}; CInlineLevelSdt.prototype.fillContentWithDataBinding = function(content) { let run = new AscWord.CRun(); diff --git a/word/Editor/StructuredDocumentTags/SdtBase.js b/word/Editor/StructuredDocumentTags/SdtBase.js index 9f72200185..b31bd0a798 100644 --- a/word/Editor/StructuredDocumentTags/SdtBase.js +++ b/word/Editor/StructuredDocumentTags/SdtBase.js @@ -1071,6 +1071,15 @@ 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; +}; /** * Проверяем, есть ли привязанные данные, и если есть заполняем ими содержимое контрола */ diff --git a/word/Editor/StructuredDocumentTags/SdtPrChanges.js b/word/Editor/StructuredDocumentTags/SdtPrChanges.js index 6358aaf92e..8b396ad44b 100644 --- a/word/Editor/StructuredDocumentTags/SdtPrChanges.js +++ b/word/Editor/StructuredDocumentTags/SdtPrChanges.js @@ -45,7 +45,6 @@ AscDFH.changesFactory[AscDFH.historyitem_SdtPr_Lock] = CChangesSdtPr AscDFH.changesFactory[AscDFH.historyitem_SdtPr_DocPartObj] = CChangesSdtPrDocPartObj; AscDFH.changesFactory[AscDFH.historyitem_SdtPr_Appearance] = CChangesSdtPrAppearance; AscDFH.changesFactory[AscDFH.historyitem_SdtPr_Color] = CChangesSdtPrColor; -AscDFH.changesFactory[AscDFH.historyitem_SdtPr_DataBinding] = CChangesSdtPrDataBinding; AscDFH.changesFactory[AscDFH.historyitem_SdtPr_CheckBox] = CChangesSdtPrCheckBox; AscDFH.changesFactory[AscDFH.historyitem_SdtPr_CheckBox_Checked] = CChangesSdtPrCheckBoxChecked; AscDFH.changesFactory[AscDFH.historyitem_SdtPr_Picture] = CChangesSdtPrPicture; @@ -62,6 +61,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; //---------------------------------------------------------------------------------------------------------------------- // Карта зависимости изменений //---------------------------------------------------------------------------------------------------------------------- @@ -437,14 +438,13 @@ CChangesSdtPrDataBinding.prototype.private_SetValue = function(Value) }; CChangesSdtPrDataBinding.prototype.private_CreateObject = function() { - return {}; + return new AscWord.DataBinding(); }; CChangesSdtPrDataBinding.prototype.IsNeedRecalculate = function() { - return false; + return true; }; - /** * @constructor * @extends {AscDFH.CChangesBaseObjectProperty} diff --git a/word/Editor/custom-xml/data-binding.js b/word/Editor/custom-xml/data-binding.js index f311542ee9..7c9f3f400a 100644 --- a/word/Editor/custom-xml/data-binding.js +++ b/word/Editor/custom-xml/data-binding.js @@ -48,6 +48,16 @@ return new DataBinding(this.prefixMappings, this.storeItemID, this.xpath); }; 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); @@ -76,17 +86,15 @@ writer.WriteLong(flags); writer.Seek(endPos); }; - DataBinding.fromBinary = function(reader) + DataBinding.prototype.Read_FromBinary = function(reader) { - let data = new DataBinding(); - let flags = reader.GetLong(); if (flags & 1) - data.prefixMappings = reader.GetString2(); + this.prefixMappings = reader.GetString2(); if (flags & 2) - data.storeItemID = reader.GetString2(); + this.storeItemID = reader.GetString2(); if (flags & 4) - data.xpath = reader.GetString2(); + this.xpath = reader.GetString2(); }; //--------------------------------------------------------export---------------------------------------------------- From 2849a6593388c5237757056b1017e1d83d2e907d Mon Sep 17 00:00:00 2001 From: EvgeniyIgol Date: Wed, 1 Nov 2023 17:16:03 +0300 Subject: [PATCH 09/22] Add process of CustomXML for rich text --- word/Editor/Serialize2.js | 30 +++-- .../StructuredDocumentTags/BlockLevel.js | 117 ++++++++++++++++-- word/Native/api.js | 1 - 3 files changed, 126 insertions(+), 22 deletions(-) diff --git a/word/Editor/Serialize2.js b/word/Editor/Serialize2.js index 34b0c29bc7..d8a5ab425d 100644 --- a/word/Editor/Serialize2.js +++ b/word/Editor/Serialize2.js @@ -16170,9 +16170,11 @@ function Binary_CustomsTableReader(doc, oReadResult, stream) { var res = c_oSerConstants.ReadOk; var oThis = this; - if (c_oSerCustoms.Custom === type) { + if (c_oSerCustoms.Custom === type) + { var custom = {Uri: [], ItemId: null, Content: null}; - res = this.bcr.Read1(length, function(t, l) { + res = this.bcr.Read1(length, function (t, l) + { return oThis.ReadCustomContent(t, l, custom); }); @@ -16181,6 +16183,9 @@ function Binary_CustomsTableReader(doc, oReadResult, stream) { let one = new StaxParser(two); let curCont = null; + let tg = new CT_XmlNode(); + let stax = new StaxParser(two, tg); + function CustomXMLItem(par, name) { this.parent = par; @@ -16216,7 +16221,7 @@ function Binary_CustomsTableReader(doc, oReadResult, stream) { if (text !== "") this.textContent += text; } - this.GetBuffer = function() + this.GetBuffer = function () { let writer = new AscCommon.CMemory(); @@ -16228,8 +16233,7 @@ function Binary_CustomsTableReader(doc, oReadResult, stream) { { writer.WriteXmlString("\x8B\x00\x00\x00"); current = content.content[0]; - } - else + } else { current = content; } @@ -16271,30 +16275,30 @@ function Binary_CustomsTableReader(doc, oReadResult, stream) { curCont = ParCont; - while(one.Read()) + while (one.Read()) { switch (one.GetEventType()) { - case EasySAXEvent.CHARACTERS: curCont.AddTextContent(one.text.trim().replace(/\s/g,'')); break; - case EasySAXEvent.END_ELEMENT: curCont = curCont.parent; break; + case EasySAXEvent.CHARACTERS: + curCont.AddTextContent(one.text); + break; + case EasySAXEvent.END_ELEMENT: + curCont = curCont.parent; + break; case EasySAXEvent.START_ELEMENT: let name = one.GetName(); curCont.AddContent(name) while (one.MoveToNextAttribute()) { - let nameAttrib = one.GetName(); + let nameAttrib = one.GetName(); let valueAttrib = one.GetValue(); curCont.AddAttribute(nameAttrib, valueAttrib); } break; } } - - debugger - console.log(ParCont); custom.Content = ParCont; - this.customXmlManager.add(custom); } else diff --git a/word/Editor/StructuredDocumentTags/BlockLevel.js b/word/Editor/StructuredDocumentTags/BlockLevel.js index 48205bacd2..b5ae02d102 100644 --- a/word/Editor/StructuredDocumentTags/BlockLevel.js +++ b/word/Editor/StructuredDocumentTags/BlockLevel.js @@ -1550,14 +1550,115 @@ CBlockLevelSdt.prototype.SetColor = function(oColor) CBlockLevelSdt.prototype.fillContentWithDataBinding = function(content) { let logicDocument = this.GetLogicDocument(); - - let paragraph = new AscWord.CParagraph(logicDocument.GetDrawingDocument()); - this.Content.ClearContent(false); - this.Content.AddToContent(0, paragraph); - - let run = new AscWord.CRun(); - run.AddText(content); - paragraph.AddToContent(0, run); + + if (this.IsCheckBox()) + { + let checkBoxPr = new AscWord.CSdtCheckBoxPr(); + if (content === "true" || content === "1") + checkBoxPr.SetChecked(true); + this.SetCheckBoxPr(checkBoxPr) + } + else + { + content = content.replaceAll("<", "<"); + content = content.replaceAll(">", ">"); + content = content.replaceAll("", ""); + content = content.replaceAll("", ""); + let zLib = new AscCommon.ZLib; + let zip = zLib.create(); + + let nPos = 0; + + zLib.addFile('[Content_Types].xml', new TextEncoder("utf-8").encode('' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '')); + + while (true) + { + let nStartPos = nPos = content.indexOf('', nStartPos); + + let strText = content.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) + ''.length; + let nDataEndPos = strText.indexOf('', nDataStartPos); + //nPos = nDataEndPos + ''.length; + 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 = logicDocument.DrawingDocument; + let Doc = new CDocument(draw, false); + + let xmlParserContext = new AscCommon.XmlParserContext(); + xmlParserContext.DrawingDocument = draw; + + let jsZlib = new AscCommon.ZLib(); + if (!jsZlib.open(arr)) { + return false; + } + + let reader, openParams = {}; + let oBinaryFileReader = new AscCommonWord.BinaryFileReader(Doc, openParams); + oBinaryFileReader.PreLoadPrepare(); + + Doc.fromZip(jsZlib, xmlParserContext, oBinaryFileReader.oReadResult); + + oBinaryFileReader.PostLoadPrepare(xmlParserContext); + jsZlib.close(); + debugger + + this.Content.RemoveFromContent(0, 1); + this.Content.AddContent(Doc.Content); + this.Content.Recalculate(true); + } }; CBlockLevelSdt.prototype.GetDataBinding = function () { diff --git a/word/Native/api.js b/word/Native/api.js index cf9cc4ce9b..436c489744 100644 --- a/word/Native/api.js +++ b/word/Native/api.js @@ -987,7 +987,6 @@ Asc['asc_docs_api'].prototype["Call_Menu_Event"] = function(type, _params) } case 9 : // ASC_MENU_EVENT_TYPE_IMAGE { - debugger var _imagePr = new Asc.asc_CImgProperty(); while (_continue) { From 46888f9e67b0b06b9257ec2d62fd624b64a7a340 Mon Sep 17 00:00:00 2001 From: EvgeniyIgol Date: Wed, 6 Dec 2023 18:38:48 +0300 Subject: [PATCH 10/22] Update processing of customXML --- common/Drawings/Metafile.js | 11 + tests/word/customXML/customXML.html | 37 ++ tests/word/customXML/customXML.js | 391 ++++++++++++++++++ word/Editor/Document.js | 10 +- word/Editor/Serialize2.js | 212 ++++++++-- .../StructuredDocumentTags/BlockLevel.js | 54 ++- word/Editor/StructuredDocumentTags/SdtBase.js | 2 +- word/Editor/custom-xml/custom-xml-manager.js | 96 +++-- word/Editor/custom-xml/custom-xml.js | 9 +- word/Editor/custom-xml/data-binding.js | 188 ++++++++- word/api.js | 6 + 11 files changed, 912 insertions(+), 104 deletions(-) create mode 100644 tests/word/customXML/customXML.html create mode 100644 tests/word/customXML/customXML.js diff --git a/common/Drawings/Metafile.js b/common/Drawings/Metafile.js index d0f7a4fd0f..7f25363bef 100644 --- a/common/Drawings/Metafile.js +++ b/common/Drawings/Metafile.js @@ -838,6 +838,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 & 0xFFFF; diff --git a/tests/word/customXML/customXML.html b/tests/word/customXML/customXML.html new file mode 100644 index 0000000000..23f3848a72 --- /dev/null +++ b/tests/word/customXML/customXML.html @@ -0,0 +1,37 @@ + + + + + + Document calculation tests + + + + + + + + + + + + + + + + + + + +

Test forms

+

+
+

+
    +
    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..a865004df6 --- /dev/null +++ b/tests/word/customXML/customXML.js @@ -0,0 +1,391 @@ +/* + * (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 () { + + //something (zlib engine) does not have time to load, for now need to leave this line of code here + debugger + //==== + + AscCommon.zlib_load(function (){return true},function (){return false}) + window.onZlibEngineInit() + + let logicDocument = AscTest.CreateLogicDocument(); + let custom; + + function proceedCustomXml(strXml) + { + let oStax = new StaxParser(strXml); + + // switch to CT_Node + function CustomXMLItem(par, name) + { + this.parent = par; + this.content = []; + this.name = name ? name : ""; + this.attribute = {}; + this.textContent = ""; + this.current = undefined; + + this.str = ""; + + this.AddAttribute = function (name, value) + { + this.attribute[name] = value; + } + this.AddContent = function (name) + { + let one = new CustomXMLItem(this, name); + oCurrentContent = one; + this.content.push(one); + } + this.GetParent = function () + { + if (this.parent) + return this.parent; + + return null; + } + this.SetParent = function (oPar) + { + this.parent = oPar; + } + this.AddTextContent = function (text) + { + if (text !== "") + this.textContent += text; + } + this.GetStringFromBuffer = function () + { + let buffer = this.GetBuffer(); + let arr = Array.prototype.slice.call(buffer.data.slice(1, buffer.pos)); + let str = String.fromCharCode.apply(null, arr); + str = str.replaceAll(""", "\""); + str = str.replaceAll("&", "&"); + + this.str = str; + return str; + } + this.GetBuffer = function () + { + let writer = new AscCommon.CMemory(); + + function Write(content) + { + let current = null; + + if (!content.name) + { + writer.WriteXmlString("\x00"); + current = content.content[0]; + } else + { + current = content; + } + + 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++) + { + let curContent = current.content[i]; + Write(curContent); + } + + if (current.textContent) + writer.WriteXmlStringEncode(current.textContent.toString()); + + writer.WriteXmlNodeEnd(current.name); + } + + Write(this); + return writer; + } + } + + let oParentContent; + let oCurrentContent = oParentContent = new CustomXMLItem(null); + + while (oStax.Read()) + { + switch (oStax.GetEventType()) + { + case EasySAXEvent.CHARACTERS: + oCurrentContent.AddTextContent(oStax.text); + break; + case EasySAXEvent.END_ELEMENT: + oCurrentContent = oCurrentContent.parent; + break; + case EasySAXEvent.START_ELEMENT: + let name = oStax.GetName(); + oCurrentContent.AddContent(name) + + while (oStax.MoveToNextAttribute()) + { + let nameAttrib = oStax.GetName(); + let valueAttrib = oStax.GetValue(); + oCurrentContent.AddAttribute(nameAttrib, valueAttrib); + } + break; + } + } + + return oParentContent + } + function getXml(arrStr) + { + let start = '\n' + + '\n' + + ' <?xml version="1.0" standalone="yes"?>\n' + + ' <?mso-application progid="Word.Document"?>\n' + + ' <pkg:package xmlns:pkg="http://schemas.microsoft.com/office/2006/xmlPackage"><pkg:part\n' + + ' pkg:name="/_rels/.rels" pkg:contentType="application/vnd.openxmlformats-package.relationships+xml"\n' + + ' pkg:padding="512"><pkg:xmlData><Relationships\n' + + ' xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1"\n' + + ' Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"\n' + + ' Target="word/document.xml"/></Relationships></pkg:xmlData></pkg:part><pkg:part\n' + + ' pkg:name="/word/document.xml"\n' + + ' pkg:contentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"><pkg:xmlData><w:document\n' + + ' xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas"\n' + + ' xmlns:cx="http://schemas.microsoft.com/office/drawing/2014/chartex"\n' + + ' xmlns:cx1="http://schemas.microsoft.com/office/drawing/2015/9/8/chartex"\n' + + ' xmlns:cx2="http://schemas.microsoft.com/office/drawing/2015/10/21/chartex"\n' + + ' xmlns:cx3="http://schemas.microsoft.com/office/drawing/2016/5/9/chartex"\n' + + ' xmlns:cx4="http://schemas.microsoft.com/office/drawing/2016/5/10/chartex"\n' + + ' xmlns:cx5="http://schemas.microsoft.com/office/drawing/2016/5/11/chartex"\n' + + ' xmlns:cx6="http://schemas.microsoft.com/office/drawing/2016/5/12/chartex"\n' + + ' xmlns:cx7="http://schemas.microsoft.com/office/drawing/2016/5/13/chartex"\n' + + ' xmlns:cx8="http://schemas.microsoft.com/office/drawing/2016/5/14/chartex"\n' + + ' xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"\n' + + ' xmlns:aink="http://schemas.microsoft.com/office/drawing/2016/ink"\n' + + ' xmlns:am3d="http://schemas.microsoft.com/office/drawing/2017/model3d"\n' + + ' xmlns:o="urn:schemas-microsoft-com:office:office"\n' + + ' xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"\n' + + ' xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml"\n' + + ' xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing"\n' + + ' xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"\n' + + ' xmlns:w10="urn:schemas-microsoft-com:office:word"\n' + + ' xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"\n' + + ' xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml"\n' + + ' xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml"\n' + + ' xmlns:w16cex="http://schemas.microsoft.com/office/word/2018/wordml/cex"\n' + + ' xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid"\n' + + ' xmlns:w16="http://schemas.microsoft.com/office/word/2018/wordml"\n' + + ' xmlns:w16sdtdh="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash"\n' + + ' xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex"\n' + + ' xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup"\n' + + ' xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk"\n' + + ' xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml"\n' + + ' xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 w15 w16se w16cid\n' + + ' w16 w16cex w16sdtdh wp14"\n' + + ' ><w:body>'; + + arrStr.forEach(str => start += '<w:p><w:r><w:t>' + str + '</w:t></w:r></w:p>') + + start += '</w:body></w:document></pkg:xmlData></pkg:part><pkg:part\n' + + ' pkg:name="/word/_rels/document.xml.rels"\n' + + ' pkg:contentType="application/vnd.openxmlformats-package.relationships+xml" pkg:padding="256"><pkg:xmlData><Relationships\n' + + ' xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1"\n' + + ' Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/></Relationships></pkg:xmlData></pkg:part><pkg:part\n' + + ' pkg:name="/word/styles.xml"\n' + + ' pkg:contentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"><pkg:xmlData><w:styles\n' + + ' xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"\n' + + ' xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"\n' + + ' xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"\n' + + ' xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml"\n' + + ' xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml"\n' + + ' xmlns:w16cex="http://schemas.microsoft.com/office/word/2018/wordml/cex"\n' + + ' xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid"\n' + + ' xmlns:w16="http://schemas.microsoft.com/office/word/2018/wordml"\n' + + ' xmlns:w16sdtdh="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash"\n' + + ' xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" mc:Ignorable="w14 w15 w16se w16cid w16\n' + + ' w16cex w16sdtdh"><w:docDefaults><w:rPrDefault><w:rPr><w:rFonts w:asciiTheme="minorHAnsi"\n' + + ' w:eastAsiaTheme="minorHAnsi" w:hAnsiTheme="minorHAnsi" w:cstheme="minorBidi"/><w:sz w:val="22"/><w:szCs\n' + + ' 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\n' + + ' w:after="160" w:line="259" w:lineRule="auto"/></w:pPr></w:pPrDefault></w:docDefaults><w:style\n' + + ' w:type="paragraph" w:default="1" w:styleId="a"><w:name w:val="Normal"/><w:qFormat/><w:pPr><w:spacing\n' + + ' w:after="200" w:line="276" w:lineRule="auto"/></w:pPr></w:style><w:style w:type="character"\n' + + ' 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\n' + + ' 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\n' + + ' w:w="0" w:type="dxa"/><w:tblCellMar><w:top w:w="0" w:type="dxa"/><w:left w:w="108"\n' + + ' 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\n' + + ' 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>\n' + + ' \n' + + '' + + return start + } + function CreateContentControl() + { + let cc = new AscWord.CBlockLevelSdt(logicDocument); + cc.SetPlaceholder(c_oAscDefaultPlaceholderName.Text); + cc.ReplacePlaceHolderWithContent(); + cc.SetShowingPlcHdr(false); + return cc; + } + function CreateFilledContentControl() + { + let cc = CreateContentControl(); + let docContent = cc.GetContent(); + docContent.ClearContent(false); + + let d1 = new AscWord.DataBinding(); + d1.prefixMappings = "xmlns:ns0='http://example.com/picture' "; + d1.storeItemID = "{694325A8-B1C9-407B-A2C2-E2DD1740AA5E}"; + d1.xpath = "/ns0:documentData[1]/ns0:simpleText[1]"; + d1.storeItemCheckSum = "Gt6wYg=="; + cc.Pr.DataBinding = d1; + + return cc; + } + 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 updateXML(strXml) + { + custom = new AscWord.CustomXml(); + custom.itemId ="{694325A8-B1C9-407B-A2C2-E2DD1740AA5E}"; + custom.uri = ['http://example.com/picture']; + custom.content = proceedCustomXml(strXml); + logicDocument.customXml.add(custom) + } + + function formatXml(xml) { + var formatted = ''; + var reg = /(>)(<)(\/*)/g; + xml = xml.replace(reg, '$1\r\n$2$3'); + var pad = 0; + jQuery.each(xml.split('\r\n'), function(index, node) { + var indent = 0; + if (node.match( /.+<\/\w[^>]*>$/ )) { + indent = 0; + } else if (node.match( /^<\/\w/ )) { + if (pad != 0) { + pad -= 1; + } + } else if (node.match( /^<\w[^>]*[^\/]>.*$/ )) { + indent = 1; + } else { + indent = 0; + } + + var padding = ''; + for (var i = 0; i < pad; i++) { + padding += ' '; + } + + formatted += padding + node + '\r\n'; + pad += indent; + }); + + return formatted; + } + + //todo content control inside content control: + // picture + // richText + // simpleText + // checkBox + + window['asc_docs_api'] = AscCommon.baseEditorsApi; + const editor = new AscCommon.baseEditorsApi({}); + + QUnit.test("Load content from customXML", function (assert) + { + AscTest.ClearDocument(); + + let c1 = CreateFilledContentControl(); + logicDocument.AddToContent(0, c1); + updateXML(getXml(['Один два три 4 пять'])) + c1.checkDataBinding(); + CheckContentParagraph(assert, c1.Content.Content, ['Один два три 4 пять ']) + }); + + QUnit.test("Load content from customXML", function (assert) + { + AscTest.ClearDocument(); + + let c1 = CreateFilledContentControl(); + logicDocument.AddToContent(0, c1); + updateXML(getXml(['Один два три 4 пять', '23'])) + c1.checkDataBinding(); + CheckContentParagraph(assert, c1.Content.Content, ['Один два три 4 пять ', '23 ']) + }); + + QUnit.test("Save content to customXML", function (assert) + { + AscTest.ClearDocument(); + let c1 = CreateFilledContentControl(); + logicDocument.AddToContent(0, c1); + c1.checkDataBinding(); + + let doc = new AscTest.CreateLogicDocument(); + doc.ReplaceContent(c1.Content.Content); + + // let jsZlib = new AscCommon.ZLib(); + // jsZlib.create(); + // doc.toZip(jsZlib, new AscCommon.XmlWriterContext(AscCommon.c_oEditorId.Word)); + // let data = jsZlib.save(); + // let jsZlib2 = new AscCommon.ZLib(); + // jsZlib2.open(data); + // + // let openDoc = new AscCommon.openXml.OpenXmlPackage(jsZlib2, null); + // + // console.log(openDoc) + + let str = AscCommon.getCustomXmlFromContentControl(custom); + str = str.replaceAll('<', '<'); + str = str.replaceAll('>', '>'); + + console.log(str) + console.log(formatXml(str)) + + // check content of customXMl + + assert.strictEqual("save", false, "Check no format validation"); + }); + +}); diff --git a/word/Editor/Document.js b/word/Editor/Document.js index 2163ccb2a4..3867498a30 100644 --- a/word/Editor/Document.js +++ b/word/Editor/Document.js @@ -27088,11 +27088,10 @@ CDocument.prototype.IsCheckFormPlaceholder = function() }; CDocument.prototype.WriteCustomXML = function(oDataBindings, ContentToWrite) { - for (let i = 0; i < this.CustomXmls.length; i++) + for (let i = 0; i < this.customXml.xml.length; i++) { - let oCurCustomXml = this.CustomXmls[i]; - - if (oDataBindings.storeItemID === oCurCustomXml.ItemId) + let oCurCustomXml = this.customXml.xml[i]; + if (oDataBindings.storeItemID === oCurCustomXml.itemId) { let xPath = oDataBindings.xpath; @@ -27130,8 +27129,7 @@ CDocument.prototype.WriteCustomXML = function(oDataBindings, ContentToWrite) return currentElement.textContent = ContentToWrite; } - - return findElementsByXPath(oCurCustomXml.Content, xPath); + return findElementsByXPath(oCurCustomXml.content, xPath); } } } diff --git a/word/Editor/Serialize2.js b/word/Editor/Serialize2.js index d8a5ab425d..32f625b5ac 100644 --- a/word/Editor/Serialize2.js +++ b/word/Editor/Serialize2.js @@ -1123,6 +1123,8 @@ var c_oSerSdt = { TextFormPrFormatVal : 81, TextFormPrFormatSymbols : 82, + StoreItemCheckSum : 85, + ComplexFormPr : 90, ComplexFormPrType : 91, OformMaster : 92 @@ -6683,6 +6685,14 @@ function BinaryDocumentTableWriter(memory, doc, oMapCommentId, oNumIdMap, copyPa this.memory.WriteByte(c_oSerSdt.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) { @@ -7546,6 +7556,114 @@ function BinaryNotesTableWriter(memory, doc, oNumIdMap, oMapCommentId, copyParam this.bs.WriteItem(c_oSerNotes.NoteContent, function(){dtw.WriteDocumentContent(note);}); }; }; + + +//temp location +function getCustomXmlFromContentControl(customXml) +{ + let oContent = customXml.oContentLink; + + let writer = new AscCommon.CMemory() + writer.context = new AscCommon.XmlWriterContext(AscCommon.c_oEditorId.Word); + writer.context.docSaveParams = new DocSaveParams(undefined, undefined, false, undefined); + + let drawDoc = new AscCommon.CDrawingDocument(); + drawDoc.m_oWordControl = drawDoc + drawDoc.m_oWordControl.m_oApi = window.editor; + let doc = new AscWord.CDocument(drawDoc); + doc.ReplaceContent(oContent.Content.Content); + + let jsZlib = new AscCommon.ZLib(); + jsZlib.create(); + doc.toZip(jsZlib, new AscCommon.XmlWriterContext(AscCommon.c_oEditorId.Word)); + let data = jsZlib.save(); + let jsZlib2 = new AscCommon.ZLib(); + jsZlib2.open(data); + + var openDoc = new AscCommon.openXml.OpenXmlPackage(jsZlib2, null); + + let outputUString = "\n" + + "\n" + + ""; + + 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; + } + + jsZlib2.files.forEach(function(path){ + if ((path === "_rels/.rels" || path === "word/document.xml" || path === "word/_rels/document.xml.rels") && !path.includes("glossary")) + { + let ctfBytes = jsZlib2.getFile(path); + let ctfText = AscCommon.UTF8ArrayToString(ctfBytes, 0, ctfBytes.length); + let type = openDoc.getContentType(path); + console.log(ctfText, openDoc, type) + + 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", "") + "" + } + }); + + //check diffrences between main write and this, when save main document higlight write correct + outputUString = outputUString.replace("FFFF00", "yellow"); + + //need get contentType from openXml.Types + outputUString = outputUString.replace("pkg:contentType=\"application/xml\"", "pkg:contentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml\""); + outputUString = outputUString.replace("pkg:contentType=\"application/vnd.openxmlformats-package.relationships+xml\"", "pkg:contentType=\"application/vnd.openxmlformats-package.relationships+xml\" pkg:padding=\"512\"") + outputUString = outputUString.replace("\"/word/_rels/document.xml.rels\"pkg:contentType=\"application/vnd.openxmlformats-package.relationships+xml\"", "\"/word/_rels/document.xml.rels\"pkg:contentType=\"application/vnd.openxmlformats-package.relationships+xml\" pkg:padding=\"256\"") + + outputUString += ""; + + //create flat xml + outputUString = outputUString.replaceAll("<", "<"); + outputUString = outputUString.replaceAll(">", ">"); + + let str = customXml.content.GetStringFromBuffer(); + let nStartIndex = str.indexOf("") + ''.length; + let nEndIndex = str.indexOf("/pkg:package>") + '/pkg:package>'.length ; + + str = replaceSubstring(str, nStartIndex, nEndIndex, outputUString); + + //for now hardcode + str = str.replace("", "") + + // nStartIndex = str.indexOf("") + ''.length; + // nEndIndex = str.indexOf("/pkg:package>") + '/pkg:package>'.length ; + //customXml.oContentLink.Pr.DataBinding.recalculateCheckSum(str.substring(nStartIndex, nEndIndex)); + + return str; +} + function BinaryCustomsTableWriter(memory, doc, customXmlManager) { this.memory = memory; @@ -7567,21 +7685,20 @@ function BinaryCustomsTableWriter(memory, doc, customXmlManager) }; 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) { this.bs.WriteItem(c_oSerCustoms.ItemId, function() { - oThis.memory.WriteString3(customXml.ItemId); + oThis.memory.WriteString3(customXml.itemId); }); } if (null !== customXml.Content) { - let mem = this.bs.memory; this.bs.WriteItem(c_oSerCustoms.ContentA, function() { - let buffer = customXml.Content.GetBuffer(); - oThis.memory.WriteBuffer(buffer.data, 1, buffer.pos); + let str = getCustomXmlFromContentControl(customXml); + oThis.memory.WriteCustomStringA(str); }); } }; @@ -13197,6 +13314,8 @@ function Binary_DocumentTableReader(doc, oReadResult, openParams, stream, curNot val.storeItemID = this.stream.GetString2LE(length); } else if (c_oSerSdt.XPath === type) { val.xpath = this.stream.GetString2LE(length); + } else if (c_oSerSdt.StoreItemCheckSum === type) { + val.storeItemCheckSum = this.stream.GetString2LE(length) } else { res = c_oSerConstants.ReadUnknown; } @@ -16169,23 +16288,23 @@ function Binary_CustomsTableReader(doc, oReadResult, stream) { this.ReadCustom = function(type, length) { var res = c_oSerConstants.ReadOk; var oThis = this; + if (c_oSerCustoms.Custom === type) { - if (c_oSerCustoms.Custom === type) - { - var custom = {Uri: [], ItemId: null, Content: null}; - res = this.bcr.Read1(length, function (t, l) - { + var custom = new AscWord.CustomXml(); + + res = this.bcr.Read1(length, function(t, l) { return oThis.ReadCustomContent(t, l, custom); }); - let two = String.fromCharCode.apply(String, custom.Content); - console.log(two) - let one = new StaxParser(two); - let curCont = null; + let strContent = "".fromUtf8(custom.content) + strContent = strContent.slice(strContent.indexOf("<"), strContent.length); // Skip "L" + + console.log('start', strContent); - let tg = new CT_XmlNode(); - let stax = new StaxParser(two, tg); + let oStax = new StaxParser(strContent); + let oCurrentContent = null; + // switch to CT_Node function CustomXMLItem(par, name) { this.parent = par; @@ -16195,6 +16314,8 @@ function Binary_CustomsTableReader(doc, oReadResult, stream) { this.textContent = ""; this.current = undefined; + this.str = ""; + this.AddAttribute = function (name, value) { this.attribute[name] = value; @@ -16202,7 +16323,7 @@ function Binary_CustomsTableReader(doc, oReadResult, stream) { this.AddContent = function (name) { let one = new CustomXMLItem(this, name); - curCont = one; + oCurrentContent = one; this.content.push(one); } this.GetParent = function () @@ -16221,6 +16342,17 @@ function Binary_CustomsTableReader(doc, oReadResult, stream) { if (text !== "") this.textContent += text; } + this.GetStringFromBuffer = function () + { + let buffer = this.GetBuffer(); + let arr = Array.prototype.slice.call(buffer.data.slice(1, buffer.pos)); + let str = String.fromCharCode.apply(null, arr); + str = str.replaceAll(""", "\""); + str = str.replaceAll("&", "&"); + + this.str = str; + return str; + } this.GetBuffer = function () { let writer = new AscCommon.CMemory(); @@ -16231,7 +16363,7 @@ function Binary_CustomsTableReader(doc, oReadResult, stream) { if (!content.name) { - writer.WriteXmlString("\x8B\x00\x00\x00"); + writer.WriteXmlString("\x00"); current = content.content[0]; } else { @@ -16248,8 +16380,6 @@ function Binary_CustomsTableReader(doc, oReadResult, stream) { writer.WriteXmlAttributeStringEncode(cur, current.attribute[cur]); } writer.WriteXmlAttributesEnd(); - writer.WriteXmlString("\r\n"); - for (let i = 0; i < current.content.length; i++) { @@ -16258,12 +16388,9 @@ function Binary_CustomsTableReader(doc, oReadResult, stream) { } if (current.textContent) - { - writer.WriteXmlString(current.textContent); - } + writer.WriteXmlStringEncode(current.textContent.toString()); writer.WriteXmlNodeEnd(current.name); - writer.WriteXmlString("\r\n"); } Write(this); @@ -16271,34 +16398,32 @@ function Binary_CustomsTableReader(doc, oReadResult, stream) { } } - let ParCont = new CustomXMLItem(null); - - curCont = ParCont; + let oParContent = oCurrentContent = new CustomXMLItem(null); - while (one.Read()) + while (oStax.Read()) { - switch (one.GetEventType()) + switch (oStax.GetEventType()) { case EasySAXEvent.CHARACTERS: - curCont.AddTextContent(one.text); + oCurrentContent.AddTextContent(oStax.text); break; case EasySAXEvent.END_ELEMENT: - curCont = curCont.parent; + oCurrentContent = oCurrentContent.parent; break; case EasySAXEvent.START_ELEMENT: - let name = one.GetName(); - curCont.AddContent(name) + let name = oStax.GetName(); + oCurrentContent.AddContent(name) - while (one.MoveToNextAttribute()) + while (oStax.MoveToNextAttribute()) { - let nameAttrib = one.GetName(); - let valueAttrib = one.GetValue(); - curCont.AddAttribute(nameAttrib, valueAttrib); + let nameAttrib = oStax.GetName(); + let valueAttrib = oStax.GetValue(); + oCurrentContent.AddAttribute(nameAttrib, valueAttrib); } break; } } - custom.Content = ParCont; + custom.content = oParContent; this.customXmlManager.add(custom); } else @@ -16308,11 +16433,11 @@ function Binary_CustomsTableReader(doc, oReadResult, stream) { 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.content = this.stream.GetBuffer(length); } else res = c_oSerConstants.ReadUnknown; return res; @@ -17666,3 +17791,6 @@ window["AscCommonWord"].BinaryTableStyleUpdater = BinaryTableStyleUpdater; window["AscCommonWord"].BinaryAbstractNumStyleLinkUpdater = BinaryAbstractNumStyleLinkUpdater; window["AscCommonWord"].BinaryAbstractNumNumStyleLinkUpdater = BinaryAbstractNumNumStyleLinkUpdater; window["AscCommonWord"].BinaryNumLvlStyleUpdater = BinaryNumLvlStyleUpdater; + +//temp +window['AscCommon'].getCustomXmlFromContentControl = getCustomXmlFromContentControl; diff --git a/word/Editor/StructuredDocumentTags/BlockLevel.js b/word/Editor/StructuredDocumentTags/BlockLevel.js index b5ae02d102..0e2488335c 100644 --- a/word/Editor/StructuredDocumentTags/BlockLevel.js +++ b/word/Editor/StructuredDocumentTags/BlockLevel.js @@ -1558,6 +1558,13 @@ CBlockLevelSdt.prototype.fillContentWithDataBinding = function(content) checkBoxPr.SetChecked(true); this.SetCheckBoxPr(checkBoxPr) } + else if (this.IsDatePicker()) + { + let datePr = new AscWord.CSdtDatePickerPr(); + datePr.SetFullDate(content); + this.SetDatePickerPr(datePr); + this.private_UpdateDatePickerContent(); + } else { content = content.replaceAll("<", "<"); @@ -1565,8 +1572,7 @@ CBlockLevelSdt.prototype.fillContentWithDataBinding = function(content) content = content.replaceAll("", ""); content = content.replaceAll("", ""); let zLib = new AscCommon.ZLib; - let zip = zLib.create(); - + zLib.create(); let nPos = 0; zLib.addFile('[Content_Types].xml', new TextEncoder("utf-8").encode('' + @@ -1623,9 +1629,24 @@ CBlockLevelSdt.prototype.fillContentWithDataBinding = function(content) let nPosEndName = strText.indexOf('"', nPosStartName); let name = strText.substring(nPosStartName, nPosEndName); - let nDataStartPos = strText.indexOf('', 0) + ''.length; - let nDataEndPos = strText.indexOf('', nDataStartPos); - //nPos = nDataEndPos + ''.length; + 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); @@ -1653,9 +1674,8 @@ CBlockLevelSdt.prototype.fillContentWithDataBinding = function(content) oBinaryFileReader.PostLoadPrepare(xmlParserContext); jsZlib.close(); - debugger - this.Content.RemoveFromContent(0, 1); + this.Content.RemoveFromContent(0, this.Content.Content.length); this.Content.AddContent(Doc.Content); this.Content.Recalculate(true); } @@ -1787,6 +1807,8 @@ CBlockLevelSdt.prototype.CanBeDeleted = function() */ CBlockLevelSdt.prototype.CanBeEdited = function() { + //for debugging pictures + this.SkipSpecialLock = true; if (!this.SkipSpecialLock && (this.IsCheckBox() || this.IsPicture() || this.IsDropDownList())) return false; @@ -2116,6 +2138,12 @@ CBlockLevelSdt.prototype.private_UpdateCheckBoxContent = function() oRun.SetRFontsCS({Index : -1, Name : this.Pr.CheckBox.UncheckedFont}); oRun.SetRFontsEastAsia({Index : -1, Name : this.Pr.CheckBox.UncheckedFont}); } + + if (this.Pr.DataBinding) + { + let CustomManager = this.LogicDocument.getCustomXmlManager(); + CustomManager.setContentByDataBinding(this.Pr.DataBinding, isChecked ? "true" : "false"); + } }; /** * Проверяем, является ли данный класс специальным контейнером для картинки @@ -2303,6 +2331,12 @@ CBlockLevelSdt.prototype.SelectListItem = function(sValue) var sText = oList.GetTextByValue(sValue); + if (this.Pr.DataBinding) + { + let CustomManager = this.LogicDocument.getCustomXmlManager(); + CustomManager.setContentByDataBinding(this.Pr.DataBinding, sText); + } + if (this.LogicDocument && this.LogicDocument.IsTrackRevisions()) { if (!sText && this.IsPlaceHolder()) @@ -2452,6 +2486,12 @@ CBlockLevelSdt.prototype.private_UpdateDatePickerContent = function() var oRun; var sText = this.Pr.Date.ToString(); + if (this.Pr.DataBinding) + { + let CustomManager = this.LogicDocument.getCustomXmlManager(); + CustomManager.setContentByDataBinding(this.Pr.DataBinding, sText); + } + if (this.LogicDocument && this.LogicDocument.IsTrackRevisions()) { if (!sText && this.IsPlaceHolder()) diff --git a/word/Editor/StructuredDocumentTags/SdtBase.js b/word/Editor/StructuredDocumentTags/SdtBase.js index 1641c898ce..49cf03e9a1 100644 --- a/word/Editor/StructuredDocumentTags/SdtBase.js +++ b/word/Editor/StructuredDocumentTags/SdtBase.js @@ -1084,7 +1084,7 @@ CSdtBase.prototype.checkDataBinding = function() if (!logicDocument || !this.Pr.DataBinding) return; - let content = logicDocument.getCustomXmlManager().getContentByDataBinding(this.Pr.DataBinding); + let content = logicDocument.getCustomXmlManager().getContentByDataBinding(this.Pr.DataBinding, this); if (!content) return; diff --git a/word/Editor/custom-xml/custom-xml-manager.js b/word/Editor/custom-xml/custom-xml-manager.js index fdebb9667e..426c523d6e 100644 --- a/word/Editor/custom-xml/custom-xml-manager.js +++ b/word/Editor/custom-xml/custom-xml-manager.js @@ -58,56 +58,74 @@ { return this.xml[index]; }; - CustomXmlManager.prototype.getContentByDataBinding = function(dataBinding) + CustomXmlManager.prototype.findElementsByXPath = function (root, xpath) + { + let parts = xpath.split('/'); + parts.shift(); // Убираем пустой первый элемент + + let currentElement = root; + + for (let i = 0; i < parts.length; i++) { + let part = parts[i]; + let namespaceAndTag = part.split('[')[0]; + let index = parseInt(part.split('[')[1].slice(0, -1)) - 1; + let tagName = namespaceAndTag.split(':')[1]; + + 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) { + return null; // Элемент не найден + } + + currentElement = matchingChildren[index]; + } + + return currentElement; + } + 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) + if (dataBinding.storeItemID === customXml.itemId) { let xPath = dataBinding.xpath; - - function findElementsByXPath(root, xpath) { - var parts = xpath.split('/'); - parts.shift(); // Убираем пустой первый элемент - - var currentElement = root; - - for (var i = 0; i < parts.length; i++) { - var part = parts[i]; - var namespaceAndTag = part.split('[')[0]; - var index = parseInt(part.split('[')[1].slice(0, -1)) - 1; - var tagName = namespaceAndTag.split(':')[1]; - - var 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) { - return null; // Элемент не найден - } - - currentElement = matchingChildren[index]; - } - - return currentElement.textContent; - } - - return findElementsByXPath(customXml.Content, xPath); + + let content = this.findElementsByXPath(customXml.content, xPath); + return content.textContent; } } }; + 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 content = this.findElementsByXPath(customXml.content, xPath); + content.textContent = data; + } + } + } //--------------------------------------------------------export---------------------------------------------------- window['AscWord'] = window['AscWord'] || {}; diff --git a/word/Editor/custom-xml/custom-xml.js b/word/Editor/custom-xml/custom-xml.js index 0ea2d0ec6c..3ec60aa0b6 100644 --- a/word/Editor/custom-xml/custom-xml.js +++ b/word/Editor/custom-xml/custom-xml.js @@ -37,11 +37,12 @@ /** * @constructor */ - function CustomXml() + function CustomXml(uri, itemId, content, oContentLink) { - this.uri = []; - this.itemID = ""; - this.content = null; + this.uri = uri ? uri : []; + this.itemId = itemId ? itemId : ""; + this.content = content ? content : null; + this.oContentLink = oContentLink ? oContentLink : null; } //--------------------------------------------------------export---------------------------------------------------- diff --git a/word/Editor/custom-xml/data-binding.js b/word/Editor/custom-xml/data-binding.js index 7c9f3f400a..a50c7c8a12 100644 --- a/word/Editor/custom-xml/data-binding.js +++ b/word/Editor/custom-xml/data-binding.js @@ -37,16 +37,194 @@ /** * @constructor */ - function DataBinding(prefix, itemID, xpath) + function DataBinding(prefix, itemID, xpath, checkSum) { - this.prefixMappings = prefix ? prefix : undefined; - this.storeItemID = itemID ? itemID : undefined; - this.xpath = xpath ? xpath : undefined; + 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); + return new DataBinding(this.prefixMappings, this.storeItemID, this.xpath, this.storeItemCheckSum); }; + DataBinding.prototype.recalculateCheckSum = function (stringOfCustomXMlContent) + { + // let str = stringOfCustomXMlContent; +// const encoder = new TextEncoder(); +// stringOfCustomXMlContent = encoder.encode(stringOfCustomXMlContent); +// +// function calculateMsoCrc32Utf8(data) { +// const polynomial = 0xAF; // Полином x^32+x^7+x^5+x^3+x^2+x+1 +// let crc = 0xFFFFFFFF; // Начальное значение +// +// for (let i = 0; i < data.length; i++) { +// let code = data.charCodeAt(i); +// +// if (code < 0x80) { +// code = code & 0xFF; // Приводим к однобайтовому значению +// crc ^= (code << 24); +// } else if (code < 0x800) { +// crc ^= ((0xC0 | (code >> 6)) << 24); +// crc ^= ((0x80 | (code & 0x3F)) << 24); +// } else if (code < 0x10000) { +// crc ^= ((0xE0 | (code >> 12)) << 24); +// crc ^= ((0x80 | ((code >> 6) & 0x3F)) << 24); +// crc ^= ((0x80 | (code & 0x3F)) << 24); +// } else { +// crc ^= ((0xF0 | (code >> 18)) << 24); +// crc ^= ((0x80 | ((code >> 12) & 0x3F)) << 24); +// crc ^= ((0x80 | ((code >> 6) & 0x3F)) << 24); +// crc ^= ((0x80 | (code & 0x3F)) << 24); +// } +// +// for (let j = 0; j < 8; j++) { +// if ((crc & 0x80000000) !== 0) { +// crc = (crc << 1) ^ polynomial; +// } else { +// crc <<= 1; +// } +// } +// } +// +// return crc >>> 0; // Возвращаем беззнаковое 32-битное значение +// } +// +// +// +// function calculateCRC(data) { +// const polynomial = 0xAF; // Полином x32+x7+x5+x3+x2+x+1 +// let crc = 0xFFFFFFFF; // Начальное значение +// +// for (let i = 0; i < data.length; i++) { +// let code = data.charCodeAt(i); +// +// if (code < 0x80) { +// crc ^= (code << 24); +// } else if (code < 0x800) { +// crc ^= ((0xC0 | (code >> 6)) << 24); +// crc ^= ((0x80 | (code & 0x3F)) << 24); +// } else if (code < 0x10000) { +// crc ^= ((0xE0 | (code >> 12)) << 24); +// crc ^= ((0x80 | ((code >> 6) & 0x3F)) << 24); +// crc ^= ((0x80 | (code & 0x3F)) << 24); +// } else { +// crc ^= ((0xF0 | (code >> 18)) << 24); +// crc ^= ((0x80 | ((code >> 12) & 0x3F)) << 24); +// crc ^= ((0x80 | ((code >> 6) & 0x3F)) << 24); +// crc ^= ((0x80 | (code & 0x3F)) << 24); +// } +// +// for (let j = 0; j < 8; j++) { +// if ((crc & 0x80000000) !== 0) { +// crc = (crc << 1) ^ polynomial; +// } else { +// crc <<= 1; +// } +// } +// } +// +// return crc >>> 0; +// } +// +// function CRC(CrcValue, data) { +// for (let i = 0; i < data.length; i++) { +// let byte = data.charCodeAt(i); +// +// let index = CrcValue; +// index = (index >>> 24) ^ byte; +// +// CrcValue <<= 8; +// CrcValue ^= index; // Просто XOR с байтом +// } +// +// return CrcValue >>> 0; // Возвращаем беззнаковое 32-битное значение +// } +// +// const crcResult = CRC( 0xFFFFFFFF, str); +// const byteArray = [ +// (crcResult >> 24) & 0xFF, +// (crcResult >> 16) & 0xFF, +// (crcResult >> 8) & 0xFF, +// crcResult & 0xFF +// ]; +// +// const base64Value = bytesToBase64(byteArray); +// console.log(base64Value) +// +// function bytesToBase64(bytes) { +// const base64Chars = +// 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; +// +// let result = ''; +// let i = 0; +// +// while (i < bytes.length) { +// const byte1 = bytes[i++] & 0xff; +// const byte2 = bytes[i++] & 0xff; +// const byte3 = bytes[i++] & 0xff; +// +// const enc1 = byte1 >> 2; +// const enc2 = ((byte1 & 3) << 4) | (byte2 >> 4); +// const enc3 = ((byte2 & 15) << 2) | (byte3 >> 6); +// const enc4 = byte3 & 63; +// +// if (isNaN(byte2)) { +// enc3 = enc4 = 64; +// } else if (isNaN(byte3)) { +// enc4 = 64; +// } +// +// result += +// base64Chars.charAt(enc1) + +// base64Chars.charAt(enc2) + +// base64Chars.charAt(enc3) + +// base64Chars.charAt(enc4); +// } +// +// return result; +// } +// +// +// +// +// console.log(calculateCRC(str)); +// +// //check +// const CRC32_POLY = 0x04C11DB7; +// let crc32TableArray = new Array(256); +// let crcValue = 0xFFFFFFFF; +// +// // InitializationOfCRC32TableArray Function +// function initializeCRC32TableArray() { +// for (let iValue = 0; iValue < crc32TableArray.length; iValue++) { +// let cValue = iValue << 24; +// for (let jValue = 8; jValue > 0; jValue--) { +// cValue = (cValue & 0x80000000) ? ((cValue << 1) ^ CRC32_POLY) : (cValue << 1); +// crc32TableArray[iValue] = cValue; +// } +// } +// } +// +// // Calculation of crc32Value +// function calculateCRC32Value(pBuffer, cLength) { +// for (let i = 0; i < cLength; i++) { +// let tempIndex = (crcValue >>> 24) ^ pBuffer[i]; +// crcValue = (crcValue << 8) ^ crc32TableArray[tempIndex]; +// } +// } +// +// initializeCRC32TableArray(); +// const buffer = stringOfCustomXMlContent; +// const bufferLength = buffer.length; +// calculateCRC32Value(buffer, bufferLength); +// console.log("CRC32 Value:", crcValue); +// +// +// let crc = AscCommon.g_oCRC32.Calculate_ByString(str, str.length); +// console.log(crc) +// this.storeItemCheckSum = AscCommon.Base64.encode(crcValue.toString()); + } DataBinding.prototype.toBinary = function(writer) { return this.Write_ToBinary(writer); diff --git a/word/api.js b/word/api.js index 172df2fda7..54cc0c86c3 100644 --- a/word/api.js +++ b/word/api.js @@ -10415,6 +10415,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(); From 54d29c47c92060da20db160bfd8d35a272f09c5a Mon Sep 17 00:00:00 2001 From: EvgeniyIgol Date: Fri, 2 Aug 2024 17:58:48 +0300 Subject: [PATCH 11/22] Fix write custom xml for rich text content control --- word/Editor/Serialize2.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/word/Editor/Serialize2.js b/word/Editor/Serialize2.js index 3fb9ff37a0..8f084afaf2 100644 --- a/word/Editor/Serialize2.js +++ b/word/Editor/Serialize2.js @@ -7661,8 +7661,8 @@ function getCustomXmlFromContentControl(customXml) ctfText = replaceSubstring(ctfText, nStart, nEnd, text); } - outputUString += "" + + outputUString += " " + "" + ctfText.replace("", "").replace("\n", "") + "" } }); From 3eaed98c42aed388ff4581e094c700bab4461357 Mon Sep 17 00:00:00 2001 From: EvgeniyIgol Date: Tue, 6 Aug 2024 16:33:49 +0300 Subject: [PATCH 12/22] [de] Improve CustomXMl processing for ComboBox and DropDownList --- word/Editor/Serialize2.js | 170 +++++++++--------- .../StructuredDocumentTags/BlockLevel.js | 31 +++- 2 files changed, 112 insertions(+), 89 deletions(-) diff --git a/word/Editor/Serialize2.js b/word/Editor/Serialize2.js index 8f084afaf2..72b64b4ec0 100644 --- a/word/Editor/Serialize2.js +++ b/word/Editor/Serialize2.js @@ -7592,109 +7592,115 @@ function BinaryNotesTableWriter(memory, doc, oNumIdMap, oMapCommentId, copyParam //temp location -function getCustomXmlFromContentControl(customXml) +function getCustomXmlFromContentControl(customXml, customXmlManager) { - let oContent = customXml.oContentLink; - - let writer = new AscCommon.CMemory() - writer.context = new AscCommon.XmlWriterContext(AscCommon.c_oEditorId.Word); - writer.context.docSaveParams = new DocSaveParams(undefined, undefined, false, undefined); - - let drawDoc = new AscCommon.CDrawingDocument(); - drawDoc.m_oWordControl = drawDoc - drawDoc.m_oWordControl.m_oApi = window.editor; - let doc = new AscWord.CDocument(drawDoc); - doc.ReplaceContent(oContent.Content.Content); - - let jsZlib = new AscCommon.ZLib(); - jsZlib.create(); - doc.toZip(jsZlib, new AscCommon.XmlWriterContext(AscCommon.c_oEditorId.Word)); - let data = jsZlib.save(); - let jsZlib2 = new AscCommon.ZLib(); - jsZlib2.open(data); - - var openDoc = new AscCommon.openXml.OpenXmlPackage(jsZlib2, null); - - let outputUString = "\n" + - "\n" + - ""; - 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); + + const prefix = originalString.substring(0, startPoint); + const suffix = originalString.substring(endPoint + 1); + return prefix + insertionString + suffix; } - jsZlib2.files.forEach(function(path){ - if ((path === "_rels/.rels" || path === "word/document.xml" || path === "word/_rels/document.xml.rels") && !path.includes("glossary")) - { - let ctfBytes = jsZlib2.getFile(path); - let ctfText = AscCommon.UTF8ArrayToString(ctfBytes, 0, ctfBytes.length); - let type = openDoc.getContentType(path); - console.log(ctfText, openDoc, type) + let oContent = customXml.oContentLink; + let oDataBinding = oContent.GetDataBinding(); + + if (oContent.IsCheckBox() || oContent.IsDatePicker() || oContent.IsPicture() || oContent.IsDropDownList() || oContent.IsComboBox()) + { + return customXml.content.GetStringFromBuffer(); + } + else + { + let writer = new AscCommon.CMemory(); + writer.context = new AscCommon.XmlWriterContext(AscCommon.c_oEditorId.Word); + writer.context.docSaveParams = new DocSaveParams(undefined, undefined, false, undefined); + + let drawDoc = new AscCommon.CDrawingDocument(); + drawDoc.m_oWordControl = drawDoc; + drawDoc.m_oWordControl.m_oApi = window.editor; + let doc = new AscWord.CDocument(drawDoc); + + doc.ReplaceContent(oContent.Content.Content); - if (path === "word/_rels/document.xml.rels") + let jsZlib = new AscCommon.ZLib(); + jsZlib.create(); + doc.toZip(jsZlib, new AscCommon.XmlWriterContext(AscCommon.c_oEditorId.Word)); + + let data = jsZlib.save(); + let jsZlib2 = new AscCommon.ZLib(); + jsZlib2.open(data); + var openDoc = new AscCommon.openXml.OpenXmlPackage(jsZlib2, null); + + let outputUString = "\n" + + "\n" + + ""; + + jsZlib2.files.forEach(function(path) { + if ((path === "_rels/.rels" || path === "word/document.xml" || path === "word/_rels/document.xml.rels") && !path.includes("glossary")) { - let text = ''; - let arrRelationships = openDoc.getRelationships(); - for (let i = 0; i < arrRelationships.length; i++) + let ctfBytes = jsZlib2.getFile(path); + let ctfText = AscCommon.UTF8ArrayToString(ctfBytes, 0, ctfBytes.length); + let type = openDoc.getContentType(path); + + if (path === "word/_rels/document.xml.rels") { - let relation = arrRelationships[i]; - let relId = relation.relationshipId; - let relType = relation.relationshipType; - let relTarget = relation.target; - if(i===0) + let text = ''; + let arrRelationships = openDoc.getRelationships(); + for (let i = 0; i < arrRelationships.length; i++) { - relType = relType.replace("relationships\/officeDocument", "relationships\/styles"); - relTarget = relTarget.replace("word/document.xml", "styles.xml"); + 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 += "" } - text += "" + let nStart = ctfText.indexOf("", 0) + "".length; + let nEnd = ctfText.indexOf("", nStart) - 1; + ctfText = replaceSubstring(ctfText, nStart, nEnd, 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 += " " + - "" + ctfText.replace("", "").replace("\n", "") + "" - } - }); - - //check diffrences between main write and this, when save main document higlight write correct - outputUString = outputUString.replace("FFFF00", "yellow"); - - //need get contentType from openXml.Types - outputUString = outputUString.replace("pkg:contentType=\"application/xml\"", "pkg:contentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml\""); - outputUString = outputUString.replace("pkg:contentType=\"application/vnd.openxmlformats-package.relationships+xml\"", "pkg:contentType=\"application/vnd.openxmlformats-package.relationships+xml\" pkg:padding=\"512\"") - outputUString = outputUString.replace("\"/word/_rels/document.xml.rels\"pkg:contentType=\"application/vnd.openxmlformats-package.relationships+xml\"", "\"/word/_rels/document.xml.rels\"pkg:contentType=\"application/vnd.openxmlformats-package.relationships+xml\" pkg:padding=\"256\"") + //check diffrences between main write and this, when save main document higlight write correct + // outputUString = outputUString.replace("FFFF00", "yellow"); - outputUString += ""; + //need get contentType from openXml.Types + outputUString = outputUString.replace("pkg:contentType=\"application/xml\"", "pkg:contentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml\""); + outputUString = outputUString.replace("pkg:contentType=\"application/vnd.openxmlformats-package.relationships+xml\"", "pkg:contentType=\"application/vnd.openxmlformats-package.relationships+xml\" pkg:padding=\"512\"") + outputUString = outputUString.replace("\"/word/_rels/document.xml.rels\"pkg:contentType=\"application/vnd.openxmlformats-package.relationships+xml\"", "\"/word/_rels/document.xml.rels\"pkg:contentType=\"application/vnd.openxmlformats-package.relationships+xml\" pkg:padding=\"256\"") - //create flat xml - outputUString = outputUString.replaceAll("<", "<"); - outputUString = outputUString.replaceAll(">", ">"); + outputUString += ""; - let str = customXml.content.GetStringFromBuffer(); - let nStartIndex = str.indexOf("") + ''.length; - let nEndIndex = str.indexOf("/pkg:package>") + '/pkg:package>'.length ; + //create flat xml + outputUString = outputUString.replaceAll("<", "<"); + outputUString = outputUString.replaceAll(">", ">"); - str = replaceSubstring(str, nStartIndex, nEndIndex, outputUString); + let str = customXml.content.GetStringFromBuffer(); + let nStartIndex = str.indexOf("") + ''.length; + let nEndIndex = str.indexOf("/pkg:package>") + '/pkg:package>'.length ; - //for now hardcode - str = str.replace("", "") + str = replaceSubstring(str, nStartIndex, nEndIndex, outputUString); - // nStartIndex = str.indexOf("") + ''.length; - // nEndIndex = str.indexOf("/pkg:package>") + '/pkg:package>'.length ; - //customXml.oContentLink.Pr.DataBinding.recalculateCheckSum(str.substring(nStartIndex, nEndIndex)); + // nStartIndex = str.indexOf("") + ''.length; + // nEndIndex = str.indexOf("/pkg:package>") + '/pkg:package>'.length ; + //customXml.oContentLink.Pr.DataBinding.recalculateCheckSum(str.substring(nStartIndex, nEndIndex)); - return str; + return str; + } } function BinaryCustomsTableWriter(memory, doc, customXmlManager) @@ -7723,14 +7729,14 @@ function BinaryCustomsTableWriter(memory, doc, customXmlManager) 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); }); } - if (null !== customXml.Content) { + if (null !== customXml.content) { this.bs.WriteItem(c_oSerCustoms.ContentA, function() { - let str = getCustomXmlFromContentControl(customXml); + let str = getCustomXmlFromContentControl(customXml, customXmlManager); oThis.memory.WriteCustomStringA(str); }); } @@ -16197,8 +16203,6 @@ function Binary_CustomsTableReader(doc, oReadResult, stream) { let strContent = "".fromUtf8(custom.content) strContent = strContent.slice(strContent.indexOf("<"), strContent.length); // Skip "L" - console.log('start', strContent); - let oStax = new StaxParser(strContent); let oCurrentContent = null; diff --git a/word/Editor/StructuredDocumentTags/BlockLevel.js b/word/Editor/StructuredDocumentTags/BlockLevel.js index 518498ae01..f5fa24a4c7 100644 --- a/word/Editor/StructuredDocumentTags/BlockLevel.js +++ b/word/Editor/StructuredDocumentTags/BlockLevel.js @@ -594,6 +594,15 @@ 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]; + + let CustomManager = this.LogicDocument.getCustomXmlManager(); + CustomManager.setContentByDataBinding(this.Pr.DataBinding, Item.GetText()); + } + if (isRemoveWrapper) this.RemoveContentControlWrapper(); }; @@ -1580,6 +1589,16 @@ CBlockLevelSdt.prototype.fillContentWithDataBinding = function(content) this.SetDatePickerPr(datePr); this.private_UpdateDatePickerContent(); } + else if (this.IsDropDownList() || this.IsComboBox()) + { + let oRun = new ParaRun(); + oRun.AddText(content); + + // now style reset todo + this.Content.Remove_FromContent(0, this.Content.Content.length); + + this.Content.AddToParagraph(oRun); + } else { content = content.replaceAll("<", "<"); @@ -2346,12 +2365,6 @@ CBlockLevelSdt.prototype.SelectListItem = function(sValue) var sText = oList.GetTextByValue(sValue); - if (this.Pr.DataBinding) - { - let CustomManager = this.LogicDocument.getCustomXmlManager(); - CustomManager.setContentByDataBinding(this.Pr.DataBinding, sText); - } - if (this.LogicDocument && this.LogicDocument.IsTrackRevisions()) { if (!sText && this.IsPlaceHolder()) @@ -2428,6 +2441,12 @@ CBlockLevelSdt.prototype.SelectListItem = function(sValue) var oRun = this.private_UpdateListContent(); if (oRun) oRun.AddText(sText); + + if (this.Pr.DataBinding) + { + let CustomManager = this.LogicDocument.getCustomXmlManager(); + CustomManager.setContentByDataBinding(this.Pr.DataBinding, sText); + } } } }; From ce074cd9fdb5ddcf3a892e2428de7e704315cb22 Mon Sep 17 00:00:00 2001 From: EvgeniyIgol Date: Thu, 8 Aug 2024 13:08:15 +0300 Subject: [PATCH 13/22] [de] Improve CustomXML processing - fix fillContentWithDataBinding for text content control - fix findElementsByXPath for nonexistence of namespace - move parseCustomXML and getCustomXMLString in CustomXmlManager - add more tests for Load\Save CustomXml (CheckBox and Date content controls) --- tests/word/customXML/customXML.html | 2 - tests/word/customXML/customXML.js | 526 +++++++----------- word/Editor/Serialize2.js | 126 +---- .../StructuredDocumentTags/BlockLevel.js | 2 +- word/Editor/custom-xml/custom-xml-manager.js | 255 ++++++++- 5 files changed, 469 insertions(+), 442 deletions(-) diff --git a/tests/word/customXML/customXML.html b/tests/word/customXML/customXML.html index 23f3848a72..3db4d28ddd 100644 --- a/tests/word/customXML/customXML.html +++ b/tests/word/customXML/customXML.html @@ -22,8 +22,6 @@ - - diff --git a/tests/word/customXML/customXML.js b/tests/word/customXML/customXML.js index a865004df6..fae2301d12 100644 --- a/tests/word/customXML/customXML.js +++ b/tests/word/customXML/customXML.js @@ -31,248 +31,113 @@ */ $(function () { - - //something (zlib engine) does not have time to load, for now need to leave this line of code here - debugger - //==== - - AscCommon.zlib_load(function (){return true},function (){return false}) - window.onZlibEngineInit() - let logicDocument = AscTest.CreateLogicDocument(); let custom; + let oXMLManager = logicDocument.getCustomXmlManager(); - function proceedCustomXml(strXml) + function CreateContentControl() + { + let cc = new AscWord.CBlockLevelSdt(logicDocument); + cc.SetPlaceholder(c_oAscDefaultPlaceholderName.Text); + cc.ReplacePlaceHolderWithContent(); + cc.SetShowingPlcHdr(false); + return cc; + } + 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 oStax = new StaxParser(strXml); + let oContent = oXMLManager.parseCustomXML(strContent); + let oXML = new AscWord.CustomXml(); - // switch to CT_Node - function CustomXMLItem(par, name) - { - this.parent = par; - this.content = []; - this.name = name ? name : ""; - this.attribute = {}; - this.textContent = ""; - this.current = undefined; - - this.str = ""; - - this.AddAttribute = function (name, value) - { - this.attribute[name] = value; - } - this.AddContent = function (name) - { - let one = new CustomXMLItem(this, name); - oCurrentContent = one; - this.content.push(one); - } - this.GetParent = function () - { - if (this.parent) - return this.parent; - - return null; - } - this.SetParent = function (oPar) - { - this.parent = oPar; - } - this.AddTextContent = function (text) - { - if (text !== "") - this.textContent += text; - } - this.GetStringFromBuffer = function () - { - let buffer = this.GetBuffer(); - let arr = Array.prototype.slice.call(buffer.data.slice(1, buffer.pos)); - let str = String.fromCharCode.apply(null, arr); - str = str.replaceAll(""", "\""); - str = str.replaceAll("&", "&"); - - this.str = str; - return str; - } - this.GetBuffer = function () - { - let writer = new AscCommon.CMemory(); - - function Write(content) - { - let current = null; - - if (!content.name) - { - writer.WriteXmlString("\x00"); - current = content.content[0]; - } else - { - current = content; - } - - 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++) - { - let curContent = current.content[i]; - Write(curContent); - } - - if (current.textContent) - writer.WriteXmlStringEncode(current.textContent.toString()); - - writer.WriteXmlNodeEnd(current.name); - } - - Write(this); - return writer; - } - } + oXML.itemId = ItemId === undefined + ? "{694325A8-B1C9-407B-A2C2-E2DD1740AA5E}" + : ItemId; - let oParentContent; - let oCurrentContent = oParentContent = new CustomXMLItem(null); + oXML.uri = Uri === undefined + ? ['http://example.com/picture'] + : Uri; - while (oStax.Read()) - { - switch (oStax.GetEventType()) - { - case EasySAXEvent.CHARACTERS: - oCurrentContent.AddTextContent(oStax.text); - break; - case EasySAXEvent.END_ELEMENT: - oCurrentContent = oCurrentContent.parent; - break; - case EasySAXEvent.START_ELEMENT: - let name = oStax.GetName(); - oCurrentContent.AddContent(name) - - while (oStax.MoveToNextAttribute()) - { - let nameAttrib = oStax.GetName(); - let valueAttrib = oStax.GetValue(); - oCurrentContent.AddAttribute(nameAttrib, valueAttrib); - } - break; - } - } + oXML.content = strContent === undefined + ? oXMLManager.parseCustomXML(oCustomXMLs.withoutContent) + : oContent; - return oParentContent + oXMLManager.add(oXML); + } + + const oCustomXMLData = { + date: "2000-01-01", + 'checkboxTrue': true, + 'checkboxFalse': false, + 'checkbox0': 0, + 'checkbox1': 1, + 'checkboxMess': "hello", + } + 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\"", + + 'checkboxTrueAnotherXML': "\n " + oCustomXMLData.checkboxTrue + "", } - function getXml(arrStr) + + function CreateDateCC(nPos) { - let start = '\n' + - '\n' + - ' <?xml version="1.0" standalone="yes"?>\n' + - ' <?mso-application progid="Word.Document"?>\n' + - ' <pkg:package xmlns:pkg="http://schemas.microsoft.com/office/2006/xmlPackage"><pkg:part\n' + - ' pkg:name="/_rels/.rels" pkg:contentType="application/vnd.openxmlformats-package.relationships+xml"\n' + - ' pkg:padding="512"><pkg:xmlData><Relationships\n' + - ' xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1"\n' + - ' Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"\n' + - ' Target="word/document.xml"/></Relationships></pkg:xmlData></pkg:part><pkg:part\n' + - ' pkg:name="/word/document.xml"\n' + - ' pkg:contentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"><pkg:xmlData><w:document\n' + - ' xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas"\n' + - ' xmlns:cx="http://schemas.microsoft.com/office/drawing/2014/chartex"\n' + - ' xmlns:cx1="http://schemas.microsoft.com/office/drawing/2015/9/8/chartex"\n' + - ' xmlns:cx2="http://schemas.microsoft.com/office/drawing/2015/10/21/chartex"\n' + - ' xmlns:cx3="http://schemas.microsoft.com/office/drawing/2016/5/9/chartex"\n' + - ' xmlns:cx4="http://schemas.microsoft.com/office/drawing/2016/5/10/chartex"\n' + - ' xmlns:cx5="http://schemas.microsoft.com/office/drawing/2016/5/11/chartex"\n' + - ' xmlns:cx6="http://schemas.microsoft.com/office/drawing/2016/5/12/chartex"\n' + - ' xmlns:cx7="http://schemas.microsoft.com/office/drawing/2016/5/13/chartex"\n' + - ' xmlns:cx8="http://schemas.microsoft.com/office/drawing/2016/5/14/chartex"\n' + - ' xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"\n' + - ' xmlns:aink="http://schemas.microsoft.com/office/drawing/2016/ink"\n' + - ' xmlns:am3d="http://schemas.microsoft.com/office/drawing/2017/model3d"\n' + - ' xmlns:o="urn:schemas-microsoft-com:office:office"\n' + - ' xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"\n' + - ' xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml"\n' + - ' xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing"\n' + - ' xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing"\n' + - ' xmlns:w10="urn:schemas-microsoft-com:office:word"\n' + - ' xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"\n' + - ' xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml"\n' + - ' xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml"\n' + - ' xmlns:w16cex="http://schemas.microsoft.com/office/word/2018/wordml/cex"\n' + - ' xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid"\n' + - ' xmlns:w16="http://schemas.microsoft.com/office/word/2018/wordml"\n' + - ' xmlns:w16sdtdh="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash"\n' + - ' xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex"\n' + - ' xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup"\n' + - ' xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk"\n' + - ' xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml"\n' + - ' xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 w15 w16se w16cid\n' + - ' w16 w16cex w16sdtdh wp14"\n' + - ' ><w:body>'; - - arrStr.forEach(str => start += '<w:p><w:r><w:t>' + str + '</w:t></w:r></w:p>') - - start += '</w:body></w:document></pkg:xmlData></pkg:part><pkg:part\n' + - ' pkg:name="/word/_rels/document.xml.rels"\n' + - ' pkg:contentType="application/vnd.openxmlformats-package.relationships+xml" pkg:padding="256"><pkg:xmlData><Relationships\n' + - ' xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1"\n' + - ' Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/></Relationships></pkg:xmlData></pkg:part><pkg:part\n' + - ' pkg:name="/word/styles.xml"\n' + - ' pkg:contentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"><pkg:xmlData><w:styles\n' + - ' xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"\n' + - ' xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"\n' + - ' xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main"\n' + - ' xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml"\n' + - ' xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml"\n' + - ' xmlns:w16cex="http://schemas.microsoft.com/office/word/2018/wordml/cex"\n' + - ' xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid"\n' + - ' xmlns:w16="http://schemas.microsoft.com/office/word/2018/wordml"\n' + - ' xmlns:w16sdtdh="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash"\n' + - ' xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" mc:Ignorable="w14 w15 w16se w16cid w16\n' + - ' w16cex w16sdtdh"><w:docDefaults><w:rPrDefault><w:rPr><w:rFonts w:asciiTheme="minorHAnsi"\n' + - ' w:eastAsiaTheme="minorHAnsi" w:hAnsiTheme="minorHAnsi" w:cstheme="minorBidi"/><w:sz w:val="22"/><w:szCs\n' + - ' 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\n' + - ' w:after="160" w:line="259" w:lineRule="auto"/></w:pPr></w:pPrDefault></w:docDefaults><w:style\n' + - ' w:type="paragraph" w:default="1" w:styleId="a"><w:name w:val="Normal"/><w:qFormat/><w:pPr><w:spacing\n' + - ' w:after="200" w:line="276" w:lineRule="auto"/></w:pPr></w:style><w:style w:type="character"\n' + - ' 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\n' + - ' 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\n' + - ' w:w="0" w:type="dxa"/><w:tblCellMar><w:top w:w="0" w:type="dxa"/><w:left w:w="108"\n' + - ' 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\n' + - ' 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>\n' + - ' \n' + - '' - - return start + let cc = CreateFilledContentControl(nPos) + let dateTimePr = new AscWord.CSdtDatePickerPr(); + cc.ApplyDatePickerPr(dateTimePr, true); + return cc; } - function CreateContentControl() + function CreateCheckBoxCC(nPos) { - let cc = new AscWord.CBlockLevelSdt(logicDocument); - cc.SetPlaceholder(c_oAscDefaultPlaceholderName.Text); - cc.ReplacePlaceHolderWithContent(); - cc.SetShowingPlcHdr(false); + let cc = CreateFilledContentControl(nPos) + let checkboxPr = new AscWord.CSdtCheckBoxPr(); + cc.ApplyCheckBoxPr(checkboxPr); + return cc; + } + function CreateComboBox(nPos) + { + let cc = CreateFilledContentControl(nPos); + let comboBoxPr = new AscWord.CSdtComboBoxPr(); + cc.ApplyComboBoxPr(comboBoxPr, true); + return cc; + } + function CreatePicture(nPos) + { + let cc = CreateFilledContentControl(nPos); + let picturePr = new AscWord.CSdtPictureFormPr(); + cc.ApplyPicturePr(picturePr); return cc; } - function CreateFilledContentControl() + function CreateText(nPos) + { + let cc = CreateFilledContentControl(nPos); + let textPr = new AscWord.CSdtTextFormPr(); + cc.ApplyTextFormPr(textPr); + return cc; + } + + function CreateFilledContentControl(nPos) { let cc = CreateContentControl(); let docContent = cc.GetContent(); docContent.ClearContent(false); - let d1 = new AscWord.DataBinding(); - d1.prefixMappings = "xmlns:ns0='http://example.com/picture' "; - d1.storeItemID = "{694325A8-B1C9-407B-A2C2-E2DD1740AA5E}"; - d1.xpath = "/ns0:documentData[1]/ns0:simpleText[1]"; - d1.storeItemCheckSum = "Gt6wYg=="; - cc.Pr.DataBinding = d1; - + logicDocument.AddToContent(nPos, cc); return cc; } function CheckContentParagraph(assert, oContentArr, arrSample) @@ -284,108 +149,143 @@ $(function () { assert.strictEqual(oCurStr, oCurContent, oCurContent); } } - function updateXML(strXml) - { - custom = new AscWord.CustomXml(); - custom.itemId ="{694325A8-B1C9-407B-A2C2-E2DD1740AA5E}"; - custom.uri = ['http://example.com/picture']; - custom.content = proceedCustomXml(strXml); - logicDocument.customXml.add(custom) - } - function formatXml(xml) { - var formatted = ''; - var reg = /(>)(<)(\/*)/g; - xml = xml.replace(reg, '$1\r\n$2$3'); - var pad = 0; - jQuery.each(xml.split('\r\n'), function(index, node) { - var indent = 0; - if (node.match( /.+<\/\w[^>]*>$/ )) { - indent = 0; - } else if (node.match( /^<\/\w/ )) { - if (pad != 0) { - pad -= 1; - } - } else if (node.match( /^<\w[^>]*[^\/]>.*$/ )) { - indent = 1; - } else { - indent = 0; - } - - var padding = ''; - for (var i = 0; i < pad; i++) { - padding += ' '; - } - - formatted += padding + node + '\r\n'; - pad += indent; - }); - - return formatted; + function Reset() + { + AscTest.ClearDocument(); + oXMLManager.xml = [] } - //todo content control inside content control: - // picture - // richText - // simpleText - // checkBox - - window['asc_docs_api'] = AscCommon.baseEditorsApi; - const editor = new AscCommon.baseEditorsApi({}); + QUnit.testStart( function() {Reset()} ); - QUnit.test("Load content from customXML", function (assert) + QUnit.test("Date and CheckBox content control's load from different CustomXML's", async function (assert) { - AscTest.ClearDocument(); - - let c1 = CreateFilledContentControl(); - logicDocument.AddToContent(0, c1); - updateXML(getXml(['Один два три 4 пять'])) - c1.checkDataBinding(); - CheckContentParagraph(assert, c1.Content.Content, ['Один два три 4 пять ']) + 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); + debugger + 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(1)), + "\n" + oCustomXMLData.checkboxTrue + "", + "Check saved CustomXML" + ); }); - QUnit.test("Load content from customXML", function (assert) + QUnit.test("Date content control load form CustomXML", async function (assert) { - AscTest.ClearDocument(); + CreateCustomXMLForDocument(oCustomXMLs.date); - let c1 = CreateFilledContentControl(); - logicDocument.AddToContent(0, c1); - updateXML(getXml(['Один два три 4 пять', '23'])) - c1.checkDataBinding(); - CheckContentParagraph(assert, c1.Content.Content, ['Один два три 4 пять ', '23 ']) + 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"); }); - QUnit.test("Save content to customXML", function (assert) + QUnit.test("Checkbox content control load form CustomXML", async function (assert) { - AscTest.ClearDocument(); - let c1 = CreateFilledContentControl(); - logicDocument.AddToContent(0, c1); - c1.checkDataBinding(); - - let doc = new AscTest.CreateLogicDocument(); - doc.ReplaceContent(c1.Content.Content); - - // let jsZlib = new AscCommon.ZLib(); - // jsZlib.create(); - // doc.toZip(jsZlib, new AscCommon.XmlWriterContext(AscCommon.c_oEditorId.Word)); - // let data = jsZlib.save(); - // let jsZlib2 = new AscCommon.ZLib(); - // jsZlib2.open(data); - // - // let openDoc = new AscCommon.openXml.OpenXmlPackage(jsZlib2, null); - // - // console.log(openDoc) - - let str = AscCommon.getCustomXmlFromContentControl(custom); - str = str.replaceAll('<', '<'); - str = str.replaceAll('>', '>'); - - console.log(str) - console.log(formatXml(str)) - - // check content of customXMl - - assert.strictEqual("save", false, "Check no format validation"); + function getCheck(strContent) + { + return '\n' + + '\n' + + '\t'+ strContent +'\n' + + ''; + } + + 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" + ); + + Reset(); }); }); diff --git a/word/Editor/Serialize2.js b/word/Editor/Serialize2.js index 72b64b4ec0..6c8ff400f3 100644 --- a/word/Editor/Serialize2.js +++ b/word/Editor/Serialize2.js @@ -7736,7 +7736,7 @@ function BinaryCustomsTableWriter(memory, doc, customXmlManager) } if (null !== customXml.content) { this.bs.WriteItem(c_oSerCustoms.ContentA, function() { - let str = getCustomXmlFromContentControl(customXml, customXmlManager); + let str = customXmlManager.getCustomXMLString(customXml); oThis.memory.WriteCustomStringA(str); }); } @@ -16203,129 +16203,7 @@ function Binary_CustomsTableReader(doc, oReadResult, stream) { let strContent = "".fromUtf8(custom.content) strContent = strContent.slice(strContent.indexOf("<"), strContent.length); // Skip "L" - let oStax = new StaxParser(strContent); - let oCurrentContent = null; - - // switch to CT_Node - function CustomXMLItem(par, name) - { - this.parent = par; - this.content = []; - this.name = name ? name : ""; - this.attribute = {}; - this.textContent = ""; - this.current = undefined; - - this.str = ""; - - this.AddAttribute = function (name, value) - { - this.attribute[name] = value; - } - this.AddContent = function (name) - { - let one = new CustomXMLItem(this, name); - oCurrentContent = one; - this.content.push(one); - } - this.GetParent = function () - { - if (this.parent) - return this.parent; - - return null; - } - this.SetParent = function (oPar) - { - this.parent = oPar; - } - this.AddTextContent = function (text) - { - if (text !== "") - this.textContent += text; - } - this.GetStringFromBuffer = function () - { - let buffer = this.GetBuffer(); - let arr = Array.prototype.slice.call(buffer.data.slice(1, buffer.pos)); - let str = String.fromCharCode.apply(null, arr); - str = str.replaceAll(""", "\""); - str = str.replaceAll("&", "&"); - - this.str = str; - return str; - } - this.GetBuffer = function () - { - let writer = new AscCommon.CMemory(); - - function Write(content) - { - let current = null; - - if (!content.name) - { - writer.WriteXmlString("\x00"); - current = content.content[0]; - } else - { - current = content; - } - - 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++) - { - let curContent = current.content[i]; - Write(curContent); - } - - if (current.textContent) - writer.WriteXmlStringEncode(current.textContent.toString()); - - writer.WriteXmlNodeEnd(current.name); - } - - Write(this); - return writer; - } - } - - let oParContent = oCurrentContent = new CustomXMLItem(null); - - while (oStax.Read()) - { - switch (oStax.GetEventType()) - { - case EasySAXEvent.CHARACTERS: - oCurrentContent.AddTextContent(oStax.text); - break; - case EasySAXEvent.END_ELEMENT: - oCurrentContent = oCurrentContent.parent; - break; - case EasySAXEvent.START_ELEMENT: - let name = oStax.GetName(); - oCurrentContent.AddContent(name) - - while (oStax.MoveToNextAttribute()) - { - let nameAttrib = oStax.GetName(); - let valueAttrib = oStax.GetValue(); - oCurrentContent.AddAttribute(nameAttrib, valueAttrib); - } - break; - } - } - custom.content = oParContent; + custom.content = this.customXmlManager.parseCustomXML(strContent); this.customXmlManager.add(custom); } else diff --git a/word/Editor/StructuredDocumentTags/BlockLevel.js b/word/Editor/StructuredDocumentTags/BlockLevel.js index f5fa24a4c7..0dcf77bd93 100644 --- a/word/Editor/StructuredDocumentTags/BlockLevel.js +++ b/word/Editor/StructuredDocumentTags/BlockLevel.js @@ -1589,7 +1589,7 @@ CBlockLevelSdt.prototype.fillContentWithDataBinding = function(content) this.SetDatePickerPr(datePr); this.private_UpdateDatePickerContent(); } - else if (this.IsDropDownList() || this.IsComboBox()) + else if (this.IsDropDownList() || this.IsComboBox() || this.Pr.Text === true || !content.includes('<?xml version=\\"1.0\\" standalone=\\"yes\\"?>')) { let oRun = new ParaRun(); oRun.AddText(content); diff --git a/word/Editor/custom-xml/custom-xml-manager.js b/word/Editor/custom-xml/custom-xml-manager.js index 426c523d6e..3a90b1c7e0 100644 --- a/word/Editor/custom-xml/custom-xml-manager.js +++ b/word/Editor/custom-xml/custom-xml-manager.js @@ -69,7 +69,7 @@ let part = parts[i]; let namespaceAndTag = part.split('[')[0]; let index = parseInt(part.split('[')[1].slice(0, -1)) - 1; - let tagName = namespaceAndTag.split(':')[1]; + let tagName = namespaceAndTag.includes(":") ? namespaceAndTag.split(':')[1] : namespaceAndTag; let matchingChildren = currentElement.content.filter(function (child) { let arr = child.name.split(":"); @@ -125,7 +125,258 @@ content.textContent = data; } } - } + }; + CustomXmlManager.prototype.parseCustomXML = function (strCustomXml) + { + let oStax = new StaxParser(strCustomXml); + let oCurrentContent = null; + + // switch to CT_Node + function CustomXMLItem(par, name) + { + this.parent = par; + this.content = []; + this.name = name ? name : ""; + this.attribute = {}; + this.textContent = ""; + this.current = undefined; + this.str = ""; + + this.AddAttribute = function (name, value) + { + this.attribute[name] = value; + } + this.AddContent = function (name) + { + let one = new CustomXMLItem(this, name); + oCurrentContent = one; + + this.content.push(one); + } + this.GetParent = function () + { + if (this.parent) + return this.parent; + + return null; + } + this.SetParent = function (oPar) + { + this.parent = oPar; + } + this.AddTextContent = function (text) + { + if (text !== "") + this.textContent += text; + } + this.GetStringFromBuffer = function () + { + let buffer = this.GetBuffer(); + let arr = Array.prototype.slice.call(buffer.data.slice(1, buffer.pos)); + let str = String.fromCharCode.apply(null, arr); + str = str.replaceAll(""", "\""); + str = str.replaceAll("&", "&"); + + this.str = str; + return str; + } + 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.WriteXmlStringEncode(current.textContent.toString().trim()); + + writer.WriteXmlNodeEnd(current.name); + } + + Write(this); + return writer; + } + } + + let oParContent = oCurrentContent = new CustomXMLItem(null); + + while (oStax.Read()) + { + switch (oStax.GetEventType()) + { + case EasySAXEvent.CHARACTERS: + oCurrentContent.AddTextContent(oStax.text); + break; + case EasySAXEvent.END_ELEMENT: + oCurrentContent = oCurrentContent.parent; + break; + case EasySAXEvent.START_ELEMENT: + let name = oStax.GetName(); + oCurrentContent.AddContent(name) + + while (oStax.MoveToNextAttribute()) + { + let nameAttrib = oStax.GetName(); + let valueAttrib = oStax.GetValue(); + oCurrentContent.AddAttribute(nameAttrib, valueAttrib); + } + break; + } + } + + return oParContent; + }; + + CustomXmlManager.prototype.getCustomXMLString = function(customXml) + { + 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; + } + + let oContent = customXml.oContentLink; + + if (oContent.IsCheckBox() || oContent.IsDatePicker() || oContent.IsPicture() || oContent.IsDropDownList() || oContent.IsComboBox() || oContent.Pr.Text) + { + return customXml.content.GetStringFromBuffer(); + } + else + { + let writer = new AscCommon.CMemory(); + writer.context = new AscCommon.XmlWriterContext(AscCommon.c_oEditorId.Word); + writer.context.docSaveParams = new DocSaveParams(undefined, undefined, false, undefined); + + let drawDoc = new AscCommon.CDrawingDocument(); + drawDoc.m_oWordControl = drawDoc; + drawDoc.m_oWordControl.m_oApi = window.editor; + let doc = new AscWord.CDocument(drawDoc); + + doc.ReplaceContent(oContent.Content); + + let jsZlib = new AscCommon.ZLib(); + jsZlib.create(); + doc.toZip(jsZlib, new AscCommon.XmlWriterContext(AscCommon.c_oEditorId.Word)); + + let data = jsZlib.save(); + let jsZlib2 = new AscCommon.ZLib(); + jsZlib2.open(data); + var openDoc = new AscCommon.openXml.OpenXmlPackage(jsZlib2, null); + + let outputUString = "\n" + + "\n" + + ""; + + jsZlib2.files.forEach(function(path) { + if ((path === "_rels/.rels" || path === "word/document.xml" || path === "word/_rels/document.xml.rels") && !path.includes("glossary")) + { + let ctfBytes = jsZlib2.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", "") + "" + } + }); + + //check diffrences between main write and this, when save main document higlight write correct + // outputUString = outputUString.replace("FFFF00", "yellow"); + + + //need get contentType from openXml.Types + outputUString = outputUString.replace("pkg:contentType=\"application/xml\"", "pkg:contentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml\""); + outputUString = outputUString.replace("pkg:contentType=\"application/vnd.openxmlformats-package.relationships+xml\"", "pkg:contentType=\"application/vnd.openxmlformats-package.relationships+xml\" pkg:padding=\"512\"") + outputUString = outputUString.replace("\"/word/_rels/document.xml.rels\"pkg:contentType=\"application/vnd.openxmlformats-package.relationships+xml\"", "\"/word/_rels/document.xml.rels\"pkg:contentType=\"application/vnd.openxmlformats-package.relationships+xml\" pkg:padding=\"256\"") + + outputUString += ""; + + //create flat xml + outputUString = outputUString.replaceAll("<", "<"); + outputUString = outputUString.replaceAll(">", ">"); + + let str = customXml.content.GetStringFromBuffer(); + let nStartIndex = str.indexOf("") + ''.length; + let nEndIndex = str.indexOf("/pkg:package>") + '/pkg:package>'.length ; + + str = replaceSubstring(str, nStartIndex, nEndIndex, outputUString); + + // nStartIndex = str.indexOf("") + ''.length; + // nEndIndex = str.indexOf("/pkg:package>") + '/pkg:package>'.length ; + //customXml.oContentLink.Pr.DataBinding.recalculateCheckSum(str.substring(nStartIndex, nEndIndex)); + + return str; + } + }; //--------------------------------------------------------export---------------------------------------------------- window['AscWord'] = window['AscWord'] || {}; From 62a93b5e5f8c18e24eec5292d12d0c8e1b4fa7d8 Mon Sep 17 00:00:00 2001 From: EvgeniyIgol Date: Thu, 8 Aug 2024 17:19:50 +0300 Subject: [PATCH 14/22] [de] Add more test for CustomXML processing --- tests/word/customXML/customXML.js | 150 ++++++++++++++++++++++++++---- 1 file changed, 132 insertions(+), 18 deletions(-) diff --git a/tests/word/customXML/customXML.js b/tests/word/customXML/customXML.js index fae2301d12..b7dbbcf115 100644 --- a/tests/word/customXML/customXML.js +++ b/tests/word/customXML/customXML.js @@ -37,11 +37,9 @@ $(function () { function CreateContentControl() { - let cc = new AscWord.CBlockLevelSdt(logicDocument); - cc.SetPlaceholder(c_oAscDefaultPlaceholderName.Text); - cc.ReplacePlaceHolderWithContent(); - cc.SetShowingPlcHdr(false); - return cc; + let para = AscTest.CreateParagraph(); + logicDocument.AddToContent(0, para); + return logicDocument.AddContentControl(c_oAscSdtLevelType.Block); } function CreateDataBindingForCC(contentControl, prefix, itemId, xpath, checkSum) { @@ -74,14 +72,20 @@ $(function () { oXMLManager.add(oXML); } + function SetPictureToContentControl (oCC, strBase64) + { + oXMLManager.setContentByDataBinding(oCC.Pr.DataBinding, strBase64); + } const oCustomXMLData = { - date: "2000-01-01", + 'date': "2000-01-01", 'checkboxTrue': true, 'checkboxFalse': false, 'checkbox0': 0, 'checkbox1': 1, 'checkboxMess': "hello", + '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\"", @@ -91,10 +95,10 @@ $(function () { '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 CreateDateCC(nPos) { let cc = CreateFilledContentControl(nPos) @@ -109,6 +113,7 @@ $(function () { cc.ApplyCheckBoxPr(checkboxPr); return cc; } + // поле со списком function CreateComboBox(nPos) { let cc = CreateFilledContentControl(nPos); @@ -116,6 +121,14 @@ $(function () { cc.ApplyComboBoxPr(comboBoxPr, true); return cc; } + // раскрывающийся список + function CreateDropDown(nPos) + { + let cc = CreateFilledContentControl(nPos); + let comboBoxPr = new AscWord.CSdtComboBoxPr(); + cc.ApplyDropDownListPr(comboBoxPr, true); + return cc; + } function CreatePicture(nPos) { let cc = CreateFilledContentControl(nPos); @@ -126,8 +139,7 @@ $(function () { function CreateText(nPos) { let cc = CreateFilledContentControl(nPos); - let textPr = new AscWord.CSdtTextFormPr(); - cc.ApplyTextFormPr(textPr); + cc.SetContentControlText(true) return cc; } @@ -156,9 +168,9 @@ $(function () { oXMLManager.xml = [] } - QUnit.testStart( function() {Reset()} ); + QUnit.testStart( function() { Reset() } ); - QUnit.test("Date and CheckBox content control's load from different CustomXML's", async function (assert) + 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]"]); @@ -174,9 +186,8 @@ $(function () { assert.strictEqual(oDate, oStartDate, "Date loaded from CustomXml"); let c2 = CreateCheckBoxCC(1); - debugger CreateDataBindingForCC(c2, '', "{694325A8-B1C9-407B-A2C2-E2DD1740AA55}", '/weather[1]', ''); - let oCHeckBoxPr = c2.GetCheckBoxPr(); + let oCHeckBoxPr = c2.GetCheckBoxPr(); assert.strictEqual( oCHeckBoxPr.Checked, @@ -184,6 +195,12 @@ $(function () { "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 + "", @@ -191,7 +208,7 @@ $(function () { ); }); - QUnit.test("Date content control load form CustomXML", async function (assert) + QUnit.test("Date content control load/save from/to CustomXML", async function (assert) { CreateCustomXMLForDocument(oCustomXMLs.date); @@ -204,9 +221,15 @@ $(function () { 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 form CustomXML", async function (assert) + QUnit.test("Checkbox content control load/save from/to CustomXML", async function (assert) { function getCheck(strContent) { @@ -284,8 +307,99 @@ $(function () { getCheck('false'), "Check saved CustomXML" ); + }); - Reset(); + QUnit.test("ComboBox content control load from/save to 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 to 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 to 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/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 to 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" + ); + }); }); From 287553ba0e89df16b5da42e6f7b6d640ed047321 Mon Sep 17 00:00:00 2001 From: EvgeniyIgol Date: Fri, 9 Aug 2024 16:35:19 +0300 Subject: [PATCH 15/22] [de] Add test for CustomXML load/save rich text content control --- tests/word/customXML/customXML.js | 208 ++++++++++++++++-- .../StructuredDocumentTags/BlockLevel.js | 6 +- word/Editor/custom-xml/custom-xml-manager.js | 3 +- 3 files changed, 199 insertions(+), 18 deletions(-) diff --git a/tests/word/customXML/customXML.js b/tests/word/customXML/customXML.js index b7dbbcf115..c8be5a228f 100644 --- a/tests/word/customXML/customXML.js +++ b/tests/word/customXML/customXML.js @@ -31,6 +31,143 @@ */ $(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 custom; let oXMLManager = logicDocument.getCustomXmlManager(); @@ -84,6 +221,7 @@ $(function () { '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=', } @@ -162,6 +300,14 @@ $(function () { } } + function getCheck(strContent) + { + return '\n' + + '\n' + + '\t'+ strContent +'\n' + + ''; + } + function Reset() { AscTest.ClearDocument(); @@ -208,7 +354,7 @@ $(function () { ); }); - QUnit.test("Date content control load/save from/to CustomXML", async function (assert) + QUnit.test("Date content control load/save CustomXML", async function (assert) { CreateCustomXMLForDocument(oCustomXMLs.date); @@ -229,16 +375,8 @@ $(function () { ); }); - QUnit.test("Checkbox content control load/save from/to CustomXML", async function (assert) + QUnit.test("Checkbox content control load/save CustomXML", async function (assert) { - function getCheck(strContent) - { - return '\n' + - '\n' + - '\t'+ strContent +'\n' + - ''; - } - CreateCustomXMLForDocument(oCustomXMLs.checkboxTrue); let c1 = CreateCheckBoxCC(0); CreateDataBindingForCC(c1); @@ -309,7 +447,7 @@ $(function () { ); }); - QUnit.test("ComboBox content control load from/save to CustomXML", async function (assert) + QUnit.test("ComboBox content control load from/save CustomXML", async function (assert) { CreateCustomXMLForDocument(oCustomXMLs.checkboxMess); @@ -334,7 +472,7 @@ $(function () { assert.strictEqual(oValue, "hello123 ", "Date loaded from CustomXml"); }); - QUnit.test("DropDown content control load from/save to CustomXML", async function (assert) + QUnit.test("DropDown content control load from/save CustomXML", async function (assert) { CreateCustomXMLForDocument(oCustomXMLs.checkboxMess); @@ -359,7 +497,7 @@ $(function () { assert.strictEqual(oValue, "hello123 ", "Date saved from CustomXml"); }); - QUnit.test("Picture content control load from/save to CustomXML", async function (assert) + QUnit.test("Picture content control load from/save CustomXML", async function (assert) { let editor = logicDocument.GetApi(); editor.ImageLoader = AscCommon.g_image_loader; @@ -387,7 +525,7 @@ $(function () { ); }); - QUnit.test("Simple text content control load from/save to CustomXML", async function (assert) + QUnit.test("Simple text content control load from/save CustomXML", async function (assert) { CreateCustomXMLForDocument(oCustomXMLs.checkboxMess); let c1 = CreateText(0); @@ -402,4 +540,46 @@ $(function () { "Check load CustomXML" ); }); + + 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; + } + + 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, + `\n\n\t<?xml version="1.0" standalone="yes"?>\n<?mso-application progid="Word.Document"?>\n<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" xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" mc:Ignorable="w14 w15 w16se w16cid w16 w16cex w16sdtdh wp14"><w:body><w:p><w:pPr><w:rPr></w:rPr></w:pPr><w:r><w:rPr><w:lang w:val="en-US"/></w:rPr><w:t xml:space="preserve">12345+2</w:t></w:r><w:r><w:t xml:space="preserve">990</w:t></w:r><w:r></w:r></w:p><w:sectPr><w:footnotePr></w:footnotePr><w:endnotePr></w:endnotePr><w:type w:val="nextPage"/><w:pgSz w:w="11906" w:h="16838" w:orient="portrait"/><w:pgMar w:top="1134" w:right="850" w:bottom="1134" w:left="1701" w:header="709" w:footer="709" w:gutter="0"/><w:pgBorders w:zOrder="front" w:display="allPages" w:offsetFrom="text"><w:top w:val="none" w:sz="4" w:space="0" w:color="000000"/><w:left w:val="none" w:sz="4" w:space="0" w:color="000000"/><w:bottom w:val="none" w:sz="4" w:space="0" w:color="000000"/><w:right w:val="none" w:sz="4" w:space="0" w:color="000000"/></w:pgBorders><w:pgNumType w:fmt="decimal"/><w:cols w:equalWidth="1" w:space="1701" w:num="1" w:sep="0"></w:cols><w:titlePg w:val="0"/><w:rtlGutter w:val="0"/></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: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:package>/simpleText>\n`, + "Check load CustomXML" + ); + }); }); diff --git a/word/Editor/StructuredDocumentTags/BlockLevel.js b/word/Editor/StructuredDocumentTags/BlockLevel.js index 0dcf77bd93..a8d8bbf19d 100644 --- a/word/Editor/StructuredDocumentTags/BlockLevel.js +++ b/word/Editor/StructuredDocumentTags/BlockLevel.js @@ -1589,15 +1589,15 @@ CBlockLevelSdt.prototype.fillContentWithDataBinding = function(content) this.SetDatePickerPr(datePr); this.private_UpdateDatePickerContent(); } - else if (this.IsDropDownList() || this.IsComboBox() || this.Pr.Text === true || !content.includes('<?xml version=\\"1.0\\" standalone=\\"yes\\"?>')) + 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.Content.AddToParagraph(oRun); + this.AddNewParagraph(); + this.Content.AddText(content); } else { diff --git a/word/Editor/custom-xml/custom-xml-manager.js b/word/Editor/custom-xml/custom-xml-manager.js index 3a90b1c7e0..a88ad662a8 100644 --- a/word/Editor/custom-xml/custom-xml-manager.js +++ b/word/Editor/custom-xml/custom-xml-manager.js @@ -297,7 +297,8 @@ drawDoc.m_oWordControl.m_oApi = window.editor; let doc = new AscWord.CDocument(drawDoc); - doc.ReplaceContent(oContent.Content); + let oSdtContent = oContent.GetContent(); + doc.ReplaceContent(oSdtContent.Content); let jsZlib = new AscCommon.ZLib(); jsZlib.create(); From d09a54a53e240ef1d39e0e43d8ccc831e1cfed9b Mon Sep 17 00:00:00 2001 From: EvgeniyIgol Date: Thu, 15 Aug 2024 16:51:12 +0300 Subject: [PATCH 16/22] [de] Fix save CustomXML and load for linear content control --- word/Editor/Document.js | 47 --- word/Editor/Serialize2.js | 123 +------- .../StructuredDocumentTags/BlockLevel.js | 123 +------- .../StructuredDocumentTags/InlineLevel.js | 40 ++- word/Editor/custom-xml/custom-xml-manager.js | 272 ++++++++++++------ 5 files changed, 239 insertions(+), 366 deletions(-) diff --git a/word/Editor/Document.js b/word/Editor/Document.js index 33d2783000..e064537c58 100644 --- a/word/Editor/Document.js +++ b/word/Editor/Document.js @@ -27337,53 +27337,6 @@ CDocument.prototype.isPreventedPreDelete = function() { return this.PreventPreDelete; }; -CDocument.prototype.WriteCustomXML = function(oDataBindings, ContentToWrite) -{ - for (let i = 0; i < this.customXml.xml.length; i++) - { - let oCurCustomXml = this.customXml.xml[i]; - if (oDataBindings.storeItemID === oCurCustomXml.itemId) - { - let xPath = oDataBindings.xpath; - - function findElementsByXPath(root, xpath) { - var parts = xpath.split('/'); - parts.shift(); // Убираем пустой первый элемент - - var currentElement = root; - - for (var i = 0; i < parts.length; i++) { - var part = parts[i]; - var namespaceAndTag = part.split('[')[0]; - var index = parseInt(part.split('[')[1].slice(0, -1)) - 1; - var tagName = namespaceAndTag.split(':')[1]; - - var 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) { - return null; // Элемент не найден - } - - currentElement = matchingChildren[index]; - } - - return currentElement.textContent = ContentToWrite; - } - return findElementsByXPath(oCurCustomXml.content, xPath); - } - } -} /** * @returns {AscWord.CustomXmlManager} */ diff --git a/word/Editor/Serialize2.js b/word/Editor/Serialize2.js index 6c8ff400f3..92b603bd8a 100644 --- a/word/Editor/Serialize2.js +++ b/word/Editor/Serialize2.js @@ -6535,11 +6535,6 @@ function BinaryDocumentTableWriter(memory, doc, oMapCommentId, oNumIdMap, copyPa // this.bs.WriteItem(c_oSerSdt.EndPr, function(){oThis.brPrs.Write_rPr(oSdt.EndPr, null, null);}); // } - if (oSdt.Pr.DataBinding) - { - this.Document.WriteCustomXML(oSdt.Pr.DataBinding, oSdt.Content.Content[0].GetText()); - } - if (0 === type) { var oInnerDocument = new BinaryDocumentTableWriter(this.memory, this.Document, this.oMapCommentId, this.oNumIdMap, this.copyParams, this.saveParams, this.oBinaryHeaderFooterTableWriter); @@ -7590,119 +7585,6 @@ function BinaryNotesTableWriter(memory, doc, oNumIdMap, oMapCommentId, copyParam }; }; - -//temp location -function getCustomXmlFromContentControl(customXml, customXmlManager) -{ - 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; - } - - let oContent = customXml.oContentLink; - let oDataBinding = oContent.GetDataBinding(); - - if (oContent.IsCheckBox() || oContent.IsDatePicker() || oContent.IsPicture() || oContent.IsDropDownList() || oContent.IsComboBox()) - { - return customXml.content.GetStringFromBuffer(); - } - else - { - let writer = new AscCommon.CMemory(); - writer.context = new AscCommon.XmlWriterContext(AscCommon.c_oEditorId.Word); - writer.context.docSaveParams = new DocSaveParams(undefined, undefined, false, undefined); - - let drawDoc = new AscCommon.CDrawingDocument(); - drawDoc.m_oWordControl = drawDoc; - drawDoc.m_oWordControl.m_oApi = window.editor; - let doc = new AscWord.CDocument(drawDoc); - - doc.ReplaceContent(oContent.Content.Content); - - let jsZlib = new AscCommon.ZLib(); - jsZlib.create(); - doc.toZip(jsZlib, new AscCommon.XmlWriterContext(AscCommon.c_oEditorId.Word)); - - let data = jsZlib.save(); - let jsZlib2 = new AscCommon.ZLib(); - jsZlib2.open(data); - var openDoc = new AscCommon.openXml.OpenXmlPackage(jsZlib2, null); - - let outputUString = "\n" + - "\n" + - ""; - - jsZlib2.files.forEach(function(path) { - if ((path === "_rels/.rels" || path === "word/document.xml" || path === "word/_rels/document.xml.rels") && !path.includes("glossary")) - { - let ctfBytes = jsZlib2.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", "") + "" - } - }); - - //check diffrences between main write and this, when save main document higlight write correct - // outputUString = outputUString.replace("FFFF00", "yellow"); - - //need get contentType from openXml.Types - outputUString = outputUString.replace("pkg:contentType=\"application/xml\"", "pkg:contentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml\""); - outputUString = outputUString.replace("pkg:contentType=\"application/vnd.openxmlformats-package.relationships+xml\"", "pkg:contentType=\"application/vnd.openxmlformats-package.relationships+xml\" pkg:padding=\"512\"") - outputUString = outputUString.replace("\"/word/_rels/document.xml.rels\"pkg:contentType=\"application/vnd.openxmlformats-package.relationships+xml\"", "\"/word/_rels/document.xml.rels\"pkg:contentType=\"application/vnd.openxmlformats-package.relationships+xml\" pkg:padding=\"256\"") - - outputUString += ""; - - //create flat xml - outputUString = outputUString.replaceAll("<", "<"); - outputUString = outputUString.replaceAll(">", ">"); - - let str = customXml.content.GetStringFromBuffer(); - let nStartIndex = str.indexOf("") + ''.length; - let nEndIndex = str.indexOf("/pkg:package>") + '/pkg:package>'.length ; - - str = replaceSubstring(str, nStartIndex, nEndIndex, outputUString); - - // nStartIndex = str.indexOf("") + ''.length; - // nEndIndex = str.indexOf("/pkg:package>") + '/pkg:package>'.length ; - //customXml.oContentLink.Pr.DataBinding.recalculateCheckSum(str.substring(nStartIndex, nEndIndex)); - - return str; - } -} - function BinaryCustomsTableWriter(memory, doc, customXmlManager) { this.memory = memory; @@ -17570,7 +17452,4 @@ window["AscCommonWord"].BinaryParagraphStyleUpdater = BinaryParagraphStyleUpdate window["AscCommonWord"].BinaryTableStyleUpdater = BinaryTableStyleUpdater; window["AscCommonWord"].BinaryAbstractNumStyleLinkUpdater = BinaryAbstractNumStyleLinkUpdater; window["AscCommonWord"].BinaryAbstractNumNumStyleLinkUpdater = BinaryAbstractNumNumStyleLinkUpdater; -window["AscCommonWord"].BinaryNumLvlStyleUpdater = BinaryNumLvlStyleUpdater; - -//temp -window['AscCommon'].getCustomXmlFromContentControl = getCustomXmlFromContentControl; +window["AscCommonWord"].BinaryNumLvlStyleUpdater = BinaryNumLvlStyleUpdater; \ No newline at end of file diff --git a/word/Editor/StructuredDocumentTags/BlockLevel.js b/word/Editor/StructuredDocumentTags/BlockLevel.js index a8d8bbf19d..a999a3a368 100644 --- a/word/Editor/StructuredDocumentTags/BlockLevel.js +++ b/word/Editor/StructuredDocumentTags/BlockLevel.js @@ -562,6 +562,12 @@ CBlockLevelSdt.prototype.Remove = function(nCount, isRemoveWholeElement, bRemove return true; } + if (this.Pr.DataBinding) + { + let CustomManager = this.LogicDocument.getCustomXmlManager(); + CustomManager.setContentByDataBinding(this.Pr.DataBinding, this, true); + } + return bResult; }; CBlockLevelSdt.prototype.Is_Empty = function() @@ -600,7 +606,7 @@ CBlockLevelSdt.prototype.Add = function(oParaItem) var Item = this.Content.Content[nContentPos]; let CustomManager = this.LogicDocument.getCustomXmlManager(); - CustomManager.setContentByDataBinding(this.Pr.DataBinding, Item.GetText()); + CustomManager.setContentByDataBinding(this.Pr.DataBinding, this); } if (isRemoveWrapper) @@ -1578,8 +1584,12 @@ CBlockLevelSdt.prototype.fillContentWithDataBinding = function(content) 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()) @@ -1601,116 +1611,11 @@ CBlockLevelSdt.prototype.fillContentWithDataBinding = function(content) } else { - content = content.replaceAll("<", "<"); - content = content.replaceAll(">", ">"); - content = content.replaceAll("", ""); - content = content.replaceAll("", ""); - let zLib = new AscCommon.ZLib; - zLib.create(); - let nPos = 0; - - zLib.addFile('[Content_Types].xml', new TextEncoder("utf-8").encode('' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '')); - - while (true) - { - let nStartPos = nPos = content.indexOf('', nStartPos); - - let strText = content.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 = logicDocument.DrawingDocument; - let Doc = new CDocument(draw, false); - - let xmlParserContext = new AscCommon.XmlParserContext(); - xmlParserContext.DrawingDocument = draw; - - let jsZlib = new AscCommon.ZLib(); - if (!jsZlib.open(arr)) { - return false; - } - - let reader, openParams = {}; - let oBinaryFileReader = new AscCommonWord.BinaryFileReader(Doc, openParams); - oBinaryFileReader.PreLoadPrepare(); - - Doc.fromZip(jsZlib, xmlParserContext, oBinaryFileReader.oReadResult); - - oBinaryFileReader.PostLoadPrepare(xmlParserContext); - jsZlib.close(); + let customXmlManager = logicDocument.getCustomXmlManager(); + let arrContent = customXmlManager.proceedLinearXMl(content); this.Content.RemoveFromContent(0, this.Content.Content.length); - this.Content.AddContent(Doc.Content); + this.Content.AddContent(arrContent); this.Content.Recalculate(true); } }; diff --git a/word/Editor/StructuredDocumentTags/InlineLevel.js b/word/Editor/StructuredDocumentTags/InlineLevel.js index 553ffb54bf..4251279bc6 100644 --- a/word/Editor/StructuredDocumentTags/InlineLevel.js +++ b/word/Editor/StructuredDocumentTags/InlineLevel.js @@ -3768,10 +3768,42 @@ CInlineLevelSdt.prototype.CorrectSingleLineFormContent = function() }; CInlineLevelSdt.prototype.fillContentWithDataBinding = function(content) { - let run = new AscWord.CRun(); - run.AddText(content); - this.ClearContent(); - this.AddToContent(0, run); + 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 oPar = new Paragraph(); + let oRun = new ParaRun(); + oPar.Add(oRun) + oRun.AddText(content); + + this.SetParagraph(oPar); + } + else + { + let customXmlManager = logicDocument.getCustomXmlManager(); + let arrContent = customXmlManager.proceedLinearXMl(content); + + this.SetParagraph(arrContent[0]); + } }; diff --git a/word/Editor/custom-xml/custom-xml-manager.js b/word/Editor/custom-xml/custom-xml-manager.js index a88ad662a8..fdd999b70e 100644 --- a/word/Editor/custom-xml/custom-xml-manager.js +++ b/word/Editor/custom-xml/custom-xml-manager.js @@ -43,6 +43,8 @@ { this.document = document; this.xml = []; + // check + this.RichTextCC = []; } CustomXmlManager.prototype.add = function(customXml) { @@ -119,10 +121,22 @@ if (dataBinding.storeItemID === customXml.itemId) { - let xPath = dataBinding.xpath; + let xPath = dataBinding.xpath; + let content = this.findElementsByXPath(customXml.content, xPath); - let content = this.findElementsByXPath(customXml.content, xPath); - content.textContent = data; + if (data instanceof AscCommonWord.CBlockLevelSdt) + { + // this.updateRichTextCustomXML(data) + // пока при каждом изменении Rich Text записывать изменения не эффективно + // запишем какой контент контрол нужно изменить, а обновим при сохранении + + if (!this.RichTextCC.includes(data)) + this.RichTextCC.push(data); + + return; + } + + content.SetTextContent(data); } } }; @@ -172,12 +186,9 @@ this.GetStringFromBuffer = function () { let buffer = this.GetBuffer(); - let arr = Array.prototype.slice.call(buffer.data.slice(1, buffer.pos)); - let str = String.fromCharCode.apply(null, arr); + let str = AscCommon.UTF8ArrayToString(buffer.data, 1); str = str.replaceAll(""", "\""); str = str.replaceAll("&", "&"); - - this.str = str; return str; } this.GetBuffer = function () @@ -228,7 +239,7 @@ } if (current.textContent) - writer.WriteXmlStringEncode(current.textContent.toString().trim()); + writer.WriteXmlString(current.textContent.toString().trim()); writer.WriteXmlNodeEnd(current.name); } @@ -236,6 +247,10 @@ Write(this); return writer; } + this.SetTextContent = function (str) + { + this.textContent = str; + } } let oParContent = oCurrentContent = new CustomXMLItem(null); @@ -266,8 +281,7 @@ return oParContent; }; - - CustomXmlManager.prototype.getCustomXMLString = function(customXml) + CustomXmlManager.prototype.updateRichTextCustomXML = function (oCC) { function replaceSubstring(originalString, startPoint, endPoint, insertionString) { @@ -280,103 +294,193 @@ return prefix + insertionString + suffix; } - let oContent = customXml.oContentLink; + AscCommon.History.TurnOff(); - if (oContent.IsCheckBox() || oContent.IsDatePicker() || oContent.IsPicture() || oContent.IsDropDownList() || oContent.IsComboBox() || oContent.Pr.Text) - { - return customXml.content.GetStringFromBuffer(); - } - else - { - let writer = new AscCommon.CMemory(); - writer.context = new AscCommon.XmlWriterContext(AscCommon.c_oEditorId.Word); - writer.context.docSaveParams = new DocSaveParams(undefined, undefined, false, undefined); + let doc = new AscWord.CDocument(null, false); + let oSdtContent = oCC.GetContent(); + let jsZlib = new AscCommon.ZLib(); - let drawDoc = new AscCommon.CDrawingDocument(); - drawDoc.m_oWordControl = drawDoc; - drawDoc.m_oWordControl.m_oApi = window.editor; - let doc = new AscWord.CDocument(drawDoc); + doc.ReplaceContent(oSdtContent.Content); + jsZlib.create(); + doc.toZip(jsZlib, new AscCommon.XmlWriterContext(AscCommon.c_oEditorId.Word)); - let oSdtContent = oContent.GetContent(); - doc.ReplaceContent(oSdtContent.Content); + let archive = jsZlib.save(); + let openDoc = new AscCommon.openXml.OpenXmlPackage(jsZlib, null); + let outputUString = ""; + let arrPath = jsZlib.getPaths(); - let jsZlib = new AscCommon.ZLib(); - jsZlib.create(); - doc.toZip(jsZlib, new AscCommon.XmlWriterContext(AscCommon.c_oEditorId.Word)); - - let data = jsZlib.save(); - let jsZlib2 = new AscCommon.ZLib(); - jsZlib2.open(data); - var openDoc = new AscCommon.openXml.OpenXmlPackage(jsZlib2, null); - - let outputUString = "\n" + - "\n" + - ""; + 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); - jsZlib2.files.forEach(function(path) { - if ((path === "_rels/.rels" || path === "word/document.xml" || path === "word/_rels/document.xml.rels") && !path.includes("glossary")) + if (path === "word/_rels/document.xml.rels") { - let ctfBytes = jsZlib2.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 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) { - 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 += "" + relType = relType.replace("relationships\/officeDocument", "relationships\/styles"); + relTarget = relTarget.replace("word/document.xml", "styles.xml"); } - let nStart = ctfText.indexOf("", 0) + "".length; - let nEnd = ctfText.indexOf("", nStart) - 1; - ctfText = replaceSubstring(ctfText, nStart, nEnd, text); + text += "" } - outputUString += " " + - "" + ctfText.replace("", "").replace("\n", "") + "" + let nStart = ctfText.indexOf("", 0) + "".length; + let nEnd = ctfText.indexOf("", nStart) - 1; + ctfText = replaceSubstring(ctfText, nStart, nEnd, text); } - }); - //check diffrences between main write and this, when save main document higlight write correct - // outputUString = outputUString.replace("FFFF00", "yellow"); + outputUString += " " + + "" + ctfText.replace("", "").replace("\n", "") + "" + } + }); + + //check diffrences between main write and this, when save main document higlight write correct + // outputUString = outputUString.replace("FFFF00", "yellow"); + //need get contentType from openXml.Types + outputUString = outputUString.replace("pkg:contentType=\"application/xml\"", "pkg:contentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml\""); + outputUString = outputUString.replace("pkg:contentType=\"application/vnd.openxmlformats-package.relationships+xml\"", "pkg:contentType=\"application/vnd.openxmlformats-package.relationships+xml\" pkg:padding=\"512\"") + outputUString = outputUString.replace("\"/word/_rels/document.xml.rels\"pkg:contentType=\"application/vnd.openxmlformats-package.relationships+xml\"", "\"/word/_rels/document.xml.rels\"pkg:contentType=\"application/vnd.openxmlformats-package.relationships+xml\" pkg:padding=\"256\"") + outputUString += ""; + outputUString = outputUString.replaceAll("<", "<"); + outputUString = outputUString.replaceAll(">", ">"); - //need get contentType from openXml.Types - outputUString = outputUString.replace("pkg:contentType=\"application/xml\"", "pkg:contentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml\""); - outputUString = outputUString.replace("pkg:contentType=\"application/vnd.openxmlformats-package.relationships+xml\"", "pkg:contentType=\"application/vnd.openxmlformats-package.relationships+xml\" pkg:padding=\"512\"") - outputUString = outputUString.replace("\"/word/_rels/document.xml.rels\"pkg:contentType=\"application/vnd.openxmlformats-package.relationships+xml\"", "\"/word/_rels/document.xml.rels\"pkg:contentType=\"application/vnd.openxmlformats-package.relationships+xml\" pkg:padding=\"256\"") + AscCommon.History.TurnOn(); + this.setContentByDataBinding(oCC.Pr.DataBinding, outputUString); + }; + CustomXmlManager.prototype.proceedLinearXMl = function (content) + { + content = content.replaceAll("<", "<"); + content = content.replaceAll(">", ">"); + content = content.replaceAll("", ""); + content = content.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 = content.indexOf('', nStartPos); + let strText = content.substring(nStartPos, nEndPos); + + let nPosStartName = strText.indexOf('name="', 0) + 'name="'.length; + let nPosEndName = strText.indexOf('"', nPosStartName); + let name = strText.substring(nPosStartName, nPosEndName); - outputUString += ""; + let nDataStartPos = strText.indexOf('', 0); + let nDataEndPos; - //create flat xml - outputUString = outputUString.replaceAll("<", "<"); - outputUString = outputUString.replaceAll(">", ">"); + if (nDataStartPos !== -1) + { + nDataStartPos = nDataStartPos + ''.length; + nDataEndPos = strText.indexOf('', nDataStartPos); + } + else + { + nDataStartPos = strText.indexOf('', 0); + if (nDataStartPos !== -1) + nDataStartPos += ''.length; + nDataEndPos = strText.indexOf('', nDataStartPos); + } - let str = customXml.content.GetStringFromBuffer(); - let nStartIndex = str.indexOf("") + ''.length; - let nEndIndex = str.indexOf("/pkg:package>") + '/pkg:package>'.length ; + if (nStartPos === -1 || nEndPos === -1) + continue; - str = replaceSubstring(str, nStartIndex, nEndIndex, outputUString); + let data = strText.substring(nDataStartPos, nDataEndPos).trim(); - // nStartIndex = str.indexOf("") + ''.length; - // nEndIndex = str.indexOf("/pkg:package>") + '/pkg:package>'.length ; - //customXml.oContentLink.Pr.DataBinding.recalculateCheckSum(str.substring(nStartIndex, nEndIndex)); + if (name[0] === "/") + name = name.substring(1, name.length); - return str; + 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 false; + + let oBinaryFileReader = new AscCommonWord.BinaryFileReader(Doc, {}); + oBinaryFileReader.PreLoadPrepare(); + + Doc.fromZip(jsZlib, xmlParserContext, oBinaryFileReader.oReadResult); + + oBinaryFileReader.PostLoadPrepare(xmlParserContext); + jsZlib.close(); + + return Doc.Content; + } + CustomXmlManager.prototype.getCustomXMLString = function(customXml) + { + for (let i = 0; i < this.RichTextCC.length; i++) + { + this.updateRichTextCustomXML(this.RichTextCC[i]); + } + + return customXml.content.GetStringFromBuffer(); }; //--------------------------------------------------------export---------------------------------------------------- From 24ec4ac3e02147a0a577d1aa6b64337590ac1921 Mon Sep 17 00:00:00 2001 From: EvgeniyIgol Date: Fri, 16 Aug 2024 16:01:38 +0300 Subject: [PATCH 17/22] [de] Fix load/save CustomXML by attribute - fix save content to CustomXMl by edit CBlockLevelSdt - add save to CustomXMl for CInlineLevelSdt --- .../StructuredDocumentTags/BlockLevel.js | 42 ++++---- .../StructuredDocumentTags/InlineLevel.js | 23 ++++- word/Editor/custom-xml/custom-xml-manager.js | 95 ++++++++++++++----- 3 files changed, 110 insertions(+), 50 deletions(-) diff --git a/word/Editor/StructuredDocumentTags/BlockLevel.js b/word/Editor/StructuredDocumentTags/BlockLevel.js index a999a3a368..48d0dc2853 100644 --- a/word/Editor/StructuredDocumentTags/BlockLevel.js +++ b/word/Editor/StructuredDocumentTags/BlockLevel.js @@ -562,11 +562,7 @@ CBlockLevelSdt.prototype.Remove = function(nCount, isRemoveWholeElement, bRemove return true; } - if (this.Pr.DataBinding) - { - let CustomManager = this.LogicDocument.getCustomXmlManager(); - CustomManager.setContentByDataBinding(this.Pr.DataBinding, this, true); - } + this.SetContentByDataBinding(this); return bResult; }; @@ -605,8 +601,10 @@ CBlockLevelSdt.prototype.Add = function(oParaItem) var nContentPos = this.Content.CurPos.ContentPos; var Item = this.Content.Content[nContentPos]; - let CustomManager = this.LogicDocument.getCustomXmlManager(); - CustomManager.setContentByDataBinding(this.Pr.DataBinding, this); + if (this.Pr.Text) + this.SetContentByDataBinding(Item.GetText()); + else + this.SetContentByDataBinding(this) } if (isRemoveWrapper) @@ -2078,11 +2076,7 @@ CBlockLevelSdt.prototype.private_UpdateCheckBoxContent = function() oRun.SetRFontsEastAsia({Index : -1, Name : this.Pr.CheckBox.UncheckedFont}); } - if (this.Pr.DataBinding) - { - let CustomManager = this.LogicDocument.getCustomXmlManager(); - CustomManager.setContentByDataBinding(this.Pr.DataBinding, isChecked ? "true" : "false"); - } + this.SetContentByDataBinding(isChecked ? "true" : "false"); }; /** * Проверяем, является ли данный класс специальным контейнером для картинки @@ -2346,14 +2340,10 @@ CBlockLevelSdt.prototype.SelectListItem = function(sValue) var oRun = this.private_UpdateListContent(); if (oRun) oRun.AddText(sText); - - if (this.Pr.DataBinding) - { - let CustomManager = this.LogicDocument.getCustomXmlManager(); - CustomManager.setContentByDataBinding(this.Pr.DataBinding, sText); - } } } + + this.SetContentByDataBinding(sText); }; CBlockLevelSdt.prototype.private_UpdateListContent = function() { @@ -2425,12 +2415,6 @@ CBlockLevelSdt.prototype.private_UpdateDatePickerContent = function() var oRun; var sText = this.Pr.Date.ToString(); - if (this.Pr.DataBinding) - { - let CustomManager = this.LogicDocument.getCustomXmlManager(); - CustomManager.setContentByDataBinding(this.Pr.DataBinding, sText); - } - if (this.LogicDocument && this.LogicDocument.IsTrackRevisions()) { if (!sText && this.IsPlaceHolder()) @@ -2504,6 +2488,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 4251279bc6..15a7bbfad3 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) @@ -1993,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) { @@ -2374,6 +2379,8 @@ CInlineLevelSdt.prototype.SelectListItem = function(sValue) oRun.AddText(sText); } } + + this.SetContentByDataBinding(sText); }; CInlineLevelSdt.prototype.private_UpdateListContent = function() { @@ -2491,13 +2498,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} diff --git a/word/Editor/custom-xml/custom-xml-manager.js b/word/Editor/custom-xml/custom-xml-manager.js index fdd999b70e..338aea4d6b 100644 --- a/word/Editor/custom-xml/custom-xml-manager.js +++ b/word/Editor/custom-xml/custom-xml-manager.js @@ -67,33 +67,48 @@ let currentElement = root; - for (let i = 0; i < parts.length; i++) { + for (let i = 0; i < parts.length; i++) + { let part = parts[i]; - let namespaceAndTag = part.split('[')[0]; - let index = parseInt(part.split('[')[1].slice(0, -1)) - 1; - let tagName = namespaceAndTag.includes(":") ? namespaceAndTag.split(':')[1] : namespaceAndTag; + let namespaceAndTag; + let index; + let tagName; + + if (part.includes("@")) + { + let strAttributeName = part.slice(1); + return {content: currentElement, attribute: strAttributeName}; + } + if (part.includes("[")) + { + namespaceAndTag = part.split('[')[0]; + let partBeforeCloseBrack = part.split(']')[0]; + index = partBeforeCloseBrack.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) { - return null; // Элемент не найден + break; // Элемент не найден } currentElement = matchingChildren[index]; } - return currentElement; + return {content: currentElement, attribute: undefined}; } CustomXmlManager.prototype.getContentByDataBinding = function(dataBinding, oContentLink) { @@ -106,10 +121,15 @@ // этот атрибут может быть опущен, так искать плохо if (dataBinding.storeItemID === customXml.itemId) { - let xPath = dataBinding.xpath; + let xPath = dataBinding.xpath; + let oFindEl = this.findElementsByXPath(customXml.content, xPath); + let content = oFindEl.content; + let strAttribute = oFindEl.attribute; - let content = this.findElementsByXPath(customXml.content, xPath); - return content.textContent; + if (undefined !== strAttribute) + return content.attribute[strAttribute]; + else + return content.textContent; } } }; @@ -121,22 +141,27 @@ if (dataBinding.storeItemID === customXml.itemId) { - let xPath = dataBinding.xpath; - let content = this.findElementsByXPath(customXml.content, xPath); + let xPath = dataBinding.xpath; + let oFindEl = this.findElementsByXPath(customXml.content, xPath); + let content = oFindEl.content; + let strAttribute = oFindEl.attribute; if (data instanceof AscCommonWord.CBlockLevelSdt) { - // this.updateRichTextCustomXML(data) - // пока при каждом изменении Rich Text записывать изменения не эффективно - // запишем какой контент контрол нужно изменить, а обновим при сохранении + this.updateRichTextCustomXML(data) - if (!this.RichTextCC.includes(data)) - this.RichTextCC.push(data); + // пока при каждом изменении Rich Text записывать изменения не эффективно + // запишем какой контент контрол нужно изменить, а обновим при сохранении + // if (!this.RichTextCC.includes(data)) + // this.RichTextCC.push(data); return; } - content.SetTextContent(data); + if (strAttribute) + content.SetAttribute(strAttribute, data); + else + content.SetTextContent(data); } } }; @@ -251,6 +276,10 @@ { this.textContent = str; } + this.SetAttribute = function (attribute, value) + { + this.attribute[attribute] = value; + } } let oParContent = oCurrentContent = new CustomXMLItem(null); @@ -294,10 +323,16 @@ return prefix + insertionString + suffix; } - AscCommon.History.TurnOff(); + let isOffHistory = false; + + if (AscCommon.History.IsOn() == true) + { + AscCommon.History.TurnOff(); + isOffHistory = true; + } let doc = new AscWord.CDocument(null, false); - let oSdtContent = oCC.GetContent(); + let oSdtContent = oCC.GetContent().Copy(); let jsZlib = new AscCommon.ZLib(); doc.ReplaceContent(oSdtContent.Content); @@ -358,16 +393,26 @@ outputUString = outputUString.replaceAll("<", "<"); outputUString = outputUString.replaceAll(">", ">"); - AscCommon.History.TurnOn(); + if (isOffHistory) + AscCommon.History.TurnOn(); + + doc.Content = []; this.setContentByDataBinding(oCC.Pr.DataBinding, outputUString); }; CustomXmlManager.prototype.proceedLinearXMl = function (content) { + content = content.replaceAll("<", "<"); content = content.replaceAll(">", ">"); content = content.replaceAll("", ""); content = content.replaceAll("", ""); + // при записи в атрибут больше проблем, изменить подход если в будущем еще будут проблемы c html entry + content = content.replaceAll(" ", ""); + content = content.replaceAll("&", "&"); + content = content.replaceAll(""", "\""); + content = content.replaceAll("'", "'"); + let zLib = new AscCommon.ZLib; zLib.create(); zLib.addFile('[Content_Types].xml', new TextEncoder("utf-8").encode('' + From fcc9e1fcc6fa09f6de2e737759ac7b07d3e6dff3 Mon Sep 17 00:00:00 2001 From: EvgeniyIgol Date: Thu, 22 Aug 2024 12:10:20 +0300 Subject: [PATCH 18/22] [de] Refactor CustomXml processing --- tests/word/customXML/customXML.js | 389 ++++++++++++---- word/Editor/Serialize2.js | 6 +- .../StructuredDocumentTags/BlockLevel.js | 8 + .../StructuredDocumentTags/InlineLevel.js | 18 +- word/Editor/custom-xml/custom-xml-manager.js | 420 +++++++----------- word/Editor/custom-xml/custom-xml.js | 167 ++++++- 6 files changed, 637 insertions(+), 371 deletions(-) diff --git a/tests/word/customXML/customXML.js b/tests/word/customXML/customXML.js index c8be5a228f..87f2281e6a 100644 --- a/tests/word/customXML/customXML.js +++ b/tests/word/customXML/customXML.js @@ -51,7 +51,6 @@ $(function () { return this.files; } } - this.create = function () { //console.log("ZLibFake: Creating new archive..."); @@ -59,7 +58,6 @@ $(function () { this.data = {}; return true; } - this.save = function () { //console.log("ZLibFake: Saving archive..."); @@ -68,15 +66,12 @@ $(function () { 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}`); @@ -86,7 +81,6 @@ $(function () { this.data[path] = data; return true; } - this.removeFile = function (path) { //console.log(`ZLibFake: Removing file: ${path}`); @@ -98,20 +92,17 @@ $(function () { } 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..."); @@ -127,24 +118,19 @@ $(function () { 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) { @@ -153,30 +139,52 @@ $(function () { 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 custom; - let oXMLManager = logicDocument.getCustomXmlManager(); + 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() + function CreateContentControl(isInline, nPos) { let para = AscTest.CreateParagraph(); - logicDocument.AddToContent(0, para); - return logicDocument.AddContentControl(c_oAscSdtLevelType.Block); + + logicDocument.AddToContent(nPos, para); + para.SetThisElementCurrent(); + return logicDocument.AddContentControl(isInline ? c_oAscSdtLevelType.Inline : c_oAscSdtLevelType.Block); } function CreateDataBindingForCC(contentControl, prefix, itemId, xpath, checkSum) { @@ -192,8 +200,13 @@ $(function () { } function CreateCustomXMLForDocument(strContent, ItemId, Uri) { - let oContent = oXMLManager.parseCustomXML(strContent); - let oXML = new AscWord.CustomXml(); + let oXML = new AscWord.CustomXml(); + + oXML.addContentByXMLString( + strContent !== undefined + ? strContent + : oCustomXMLs.withoutContent + ); oXML.itemId = ItemId === undefined ? "{694325A8-B1C9-407B-A2C2-E2DD1740AA5E}" @@ -203,92 +216,75 @@ $(function () { ? ['http://example.com/picture'] : Uri; - oXML.content = strContent === undefined - ? oXMLManager.parseCustomXML(oCustomXMLs.withoutContent) - : oContent; - 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; - 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=', + paragraph.SetThisElementCurrent(); + + if (false === isToStart) + paragraph.MoveCursorToEndPos(); + else + paragraph.MoveCursorToStartPos(); + + return paragraph; } - 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 CreateDateCC(nPos) + + function CreateDateCC(nPos, isInline) { - let cc = CreateFilledContentControl(nPos) + let cc = CreateFilledContentControl(nPos, isInline); let dateTimePr = new AscWord.CSdtDatePickerPr(); cc.ApplyDatePickerPr(dateTimePr, true); return cc; } - function CreateCheckBoxCC(nPos) + function CreateCheckBoxCC(nPos, isInline) { - let cc = CreateFilledContentControl(nPos) + let cc = CreateFilledContentControl(nPos, isInline) let checkboxPr = new AscWord.CSdtCheckBoxPr(); cc.ApplyCheckBoxPr(checkboxPr); return cc; } // поле со списком - function CreateComboBox(nPos) + function CreateComboBox(nPos, isInline) { - let cc = CreateFilledContentControl(nPos); + let cc = CreateFilledContentControl(nPos, isInline); let comboBoxPr = new AscWord.CSdtComboBoxPr(); cc.ApplyComboBoxPr(comboBoxPr, true); return cc; } // раскрывающийся список - function CreateDropDown(nPos) + function CreateDropDown(nPos, isInline) { - let cc = CreateFilledContentControl(nPos); + let cc = CreateFilledContentControl(nPos, isInline); let comboBoxPr = new AscWord.CSdtComboBoxPr(); cc.ApplyDropDownListPr(comboBoxPr, true); return cc; } - function CreatePicture(nPos) + function CreatePicture(nPos, isInline) { - let cc = CreateFilledContentControl(nPos); + let cc = CreateFilledContentControl(nPos, isInline); let picturePr = new AscWord.CSdtPictureFormPr(); cc.ApplyPicturePr(picturePr); return cc; } - function CreateText(nPos) + function CreateText(nPos, isInline) { - let cc = CreateFilledContentControl(nPos); + let cc = CreateFilledContentControl(nPos, isInline); cc.SetContentControlText(true) return cc; } - function CreateFilledContentControl(nPos) + function CreateFilledContentControl(nPos, isInline) { - let cc = CreateContentControl(); - let docContent = cc.GetContent(); - docContent.ClearContent(false); - - logicDocument.AddToContent(nPos, cc); - return cc; + return CreateContentControl(isInline, nPos) } function CheckContentParagraph(assert, oContentArr, arrSample) { @@ -307,7 +303,6 @@ $(function () { '\t'+ strContent +'\n' + ''; } - function Reset() { AscTest.ClearDocument(); @@ -316,6 +311,8 @@ $(function () { 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); @@ -541,22 +538,6 @@ $(function () { ); }); - 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; - } - QUnit.test("Rich text content control load from/save CustomXML", async function (assert) { CreateCustomXMLForDocument(getCheck(oCustomXMLData.linearXML)); @@ -578,8 +559,238 @@ $(function () { assert.strictEqual( str, - `\n\n\t<?xml version="1.0" standalone="yes"?>\n<?mso-application progid="Word.Document"?>\n<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" xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" mc:Ignorable="w14 w15 w16se w16cid w16 w16cex w16sdtdh wp14"><w:body><w:p><w:pPr><w:rPr></w:rPr></w:pPr><w:r><w:rPr><w:lang w:val="en-US"/></w:rPr><w:t xml:space="preserve">12345+2</w:t></w:r><w:r><w:t xml:space="preserve">990</w:t></w:r><w:r></w:r></w:p><w:sectPr><w:footnotePr></w:footnotePr><w:endnotePr></w:endnotePr><w:type w:val="nextPage"/><w:pgSz w:w="11906" w:h="16838" w:orient="portrait"/><w:pgMar w:top="1134" w:right="850" w:bottom="1134" w:left="1701" w:header="709" w:footer="709" w:gutter="0"/><w:pgBorders w:zOrder="front" w:display="allPages" w:offsetFrom="text"><w:top w:val="none" w:sz="4" w:space="0" w:color="000000"/><w:left w:val="none" w:sz="4" w:space="0" w:color="000000"/><w:bottom w:val="none" w:sz="4" w:space="0" w:color="000000"/><w:right w:val="none" w:sz="4" w:space="0" w:color="000000"/></w:pgBorders><w:pgNumType w:fmt="decimal"/><w:cols w:equalWidth="1" w:space="1701" w:num="1" w:sep="0"></w:cols><w:titlePg w:val="0"/><w:rtlGutter w:val="0"/></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: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:package>/simpleText>\n`, + ` + +\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/Serialize2.js b/word/Editor/Serialize2.js index 92b603bd8a..034d1274fa 100644 --- a/word/Editor/Serialize2.js +++ b/word/Editor/Serialize2.js @@ -16082,10 +16082,6 @@ function Binary_CustomsTableReader(doc, oReadResult, stream) { return oThis.ReadCustomContent(t, l, custom); }); - let strContent = "".fromUtf8(custom.content) - strContent = strContent.slice(strContent.indexOf("<"), strContent.length); // Skip "L" - - custom.content = this.customXmlManager.parseCustomXML(strContent); this.customXmlManager.add(custom); } else @@ -16099,7 +16095,7 @@ function Binary_CustomsTableReader(doc, oReadResult, stream) { } else if (c_oSerCustoms.ItemId === type) { 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 48d0dc2853..4ba357e6de 100644 --- a/word/Editor/StructuredDocumentTags/BlockLevel.js +++ b/word/Editor/StructuredDocumentTags/BlockLevel.js @@ -1609,6 +1609,14 @@ CBlockLevelSdt.prototype.fillContentWithDataBinding = function(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); diff --git a/word/Editor/StructuredDocumentTags/InlineLevel.js b/word/Editor/StructuredDocumentTags/InlineLevel.js index 15a7bbfad3..13617b6eec 100644 --- a/word/Editor/StructuredDocumentTags/InlineLevel.js +++ b/word/Editor/StructuredDocumentTags/InlineLevel.js @@ -2096,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"); }; /** * Проверяем, является ли данный класс специальным контейнером для картинки @@ -3809,14 +3811,16 @@ CInlineLevelSdt.prototype.fillContentWithDataBinding = function(content) this.SetDatePickerPr(datePr); this.private_UpdateDatePickerContent(); } - else if (this.IsDropDownList() || this.IsComboBox() || this.Pr.Text === true) + else if (this.IsDropDownList() || this.IsComboBox()) { - let oPar = new Paragraph(); - let oRun = new ParaRun(); - oPar.Add(oRun) - oRun.AddText(content); - - this.SetParagraph(oPar); + this.ReplacePlaceHolderWithContent(); + let oRun = this.private_UpdateListContent(); + if (oRun) + oRun.AddText(content); + } + else if (this.Pr.Text === true) + { + return } else { diff --git a/word/Editor/custom-xml/custom-xml-manager.js b/word/Editor/custom-xml/custom-xml-manager.js index 338aea4d6b..eb5dc7f3a5 100644 --- a/word/Editor/custom-xml/custom-xml-manager.js +++ b/word/Editor/custom-xml/custom-xml-manager.js @@ -35,16 +35,15 @@ (function(window) { /** - * Класс представляющий текстовый символ + * Класс представляющий менеджер CustomXMLs * @param {AscWord.CDocument} document * @constructor */ function CustomXmlManager(document) { - this.document = document; - this.xml = []; - // check - this.RichTextCC = []; + this.document = document; + this.xml = []; + this.saveCCs = []; } CustomXmlManager.prototype.add = function(customXml) { @@ -60,30 +59,40 @@ { return this.xml[index]; }; - CustomXmlManager.prototype.findElementsByXPath = function (root, xpath) + + /** + * 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 parts = xpath.split('/'); - parts.shift(); // Убираем пустой первый элемент + let arrParts = xpath.split('/'); + let currentElement = root; - let currentElement = root; + arrParts.shift(); // Убираем пустой первый элемент - for (let i = 0; i < parts.length; i++) + for (let i = 0; i < arrParts.length; i++) { - let part = parts[i]; - let namespaceAndTag; - let index; - let tagName; + let namespaceAndTag, + index, + tagName, + part = arrParts[i]; if (part.includes("@")) { - let strAttributeName = part.slice(1); - return {content: currentElement, attribute: strAttributeName}; + let strAttributeName = part.slice(1); + return { + content: currentElement, + attribute: strAttributeName, + }; } - if (part.includes("[")) + else if (part.includes("[")) { namespaceAndTag = part.split('[')[0]; - let partBeforeCloseBrack = part.split(']')[0]; - index = partBeforeCloseBrack.slice(-1) - 1; + let partBeforeCloseBracket = part.split(']')[0]; + index = partBeforeCloseBracket.slice(-1) - 1; } else { @@ -91,48 +100,62 @@ index = 0; } - tagName = namespaceAndTag.includes(":") ? namespaceAndTag.split(':')[1] : namespaceAndTag; + 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) { + if (matchingChildren.length <= index) break; // Элемент не найден - } currentElement = matchingChildren[index]; } - return {content: currentElement, attribute: undefined}; - } + 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; + let customXml = this.xml[i]; + customXml.oContentLink = oContentLink; // этот атрибут может быть опущен, так искать плохо if (dataBinding.storeItemID === customXml.itemId) { let xPath = dataBinding.xpath; - let oFindEl = this.findElementsByXPath(customXml.content, xPath); + let oFindEl = this.findElementByXPath(customXml.content, xPath); let content = oFindEl.content; let strAttribute = oFindEl.attribute; - if (undefined !== strAttribute) - return content.attribute[strAttribute]; - else - return content.textContent; + 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) @@ -142,174 +165,31 @@ if (dataBinding.storeItemID === customXml.itemId) { let xPath = dataBinding.xpath; - let oFindEl = this.findElementsByXPath(customXml.content, xPath); - let content = oFindEl.content; + let oFindEl = this.findElementByXPath(customXml.content, xPath); + let oContent = oFindEl.content; let strAttribute = oFindEl.attribute; if (data instanceof AscCommonWord.CBlockLevelSdt) { - this.updateRichTextCustomXML(data) - + // 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); - // пока при каждом изменении Rich Text записывать изменения не эффективно - // запишем какой контент контрол нужно изменить, а обновим при сохранении - // if (!this.RichTextCC.includes(data)) - // this.RichTextCC.push(data); return; } if (strAttribute) - content.SetAttribute(strAttribute, data); + oContent.setAttribute(strAttribute, data); else - content.SetTextContent(data); - } - } - }; - CustomXmlManager.prototype.parseCustomXML = function (strCustomXml) - { - let oStax = new StaxParser(strCustomXml); - let oCurrentContent = null; - - // switch to CT_Node - function CustomXMLItem(par, name) - { - this.parent = par; - this.content = []; - this.name = name ? name : ""; - this.attribute = {}; - this.textContent = ""; - this.current = undefined; - this.str = ""; - - this.AddAttribute = function (name, value) - { - this.attribute[name] = value; - } - this.AddContent = function (name) - { - let one = new CustomXMLItem(this, name); - oCurrentContent = one; - - this.content.push(one); - } - this.GetParent = function () - { - if (this.parent) - return this.parent; - - return null; - } - this.SetParent = function (oPar) - { - this.parent = oPar; - } - this.AddTextContent = function (text) - { - if (text !== "") - this.textContent += text; - } - this.GetStringFromBuffer = function () - { - let buffer = this.GetBuffer(); - let str = AscCommon.UTF8ArrayToString(buffer.data, 1); - str = str.replaceAll(""", "\""); - str = str.replaceAll("&", "&"); - return str; - } - 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.SetTextContent = function (str) - { - this.textContent = str; - } - this.SetAttribute = function (attribute, value) - { - this.attribute[attribute] = value; - } - } - - let oParContent = oCurrentContent = new CustomXMLItem(null); - - while (oStax.Read()) - { - switch (oStax.GetEventType()) - { - case EasySAXEvent.CHARACTERS: - oCurrentContent.AddTextContent(oStax.text); - break; - case EasySAXEvent.END_ELEMENT: - oCurrentContent = oCurrentContent.parent; - break; - case EasySAXEvent.START_ELEMENT: - let name = oStax.GetName(); - oCurrentContent.AddContent(name) - - while (oStax.MoveToNextAttribute()) - { - let nameAttrib = oStax.GetName(); - let valueAttrib = oStax.GetValue(); - oCurrentContent.AddAttribute(nameAttrib, valueAttrib); - } - break; + oContent.setTextContent(data); } } - - return oParContent; }; + /** + * Write linear xml data of content control in CustomXML + * @param oCC {CBlockLevelSdt} + */ CustomXmlManager.prototype.updateRichTextCustomXML = function (oCC) { function replaceSubstring(originalString, startPoint, endPoint, insertionString) @@ -323,95 +203,88 @@ return prefix + insertionString + suffix; } - let isOffHistory = false; + AscFormat.ExecuteNoHistory(function() { + let doc = new AscWord.CDocument(null, false); + let oSdtContent = oCC.GetContent().Copy(); + let jsZlib = new AscCommon.ZLib(); - if (AscCommon.History.IsOn() == true) - { - AscCommon.History.TurnOff(); - isOffHistory = true; - } - - 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)); + doc.ReplaceContent(oSdtContent.Content); + jsZlib.create(); + doc.toZip(jsZlib, new AscCommon.XmlWriterContext(AscCommon.c_oEditorId.Word)); - let archive = jsZlib.save(); - let openDoc = new AscCommon.openXml.OpenXmlPackage(jsZlib, null); - let outputUString = ""; - let arrPath = jsZlib.getPaths(); + 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")) + arrPath.forEach(function(path) { - 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") + if ((path === "_rels/.rels" || path === "word/document.xml" || path === "word/_rels/document.xml.rels") && !path.includes("glossary")) { - let text = ''; - let arrRelationships = openDoc.getRelationships(); - for (let i = 0; i < arrRelationships.length; i++) + 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 relation = arrRelationships[i]; - let relId = relation.relationshipId; - let relType = relation.relationshipType; - let relTarget = relation.target; - if(i===0) + let text = ''; + let arrRelationships = openDoc.getRelationships(); + for (let i = 0; i < arrRelationships.length; i++) { - relType = relType.replace("relationships\/officeDocument", "relationships\/styles"); - relTarget = relTarget.replace("word/document.xml", "styles.xml"); + 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 += "" } - text += "" + let nStart = ctfText.indexOf("", 0) + "".length; + let nEnd = ctfText.indexOf("", nStart) - 1; + ctfText = replaceSubstring(ctfText, nStart, nEnd, 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 += " " + - "" + ctfText.replace("", "").replace("\n", "") + "" - } - }); - - //check diffrences between main write and this, when save main document higlight write correct - // outputUString = outputUString.replace("FFFF00", "yellow"); - - //need get contentType from openXml.Types - outputUString = outputUString.replace("pkg:contentType=\"application/xml\"", "pkg:contentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml\""); - outputUString = outputUString.replace("pkg:contentType=\"application/vnd.openxmlformats-package.relationships+xml\"", "pkg:contentType=\"application/vnd.openxmlformats-package.relationships+xml\" pkg:padding=\"512\"") - outputUString = outputUString.replace("\"/word/_rels/document.xml.rels\"pkg:contentType=\"application/vnd.openxmlformats-package.relationships+xml\"", "\"/word/_rels/document.xml.rels\"pkg:contentType=\"application/vnd.openxmlformats-package.relationships+xml\" pkg:padding=\"256\"") - outputUString += ""; - outputUString = outputUString.replaceAll("<", "<"); - outputUString = outputUString.replaceAll(">", ">"); + //check diffrences between main write and this, when save main document higlight write correct + // outputUString = outputUString.replace("FFFF00", "yellow"); - if (isOffHistory) - AscCommon.History.TurnOn(); + outputUString = outputUString.replace("pkg:contentType=\"application/xml\"", "pkg:contentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml\""); + outputUString = outputUString.replace("pkg:contentType=\"application/vnd.openxmlformats-package.relationships+xml\"", "pkg:contentType=\"application/vnd.openxmlformats-package.relationships+xml\" pkg:padding=\"512\"") + outputUString = outputUString.replace("\"/word/_rels/document.xml.rels\"pkg:contentType=\"application/vnd.openxmlformats-package.relationships+xml\"", "\"/word/_rels/document.xml.rels\"pkg:contentType=\"application/vnd.openxmlformats-package.relationships+xml\" pkg:padding=\"256\"") + outputUString += ""; + outputUString = outputUString.replaceAll("<", "<"); + outputUString = outputUString.replaceAll(">", ">"); - doc.Content = []; - this.setContentByDataBinding(oCC.Pr.DataBinding, outputUString); + doc.Content = []; + this.setContentByDataBinding(oCC.Pr.DataBinding, outputUString); + }, this, []); }; - CustomXmlManager.prototype.proceedLinearXMl = function (content) + /** + * 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) { - - content = content.replaceAll("<", "<"); - content = content.replaceAll(">", ">"); - content = content.replaceAll("", ""); - content = content.replaceAll("", ""); + strLinearXML = strLinearXML.replaceAll("<", "<"); + strLinearXML = strLinearXML.replaceAll(">", ">"); + strLinearXML = strLinearXML.replaceAll("", ""); + strLinearXML = strLinearXML.replaceAll("", ""); // при записи в атрибут больше проблем, изменить подход если в будущем еще будут проблемы c html entry - content = content.replaceAll(" ", ""); - content = content.replaceAll("&", "&"); - content = content.replaceAll(""", "\""); - content = content.replaceAll("'", "'"); + strLinearXML = strLinearXML.replaceAll(" ", ""); + strLinearXML = strLinearXML.replaceAll("&", "&"); + strLinearXML = strLinearXML.replaceAll(""", "\""); + strLinearXML = strLinearXML.replaceAll("'", "'"); let zLib = new AscCommon.ZLib; zLib.create(); @@ -458,13 +331,13 @@ let nPos = 0; while (true) { - let nStartPos = nPos = content.indexOf('', nStartPos); - let strText = content.substring(nStartPos, nEndPos); + let nEndPos = nPos = strLinearXML.indexOf('', nStartPos); + let strText = strLinearXML.substring(nStartPos, nEndPos); let nPosStartName = strText.indexOf('name="', 0) + 'name="'.length; let nPosEndName = strText.indexOf('"', nPosStartName); @@ -506,7 +379,7 @@ xmlParserContext.DrawingDocument = draw; if (!jsZlib.open(arr)) - return false; + return []; let oBinaryFileReader = new AscCommonWord.BinaryFileReader(Doc, {}); oBinaryFileReader.PreLoadPrepare(); @@ -517,17 +390,28 @@ jsZlib.close(); return Doc.Content; - } - CustomXmlManager.prototype.getCustomXMLString = function(customXml) + }; + /** + * 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.RichTextCC.length; i++) + for (let i = 0; i < this.saveCCs.length; i++) { - this.updateRichTextCustomXML(this.RichTextCC[i]); + this.updateRichTextCustomXML(this.saveCCs[i]); } - - return customXml.content.GetStringFromBuffer(); }; - + //--------------------------------------------------------export---------------------------------------------------- window['AscWord'] = window['AscWord'] || {}; window['AscWord'].CustomXmlManager = CustomXmlManager; diff --git a/word/Editor/custom-xml/custom-xml.js b/word/Editor/custom-xml/custom-xml.js index 3ec60aa0b6..523b232155 100644 --- a/word/Editor/custom-xml/custom-xml.js +++ b/word/Editor/custom-xml/custom-xml.js @@ -35,6 +35,12 @@ (function(window) { /** + * @param {array} [uri] + * @param {string} [itemId] + * @param {CustomXMLContent} [content] + * @param [oContentLink] + * + * Класс представляющий CustomXML * @constructor */ function CustomXml(uri, itemId, content, oContentLink) @@ -44,9 +50,166 @@ 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(); + }; + /** + * 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); From 83e9898901105353ae773dc60fc34440f5cba656 Mon Sep 17 00:00:00 2001 From: EvgeniyIgol Date: Thu, 22 Aug 2024 15:58:10 +0300 Subject: [PATCH 19/22] [de] Fix getContentByDataBinding method --- word/Editor/Serialize2.js | 2 +- word/Editor/custom-xml/custom-xml-manager.js | 16 +++++----------- word/Editor/custom-xml/custom-xml.js | 13 +++++++++++++ 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/word/Editor/Serialize2.js b/word/Editor/Serialize2.js index 034d1274fa..98dee2e930 100644 --- a/word/Editor/Serialize2.js +++ b/word/Editor/Serialize2.js @@ -17448,4 +17448,4 @@ window["AscCommonWord"].BinaryParagraphStyleUpdater = BinaryParagraphStyleUpdate window["AscCommonWord"].BinaryTableStyleUpdater = BinaryTableStyleUpdater; window["AscCommonWord"].BinaryAbstractNumStyleLinkUpdater = BinaryAbstractNumStyleLinkUpdater; window["AscCommonWord"].BinaryAbstractNumNumStyleLinkUpdater = BinaryAbstractNumNumStyleLinkUpdater; -window["AscCommonWord"].BinaryNumLvlStyleUpdater = BinaryNumLvlStyleUpdater; \ No newline at end of file +window["AscCommonWord"].BinaryNumLvlStyleUpdater = BinaryNumLvlStyleUpdater; diff --git a/word/Editor/custom-xml/custom-xml-manager.js b/word/Editor/custom-xml/custom-xml-manager.js index eb5dc7f3a5..f0ffbfee2a 100644 --- a/word/Editor/custom-xml/custom-xml-manager.js +++ b/word/Editor/custom-xml/custom-xml-manager.js @@ -136,9 +136,8 @@ { let customXml = this.xml[i]; customXml.oContentLink = oContentLink; - - // этот атрибут может быть опущен, так искать плохо - if (dataBinding.storeItemID === customXml.itemId) + + if (dataBinding.storeItemID === customXml.itemId || customXml.checkUrl(dataBinding.prefixMappings)) { let xPath = dataBinding.xpath; let oFindEl = this.findElementByXPath(customXml.content, xPath); @@ -228,13 +227,15 @@ { 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) + + if (i === 0) { relType = relType.replace("relationships\/officeDocument", "relationships\/styles"); relTarget = relTarget.replace("word/document.xml", "styles.xml"); @@ -254,17 +255,10 @@ } }); - //check diffrences between main write and this, when save main document higlight write correct - // outputUString = outputUString.replace("FFFF00", "yellow"); - outputUString = outputUString.replace("pkg:contentType=\"application/xml\"", "pkg:contentType=\"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml\""); - outputUString = outputUString.replace("pkg:contentType=\"application/vnd.openxmlformats-package.relationships+xml\"", "pkg:contentType=\"application/vnd.openxmlformats-package.relationships+xml\" pkg:padding=\"512\"") - outputUString = outputUString.replace("\"/word/_rels/document.xml.rels\"pkg:contentType=\"application/vnd.openxmlformats-package.relationships+xml\"", "\"/word/_rels/document.xml.rels\"pkg:contentType=\"application/vnd.openxmlformats-package.relationships+xml\" pkg:padding=\"256\"") outputUString += ""; outputUString = outputUString.replaceAll("<", "<"); outputUString = outputUString.replaceAll(">", ">"); - - doc.Content = []; this.setContentByDataBinding(oCC.Pr.DataBinding, outputUString); }, this, []); }; diff --git a/word/Editor/custom-xml/custom-xml.js b/word/Editor/custom-xml/custom-xml.js index 523b232155..fe89307a4f 100644 --- a/word/Editor/custom-xml/custom-xml.js +++ b/word/Editor/custom-xml/custom-xml.js @@ -59,6 +59,19 @@ { return this.content.getStringFromBuffer(); }; + /** + * Find url in uri array + * @return {boolean} + */ + CustomXml.prototype.checkUrl = function (str) + { + 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} From 56694b01fd2557e34539c57f712212d51f6e7711 Mon Sep 17 00:00:00 2001 From: EvgeniyIgol Date: Thu, 22 Aug 2024 15:59:28 +0300 Subject: [PATCH 20/22] [de] Fix CustomXML checkUrl method --- word/Editor/custom-xml/custom-xml.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/word/Editor/custom-xml/custom-xml.js b/word/Editor/custom-xml/custom-xml.js index fe89307a4f..98ed20c2be 100644 --- a/word/Editor/custom-xml/custom-xml.js +++ b/word/Editor/custom-xml/custom-xml.js @@ -65,6 +65,9 @@ */ CustomXml.prototype.checkUrl = function (str) { + if (!str) + return false; + for (let i = 0; i < this.uri.length; i++) { if (str.includes(this.uri[i])) From aea24dd658aef11bcf0e37e6b8c119fba34cc4f3 Mon Sep 17 00:00:00 2001 From: EvgeniyIgol Date: Thu, 22 Aug 2024 16:43:33 +0300 Subject: [PATCH 21/22] Remove unnecessary code --- tests/word/customXML/customXML.js | 1 - word/Editor/StructuredDocumentTags/BlockLevel.js | 2 -- 2 files changed, 3 deletions(-) diff --git a/tests/word/customXML/customXML.js b/tests/word/customXML/customXML.js index 87f2281e6a..a48c82fa78 100644 --- a/tests/word/customXML/customXML.js +++ b/tests/word/customXML/customXML.js @@ -177,7 +177,6 @@ $(function () { 'checkboxTrueAnotherXML': "\n " + oCustomXMLData.checkboxTrue + "", } - function CreateContentControl(isInline, nPos) { let para = AscTest.CreateParagraph(); diff --git a/word/Editor/StructuredDocumentTags/BlockLevel.js b/word/Editor/StructuredDocumentTags/BlockLevel.js index 4ba357e6de..24c8726033 100644 --- a/word/Editor/StructuredDocumentTags/BlockLevel.js +++ b/word/Editor/StructuredDocumentTags/BlockLevel.js @@ -1752,8 +1752,6 @@ CBlockLevelSdt.prototype.CanBeDeleted = function() */ CBlockLevelSdt.prototype.CanBeEdited = function() { - //for debugging pictures - this.SkipSpecialLock = true; if (!this.SkipSpecialLock && (this.IsCheckBox() || this.IsPicture() || this.IsDropDownList())) return false; From 0af7a722e648c5a36f955188f7263668ecdf0826 Mon Sep 17 00:00:00 2001 From: EvgeniyIgol Date: Thu, 22 Aug 2024 16:45:19 +0300 Subject: [PATCH 22/22] Remove unnecessary code in DataBinding.recalculateCheckSum --- word/Editor/custom-xml/data-binding.js | 176 +------------------------ 1 file changed, 1 insertion(+), 175 deletions(-) diff --git a/word/Editor/custom-xml/data-binding.js b/word/Editor/custom-xml/data-binding.js index a50c7c8a12..fbb4e2df41 100644 --- a/word/Editor/custom-xml/data-binding.js +++ b/word/Editor/custom-xml/data-binding.js @@ -50,181 +50,7 @@ }; DataBinding.prototype.recalculateCheckSum = function (stringOfCustomXMlContent) { - // let str = stringOfCustomXMlContent; -// const encoder = new TextEncoder(); -// stringOfCustomXMlContent = encoder.encode(stringOfCustomXMlContent); -// -// function calculateMsoCrc32Utf8(data) { -// const polynomial = 0xAF; // Полином x^32+x^7+x^5+x^3+x^2+x+1 -// let crc = 0xFFFFFFFF; // Начальное значение -// -// for (let i = 0; i < data.length; i++) { -// let code = data.charCodeAt(i); -// -// if (code < 0x80) { -// code = code & 0xFF; // Приводим к однобайтовому значению -// crc ^= (code << 24); -// } else if (code < 0x800) { -// crc ^= ((0xC0 | (code >> 6)) << 24); -// crc ^= ((0x80 | (code & 0x3F)) << 24); -// } else if (code < 0x10000) { -// crc ^= ((0xE0 | (code >> 12)) << 24); -// crc ^= ((0x80 | ((code >> 6) & 0x3F)) << 24); -// crc ^= ((0x80 | (code & 0x3F)) << 24); -// } else { -// crc ^= ((0xF0 | (code >> 18)) << 24); -// crc ^= ((0x80 | ((code >> 12) & 0x3F)) << 24); -// crc ^= ((0x80 | ((code >> 6) & 0x3F)) << 24); -// crc ^= ((0x80 | (code & 0x3F)) << 24); -// } -// -// for (let j = 0; j < 8; j++) { -// if ((crc & 0x80000000) !== 0) { -// crc = (crc << 1) ^ polynomial; -// } else { -// crc <<= 1; -// } -// } -// } -// -// return crc >>> 0; // Возвращаем беззнаковое 32-битное значение -// } -// -// -// -// function calculateCRC(data) { -// const polynomial = 0xAF; // Полином x32+x7+x5+x3+x2+x+1 -// let crc = 0xFFFFFFFF; // Начальное значение -// -// for (let i = 0; i < data.length; i++) { -// let code = data.charCodeAt(i); -// -// if (code < 0x80) { -// crc ^= (code << 24); -// } else if (code < 0x800) { -// crc ^= ((0xC0 | (code >> 6)) << 24); -// crc ^= ((0x80 | (code & 0x3F)) << 24); -// } else if (code < 0x10000) { -// crc ^= ((0xE0 | (code >> 12)) << 24); -// crc ^= ((0x80 | ((code >> 6) & 0x3F)) << 24); -// crc ^= ((0x80 | (code & 0x3F)) << 24); -// } else { -// crc ^= ((0xF0 | (code >> 18)) << 24); -// crc ^= ((0x80 | ((code >> 12) & 0x3F)) << 24); -// crc ^= ((0x80 | ((code >> 6) & 0x3F)) << 24); -// crc ^= ((0x80 | (code & 0x3F)) << 24); -// } -// -// for (let j = 0; j < 8; j++) { -// if ((crc & 0x80000000) !== 0) { -// crc = (crc << 1) ^ polynomial; -// } else { -// crc <<= 1; -// } -// } -// } -// -// return crc >>> 0; -// } -// -// function CRC(CrcValue, data) { -// for (let i = 0; i < data.length; i++) { -// let byte = data.charCodeAt(i); -// -// let index = CrcValue; -// index = (index >>> 24) ^ byte; -// -// CrcValue <<= 8; -// CrcValue ^= index; // Просто XOR с байтом -// } -// -// return CrcValue >>> 0; // Возвращаем беззнаковое 32-битное значение -// } -// -// const crcResult = CRC( 0xFFFFFFFF, str); -// const byteArray = [ -// (crcResult >> 24) & 0xFF, -// (crcResult >> 16) & 0xFF, -// (crcResult >> 8) & 0xFF, -// crcResult & 0xFF -// ]; -// -// const base64Value = bytesToBase64(byteArray); -// console.log(base64Value) -// -// function bytesToBase64(bytes) { -// const base64Chars = -// 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; -// -// let result = ''; -// let i = 0; -// -// while (i < bytes.length) { -// const byte1 = bytes[i++] & 0xff; -// const byte2 = bytes[i++] & 0xff; -// const byte3 = bytes[i++] & 0xff; -// -// const enc1 = byte1 >> 2; -// const enc2 = ((byte1 & 3) << 4) | (byte2 >> 4); -// const enc3 = ((byte2 & 15) << 2) | (byte3 >> 6); -// const enc4 = byte3 & 63; -// -// if (isNaN(byte2)) { -// enc3 = enc4 = 64; -// } else if (isNaN(byte3)) { -// enc4 = 64; -// } -// -// result += -// base64Chars.charAt(enc1) + -// base64Chars.charAt(enc2) + -// base64Chars.charAt(enc3) + -// base64Chars.charAt(enc4); -// } -// -// return result; -// } -// -// -// -// -// console.log(calculateCRC(str)); -// -// //check -// const CRC32_POLY = 0x04C11DB7; -// let crc32TableArray = new Array(256); -// let crcValue = 0xFFFFFFFF; -// -// // InitializationOfCRC32TableArray Function -// function initializeCRC32TableArray() { -// for (let iValue = 0; iValue < crc32TableArray.length; iValue++) { -// let cValue = iValue << 24; -// for (let jValue = 8; jValue > 0; jValue--) { -// cValue = (cValue & 0x80000000) ? ((cValue << 1) ^ CRC32_POLY) : (cValue << 1); -// crc32TableArray[iValue] = cValue; -// } -// } -// } -// -// // Calculation of crc32Value -// function calculateCRC32Value(pBuffer, cLength) { -// for (let i = 0; i < cLength; i++) { -// let tempIndex = (crcValue >>> 24) ^ pBuffer[i]; -// crcValue = (crcValue << 8) ^ crc32TableArray[tempIndex]; -// } -// } -// -// initializeCRC32TableArray(); -// const buffer = stringOfCustomXMlContent; -// const bufferLength = buffer.length; -// calculateCRC32Value(buffer, bufferLength); -// console.log("CRC32 Value:", crcValue); -// -// -// let crc = AscCommon.g_oCRC32.Calculate_ByString(str, str.length); -// console.log(crc) -// this.storeItemCheckSum = AscCommon.Base64.encode(crcValue.toString()); - } + }; DataBinding.prototype.toBinary = function(writer) { return this.Write_ToBinary(writer);