diff --git a/common/custom-xml/serialize-custom-xml.js b/common/custom-xml/serialize-custom-xml.js index c31843ac8b..526dfd805d 100644 --- a/common/custom-xml/serialize-custom-xml.js +++ b/common/custom-xml/serialize-custom-xml.js @@ -73,10 +73,10 @@ } }; this.WriteCustomXml = function(customXml) { - let namespaces = customXml.getAllNamespaces(); - for (let i = 0; i < namespaces.length; ++i) { + let refs = customXml.getSchemaRefs(); + for (let i = 0; i < refs.length; ++i) { this.bs.WriteItem(c_oSerCustoms.Uri, function () { - _t.memory.WriteString3(namespaces[i]); + _t.memory.WriteString3(refs[i]); }); } if (null !== customXml.itemId) { @@ -112,7 +112,7 @@ // namespaces s.StartRecord(c_oSerCustomsPPTY.Uri); - let ns = Object.keys(customXml.nsManager.urls); + let ns = customXml.getSchemaRefs(); s.WriteULong(ns.length); for (let i = 0; i < ns.length; ++i) { @@ -172,7 +172,7 @@ }; this.ReadCustomContent = function(type, length, custom) { if (c_oSerCustoms.Uri === type) { - custom.setNamespaceUri(this.stream.GetString2LE(length)); + custom.addSchemaRef(this.stream.GetString2LE(length)); } else if (c_oSerCustoms.ItemId === type) { custom.itemId = this.stream.GetString2LE(length); } else if (c_oSerCustoms.ContentA === type || c_oSerCustoms.Content === type) { @@ -232,7 +232,7 @@ this.stream.GetUChar(); // AscCommon.g_nodeAttributeStart if (0 === this.stream.GetUChar()) { let ns = this.stream.GetString2(); - customXml.setNamespaceUri(ns); + customXml.addSchemaRef(ns); } this.stream.GetUChar(); // AscCommon.g_nodeAttributeEnd return c_oSerConstants.ReadOk; diff --git a/word/Editor/custom-xml/custom-xml-changes.js b/word/Editor/custom-xml/custom-xml-changes.js index 1ed490e319..0193913299 100644 --- a/word/Editor/custom-xml/custom-xml-changes.js +++ b/word/Editor/custom-xml/custom-xml-changes.js @@ -172,7 +172,7 @@ //------------------------------------------------------------------------------------------------------------------ AscDFH.historyitem_CustomXmlManager_Content_Start = AscDFH.historyitem_type_CustomXml | 1; AscDFH.historyitem_CustomXmlManager_Content_Part = AscDFH.historyitem_type_CustomXml | 2; - AscDFH.historyitem_CustomXmlManager_Content_End = AscDFH.historyitem_type_CustomXml | 2; + AscDFH.historyitem_CustomXmlManager_Content_End = AscDFH.historyitem_type_CustomXml | 3; /** * @constructor diff --git a/word/Editor/custom-xml/custom-xml-manager.js b/word/Editor/custom-xml/custom-xml-manager.js index be639beb7e..4463a96e77 100644 --- a/word/Editor/custom-xml/custom-xml-manager.js +++ b/word/Editor/custom-xml/custom-xml-manager.js @@ -112,9 +112,9 @@ { return this.xml[index]; }; - CustomXmlManager.prototype.createCustomXml = function(content, uri) + CustomXmlManager.prototype.createCustomXml = function(content, schemaRefs) { - let oXML = new AscWord.CustomXml(this, false, uri ? [uri] : null, content); + let oXML = new AscWord.CustomXml(this, false, schemaRefs, content); this.add(oXML); oXML.writeContent("", oXML.getText()); return oXML; diff --git a/word/Editor/custom-xml/custom-xml.js b/word/Editor/custom-xml/custom-xml.js index 197a657605..01b6184daf 100644 --- a/word/Editor/custom-xml/custom-xml.js +++ b/word/Editor/custom-xml/custom-xml.js @@ -37,21 +37,21 @@ /** * @param {AscWord.CustomXmlManager} xmlManager * @param {string} [itemId=null] - * @param {CustomXmlPrefixMappings} [nsManager=null] + * @param {string[]} [schemaRefs=null] * @param {CustomXmlContent} [content] * * Класс представляющий CustomXML * @constructor */ - function CustomXml(xmlManager, itemId, nsManager, content) + function CustomXml(xmlManager, itemId, schemaRefs, content) { this.Id = AscCommon.g_oIdCounter.Get_NewId(); this.Parent = xmlManager; this.itemId = itemId ? itemId : AscCommon.CreateGUID(); this.content = null; - this.nsManager = (nsManager && nsManager instanceof CustomXmlPrefixMappings) - ? nsManager - : new CustomXmlPrefixMappings(nsManager); + this.nsManager = new CustomXmlPrefixMappings(); // + this.nsURI = ""; // calculated from content + this.schemaRefs = new CustomXMLSchemaRefs(schemaRefs); this.addContentByXMLString(content); this.m_aCustomXmlData = ''; @@ -64,7 +64,7 @@ let oCopy = new CustomXml( this.Parent, this.itemId, - this.nsManager, + Object.assign([], this.schemaRefs), undefined ); @@ -76,7 +76,7 @@ { if (this.Parent) return this.Parent.deleteExactXml(this.itemId); - + return false; }; CustomXml.prototype.Get_Id = function () @@ -89,19 +89,18 @@ }; CustomXml.prototype.Refresh_RecalcData = function(Data) { - // Ничего не делаем (если что просто будет перерисовка) + // Ничего не делаем }; CustomXml.prototype.Write_ToBinary2 = function(Writer) { Writer.WriteLong(AscDFH.historyitem_type_CustomXml); - // String : Id // Long : Количество элементов // Array of Strings : массив с Id элементов Writer.WriteString2(this.Id); Writer.WriteString2(this.itemId); - this.nsManager.Write_ToBinary2(Writer); + this.schemaRefs.Write_ToBinary2(Writer); }; CustomXml.prototype.Read_FromBinary2 = function(Reader) { @@ -111,7 +110,7 @@ this.Id = Reader.GetString2(); this.itemId = Reader.GetString2(); this.Parent = editor.WordControl.m_oLogicDocument.getCustomXmlManager(); - this.nsManager.Read_FromBinary2(Reader); + this.schemaRefs.Read_FromBinary2(Reader); }; CustomXml.prototype.Write_ToBinary = function(Writer) { @@ -149,18 +148,41 @@ this.itemId = itemId; }; /** - * Add given uri to CustomXMl uri list + * Add given uri to CustomXML namespace list * @param {string} prefix * @param {string} ns */ CustomXml.prototype.addNamespace = function(prefix, ns) { - if (!prefix) - prefix = "defaultNamespace"; + let nNsCount = this.nsManager.getNsCount(); + let nsPrefix = (nNsCount > 0 ) ? nNsCount : ""; + + if (!prefix || prefix === "") + prefix = "ns" + nsPrefix; this.nsManager.addNamespace(prefix, ns); return true; }; + CustomXml.prototype.getNamespaceURI = function() + { + return this.nsURI; + }; + CustomXml.prototype.setNamespaceURI = function(nsURI) + { + this.nsURI = nsURI; + }; + /** + * Add given schemaRef to CustomXML + * @param {string} schemaRef + */ + CustomXml.prototype.addSchemaRef = function(ref) + { + return this.schemaRefs.add(ref); + }; + CustomXml.prototype.getSchemaRefs = function() + { + return this.schemaRefs.getAll(); + }; /** * Get CustomXML data by string * @return {string} @@ -193,14 +215,14 @@ let startPos = customXml.indexOf("<"); if (-1 !== startPos) customXml = customXml.slice(customXml.indexOf("<")); // Skip "L" - + this.addContentByXMLString(customXml); }; CustomXml.prototype.addContentByXMLString = function(strCustomXml) { if (strCustomXml === undefined) return; - + if (strCustomXml instanceof CustomXmlContent) strCustomXml = strCustomXml.getStringFromBuffer(); @@ -250,10 +272,10 @@ } function findMatchingNodes(elements, steps) { - + if (steps.length === 0) return elements; - + let step = steps[0]; let part = step.part; let deep = step.deepNext; @@ -279,7 +301,7 @@ { let bracketOpen = part.indexOf('['); let bracketClose = part.indexOf(']'); - + if (bracketOpen !== -1 && bracketClose !== -1 && bracketClose > bracketOpen) { let rawTag = part.slice(0, bracketOpen); @@ -434,14 +456,6 @@ this.afterChange(); return data; }; - CustomXml.prototype.setNamespaceUri = function(ns) - { - this.nsManager.setNamespaceUri(ns); - }; - CustomXml.prototype.getNamespaceUri = function() - { - return this.nsManager.getNamespaceUri(); - }; CustomXml.prototype.getAllNamespaces = function() { return Object.keys(this.nsManager.urls); @@ -692,7 +706,7 @@ start = 0; if (undefined === len) len = buffer.length; - + var result = ""; var index = start; var end = start + len; @@ -766,13 +780,20 @@ let attributeName = oStax.GetName(); let attributeValue = oStax.GetValue(); - if (attributeName === 'xmlns' && rootContent.xml) - rootContent.xml.addNamespace("defaultNamespace", attributeValue); + if (attributeName.length >= 5 && attributeName.slice(0,5) === 'xmlns') + { + // Add unique namespace URI to schema references + rootContent.xml.addSchemaRef(attributeValue); - let prefix = getPrefix(attributeName); - if (prefix && rootContent.xml) + // Register any namespace in NamespaceManager + let prefix = getPrefix(attributeName); rootContent.xml.addNamespace(prefix, attributeValue); + // Set the main NamespaceURI from root element if not set yet + if (rootContent.parentNode === null && rootContent.xml.nsURI === "") + rootContent.xml.setNamespaceURI(attributeValue); + } + childElement.addAttribute(attributeName, attributeValue); } rootContent = childElement;break; @@ -782,17 +803,21 @@ } function CustomXmlPrefixMappings() { - this.urls = {}; + this.prefixMappings = {}; this.prefix = {}; - this.namespaceUri = ""; - this.setNamespaceUri = function(ns) + this.getPrefixes = function() { - this.namespaceUri = ns; + return Object.keys(this.prefix); }; - this.getNamespaceUri = function() + this.getNamespaces = function() { - return this.namespaceUri; + return Object.keys(this.prefixMappings); + }; + this.getNsCount = function() + { + let arrNamespaces = this.getNamespaces(); + return arrNamespaces.length; }; this.addNamespace = function (prefix, ns) { @@ -801,9 +826,9 @@ if (prefix && ns) { - let prevPrefix = this.urls[ns]; + let prevPrefix = this.prefixMappings[ns]; - this.urls[ns] = prefix; + this.prefixMappings[ns] = prefix; if (prevPrefix) delete this.prefix[prevPrefix]; @@ -815,44 +840,43 @@ { return this.prefix[prefix]; }; - this.getPrefix = function(urls) + this.getPrefix = function(ns) { - return this.urls[urls]; + return this.prefixMappings[ns]; + }; + } + + function CustomXMLSchemaRefs(refs) + { + this.refs = refs ? Object.assign([], refs) : []; + + this.getAll = function() + { + return Object.assign([], this.refs); + }; + this.add = function(schemaUri) + { + if (schemaUri && schemaUri.trim() !== "" && !this.refs.includes(schemaUri)) + { + this.refs.push(schemaUri); + return true; + } + + return false; }; this.Write_ToBinary2 = function(Writer) { - Writer.WriteString2(this.namespaceUri); - - let urls = Object.keys(this.urls); - let Count = urls.length; + let Count = this.refs.length; Writer.WriteLong(Count); for (let Index = 0; Index < Count; Index++) - Writer.WriteString2(urls[Index]); - - Writer.WriteLong(Count); - for (let Index = 0; Index < Count; Index++) - Writer.WriteString2(this.urls[urls[Index]]); + Writer.WriteString2(this.refs[Index]); }; this.Read_FromBinary2 = function(Reader) { - this.namespaceUri = Reader.GetString2() - let url = []; - let Count = Reader.GetLong(); for (let Index = 0; Index < Count; Index++) - { - url.push(Reader.GetString2()); - this.urls[url[url.length - 1]] = ""; - } - - Count = Reader.GetLong(); - for (let Index = 0; Index < Count; Index++) - { - let prefix = Reader.GetString2() - this.prefix[prefix] = url[Index]; - this.urls[url[Index]] = prefix; - } + this.refs.push(Reader.GetString2()); }; }