Files
DocumentServer-v-9.2.0/sdkjs/vendor/easysax.js
T
Yajbir Singh f1b860b25c
check / markdownlint (push) Has been cancelled
check / spellchecker (push) Has been cancelled
updated
2025-12-11 19:03:17 +05:30

2177 lines
72 KiB
JavaScript

'use strict';
/*
new function() {
var parser = new EasySAXParser();
parser.ns('rss', { // or false
'http://search.yahoo.com/mrss/': 'media',
'http://www.w3.org/1999/xhtml': 'xhtml',
'http://www.w3.org/2005/Atom': 'atom',
'http://purl.org/rss/1.0/': 'rss',
});
parser.on('error', function(msgError) {
});
parser.on('startNode', function(nodeName, getAttr, isTagEnd, getStrNode) {
var attr = getAttr();
});
parser.on('endNode', function(nodeName, isTagStart, getStrNode) {
});
parser.on('textNode', function(text) {
});
parser.on('cdata', function(data) {
});
parser.on('comment', function(text) {
//console.log('--'+text+'--')
});
//parser.on('unknownNS', function(key) {console.log('unknownNS: ' + key)});
//parser.on('question', function() {}); // <? ... ?>
//parser.on('attention', function() {}); // <!XXXXX zzzz="eeee">
parser.write(stringChunk);
parser.write(stringChunk);
...
parser.end(stringChunk);
};
*/
// << ------------------------------------------------------------------------ >> //
EasySAXParser.entityDecode = xmlEntityDecode;
if (typeof module === 'object') {
module.exports = EasySAXParser;
};
var stringFromCharCode = String.fromCharCode;
var objectCreate = Object.create;
function NULL_FUNC() {};
function entity2char(x) {
if (x === 'amp') {
return '&';
};
switch(x.toLocaleLowerCase()) {
case 'quot': return '"';
case 'amp': return '&'
case 'lt': return '<'
case 'gt': return '>'
case 'plusmn': return '\u00B1';
case 'laquo': return '\u00AB';
case 'raquo': return '\u00BB';
case 'micro': return '\u00B5';
case 'nbsp': return '\u00A0';
case 'copy': return '\u00A9';
case 'sup2': return '\u00B2';
case 'sup3': return '\u00B3';
case 'para': return '\u00B6';
case 'reg': return '\u00AE';
case 'deg': return '\u00B0';
case 'apos': return '\'';
};
return '&' + x + ';';
};
function replaceEntities(s, d, x, z) {
if (z) {
return entity2char(z);
};
if (d) {
return stringFromCharCode(d);
};
return stringFromCharCode(parseInt(x, 16));
};
function xmlEntityDecode(s) {
return StaxParser.prototype.DecodeXml(s);
};
function cloneMatrixNS(nsmatrix) {
var nn = objectCreate(null);
for (var n in nsmatrix) {
nn[n] = nsmatrix[n];
};
return nn;
};
var EasySAXEvent = {
Unknown: 0,
START_ELEMENT: 1,
CHARACTERS: 2,
END_ELEMENT: 3,
CDATA: 4,
Comment: 5,
Attention: 6,
Question: 7
}
function EasySAXParser(config) {
if (!this) {
return null;
};
var onTextNode = NULL_FUNC, onStartNode = NULL_FUNC, onEndNode = NULL_FUNC, onCDATA = NULL_FUNC, onError = NULL_FUNC, onComment, onQuestion, onAttention, onUnknownNS;
var is_onComment = false, is_onQuestion = false, is_onAttention = false, is_onUnknownNS = false;
var isAutoEntity = true; // делать "EntityDecode" всегда
var indexStartXML; // позиция на которой закончен разбор xml
var entityDecode = xmlEntityDecode;
var isNamespace = false;
var returnError;
var isParseStop; // прервать парсер
var defaultNS;
var nsmatrix = null;
var useNS;
var init = false;
var xml; // string
var stringNodePosStart; // number. для получения исходной строки узла
var stringNodePosEnd; // number. для получения исходной строки узла
var attrStartPos; // number начало позиции атрибутов в строке attrString <(div^ class="xxxx" title="sssss")/>
var attrString; // строка атрибутов <(div class="xxxx" title="sssss")/>
var attrRes; // закешированный результат разбора атрибутов , null - разбор не проводился, object - хеш атрибутов, true - нет атрибутов, false - невалидный xml
function reset() {
if (isNamespace) {
nsmatrix = objectCreate(null);
nsmatrix.xmlns = defaultNS;
};
indexStartXML = 0;
returnError = '';
isParseStop = false;
xml = '';
};
this.setup = function (op) {
for (var name in op) {
switch(name) {
case 'entityDecode': entityDecode = op.entityDecode || entityDecode; break;
case 'autoEntity': isAutoEntity = !!op.autoEntity; break;
case 'defaultNS': defaultNS = op.defaultNS || null; break;
case 'ns': useNS = op.ns || null; break;
case 'on':
var listeners = op.on;
for (var ev in listeners) {
this.on(ev, listeners[ev]);
};
break;
};
};
isNamespace = !!defaultNS && !!useNS;
};
this.on = function(name, cb) {
// if (typeof cb !== 'function') {
// if (cb !== null) {
// throw error('required args on(string, function||null)');
// };
// };
switch(name) {
case 'startNode': onStartNode = cb || NULL_FUNC; break;
case 'endNode': onEndNode = cb || NULL_FUNC; break;
case 'text': case 'textNode': onTextNode = cb || NULL_FUNC; break;
case 'error': onError = cb || NULL_FUNC; break;
case 'cdata': onCDATA = cb || NULL_FUNC; break;
case 'unknownNS': onUnknownNS = cb; is_onUnknownNS = !!cb; break;
case 'attention': onAttention = cb; is_onAttention = !!cb; break; // <!XXXXX zzzz="eeee">
case 'question': onQuestion = cb; is_onQuestion = !!cb; break; // <? .... ?>
case 'comment': onComment = cb; is_onComment = !!cb; break;
};
};
this.ns = function(root, ns) {
if (!root) {
isNamespace = false;
defaultNS = null;
useNS = null;
return this;
};
if (!ns || typeof root !== 'string') {
throw Error('required args ns(string, object)');
};
isNamespace = !!(useNS = ns || null);
defaultNS = root || null;
return this;
};
this.write = function(chunk) {
if (typeof chunk !== 'string' || isParseStop) {
return;
};
if (!init) {
init = true;
reset();
};
xml = xml ? xml + chunk : chunk;
parse();
if (isParseStop && returnError) {
if (returnError) {
onError(returnError);
returnError = '';
};
};
if (indexStartXML > 0) {
xml = xml.substring(indexStartXML);
indexStartXML = 0;
};
return this;
};
this.end = function() {
if (returnError) {
onError(returnError);
returnError = '';
};
attrString = '';
init = false;
xml = '';
};
this.parse = function(xml) {
this.write(xml);
this.end();
};
this.staxParseXml = function(xml) {
staxParseWithEvents.call(this, xml);
};
this.stop = function() {
isParseStop = true;
};
if (config) {
this.setup(config);
};
// -----------------------------------------------------
var nodeParseAttrResult; // null - кеш пустой, true - атрибутов нет, {...} - карта атрибутов
var nodeParseAttrSize = 0; // число элементов nodeParseAttrMap
var nodeParseAttrMap = ['','','','','','','','','','']; // карта атрибутов. четные индексы "имя", не четные "значение"
var nodeParseHasNS = false;
var nodeParseName; // имя ноды
// разбор ноды <nodeName ...> или <nodeName .../>
// на вход indexStart = xml.indexOf('<');
// return xml.indexOf('>', ixNameStart);
function parseNode(indexStart) {
var ixNameStart = +indexStart + 1; // позиция первого сивола имени
var ixNameEnd; // позиция последнего + 1 сивола имени
var attrName;
var i = ixNameStart;
var l = xml.length;
var w;
var iE = xml.indexOf('>', ixNameStart);
var iR;
if (iE === -1) { // не полный xml. дальнейший парсинг бессмыслен
returnError = '#1901 invalid node'; // не полный xml
return -1;
};
nodeParseAttrResult = null;
nodeParseAttrSize = 0;
nodeParseHasNS = false;
nodeParseName = '';
if (i >= l) {
returnError = '#4952 invalid node'; // не полный xml
return -1;
};
w = xml.charCodeAt(i);
if (!(w > 96 && w < 123 || w > 64 && w < 91 || w === 95 || w === 58)) { // char 95"_" 58":"
returnError = '#4940 first char <nodeName .../>';
isParseStop = true; // дальнейший разбор невозможен
return -1;
};
while(true) {
if (++i >= l) {
returnError = '#4950 invalid node'; // не полный xml
return -1; // errorParse
};
w = xml.charCodeAt(i);
if (w > 96 && w < 123 || w > 64 && w < 91 || w > 47 && w < 59 || w === 45 || w === 46 || w === 95) {
continue; // символы имени тега только латиница
};
if (w === 32 || w === 9 || w === 10 || w === 11 || w === 12 || w === 13) { // \f\n\r\t\v пробел
nodeParseName = xml.substring(ixNameStart, ixNameEnd = i);
break;
};
if (w === 62 /* ">" */) { // тег закрылся, атрибутов нет
nodeParseName = xml.substring(ixNameStart, ixNameEnd = i);
return i;
};
if (w === 47 /* "/" */) {
ixNameEnd = i;
w = xml.charCodeAt(++i);
if (w === 62) {
nodeParseName = xml.substring(ixNameStart, ixNameEnd);
return i;
};
returnError = '#0320 invalid node .../>?';
isParseStop = true; // дальнейший разбор невозможен
return -1;
};
returnError = '#5347 invalid nodeName';
isParseStop = true; // дальнейший разбор невозможен
return -1;
};
i += 1; // первый сивол пробел его пропускаем
while(true) {
iR = xml.indexOf('=', i);
if (iR > iE || iR === -1) {
break;
};
attrName = xml.substring(i, iR);
if (isNamespace) {
attrName = attrName.trim();
if (attrName.charCodeAt(0) === 120 && attrName.substr(0, 6) === 'xmlns') {
nodeParseHasNS = true;
};
};
nodeParseAttrMap[nodeParseAttrSize++] = attrName; // имя атрибута
w = xml.charCodeAt(++iR);
while(w === 32 || w === 9 || w === 10 || w === 11 || w === 12 || w === 13) { // \f\n\r\t\v
w = xml.charCodeAt(++iR);
};
if (w === 34) {
i = xml.indexOf('"', iR + 1);
} else {
i = xml.indexOf('\'', iR + 1);
};
if (i === -1) {
returnError = '#5858 invalid node'; // не полный xml
return -1;
};
nodeParseAttrMap[nodeParseAttrSize++] = xml.substring(iR + 1, i); // значение атрибута
i += 1;
if (i === iE) {
break;
};
if (i > iE) {
iE = xml.indexOf('>', i);
if (iE === -1) {
returnError = '#0901 invalid node'; // не полный xml
return -1;
};
};
if (iE - i < 4) {
break;
};
};
return iE;
};
function upNSMATRIX() {
var hasNewMatrix;
var newalias;
var alias;
var value;
var name;
var j;
if (!nodeParseAttrSize) {
return;
};
for (j = 0; j < nodeParseAttrSize; j += 2) {
name = nodeParseAttrMap[j];
if (name !== 'xmlns') {
if (name.charCodeAt(0) !== 120 || name.substr(0, 6) !== 'xmlns:') {
continue;
};
newalias = name.substr(6);
} else {
newalias = 'xmlns';
};
value = nodeParseAttrMap[j + 1];
//alias = useNS[isAutoEntity ? value : entityDecode(value)];
alias = useNS[entityDecode(value)];
if (is_onUnknownNS && !alias) {
alias = onUnknownNS(value);
};
if (alias) {
if (nsmatrix[newalias] !== alias) {
if (!hasNewMatrix) {
nsmatrix = cloneMatrixNS(nsmatrix);
hasNewMatrix = true;
};
nsmatrix[newalias] = alias;
};
continue;
};
if (nsmatrix[newalias]) {
if (!hasNewMatrix) {
nsmatrix = cloneMatrixNS(nsmatrix);
hasNewMatrix = true;
};
nsmatrix[newalias] = false;
};
};
};
function getAttrs() {
if (nodeParseAttrResult !== null) {
return nodeParseAttrResult;
};
if (nodeParseAttrSize === 0) {
return nodeParseAttrResult = true;
};
var xmlnsAlias;
var nsName;
var iQ;
var attrs = {};
var value;
var name;
var j;
if (isNamespace) {
xmlnsAlias = nsmatrix.xmlns;
};
for (j = 0; j < nodeParseAttrSize; j++) {
name = isNamespace ? nodeParseAttrMap[j] : nodeParseAttrMap[j].trim();
if (isNamespace) {
iQ = name.indexOf(':');
if (iQ !== -1) {
nsName = nsmatrix[name.substring(0, iQ)];
if (!nsName || nsName === 'xmlns') {
continue;
};
name = xmlnsAlias !== nsName ? nsName + name.substr(iQ) : name.substr(iQ + 1);
};
};
value = nodeParseAttrMap[++j];
if (isAutoEntity) {
value = entityDecode(value);
};
attrs[name] = value;
};
return nodeParseAttrResult = attrs;
};
function getStringNode() { // вернет исходную строку узла
return xml.substring(stringNodePosStart, stringNodePosEnd);
};
var parseStackMatrixNS = [];
var parseStackNodes = [];
var stopIndexNS = 0;
function parse() {
// разбор идет по элементам (тег, текст cdata, ...).
// элемент должен быть целиком в памяти
var _nsmatrix;
var isTagStart = false;
var isTagEnd = false;
//var nodeBody;
var stopEmit; // используется при разборе "namespace" . если встретился неизвестное пространство то события не генерируются
var nodeName;
var xmlns;
var iD;
var iQ;
var w;
var i; // number
returnError = null; // сброс ошибки неудачного разбора
while(indexStartXML !== -1) {
stopEmit = stopIndexNS > 0;
// поиск начала тега
if (xml.charCodeAt(indexStartXML) === 60) { // "<"
i = indexStartXML;
} else {
i = xml.indexOf('<', indexStartXML);
};
if (i === -1) { // узел не найден. повторим попытку на след. write
if (parseStackNodes.length) {
returnError = 'unexpected end parse';
return;
};
// --- нужно подумать как обрабатывать начало файла ---
// if (indexStartXML === 0) { // разбор еше не начат. возможно это начало файла. мусор до первого тега игнор
// returnError = 'missing first tag';
// return;
// };
return;
};
if (indexStartXML !== i && !stopEmit) { // все что до тега это текст
var text = xml.substring(indexStartXML, i);
indexStartXML = i; // до этой позиции разбор завершен
onTextNode(isAutoEntity ? entityDecode(text) : text);
if (isParseStop) {
return;
};
};
// ELEMENT
// ---------------------------------------------
w = xml.charCodeAt(i + 1);
if (w === 33) { // 33 == "!"
var wNext = xml.charCodeAt(i + 2);
// CDATA
// ---------------------------------------------
if (wNext === 91 && xml.substr(i + 3, 6) === 'CDATA[') { // 91 == "["
var indexStartCDATA = i + 9;
var indexEndCDATA = xml.indexOf(']]>', indexStartCDATA);
if (indexEndCDATA === -1) {
returnError = 'cdata, not found ...]]>'; // не закрыт CDATA. повторим попытку на след. write
return;
};
indexStartXML = indexEndCDATA + 3;
if (!stopEmit) {
onCDATA(xml.substring(indexStartCDATA, indexEndCDATA));
if (isParseStop) {
return;
};
};
continue;
};
// COMMENT
// ---------------------------------------------
if (wNext === 45 && xml.charCodeAt(i + 3) === 45) { // 45 == "-"
var indexStartComment = i + 4;
var indexEndComment = xml.indexOf('-->', indexStartComment);
if (indexEndComment === -1) {
returnError = 'expected -->'; // не закрыт комментарий. повторим попытку на след. write
return;
};
indexStartXML = indexEndComment + 3;
if (is_onComment && !stopEmit) {
var commentText = xml.substring(indexStartComment, indexEndComment);
onComment(isAutoEntity ? entityDecode(commentText) : commentText);
if (isParseStop) {
return;
};
};
continue;
};
// ATTENTION
// ---------------------------------------------
{
var indexStartAttention = i + 1;
var indexEndAttention = xml.indexOf('>', indexStartAttention);
if (indexEndAttention === -1) {
returnError = 'expected attention ...>'; // повторим попытку на след. write
return;
};
indexStartXML = indexEndAttention + 1;
if (is_onAttention && !stopEmit) {
onAttention(xml.substring(i, indexStartXML)); // весь тег, так как не придумал api
if (isParseStop) {
return;
};
};
};
continue;
};
// QUESTION
// ---------------------------------------------
if (w === 63) { // "?"
var indexEndQuestion = xml.indexOf('?>', i);
if (indexEndQuestion === -1) { // error
returnError = 'expected question ...?>'; // повторим попытку на след. write
return;
};
indexStartXML = indexEndQuestion + 2;
if (is_onQuestion) {
onQuestion(xml.substring(i, indexStartXML)); // весь тег, так как не придумал api
if (isParseStop) {
return;
};
};
continue;
};
// NODE ELEMENT
// ---------------------------------------------
if (w === 47) { // </...
var indexEndNode = xml.indexOf('>', i + 1);
if (indexEndNode === -1) { // error ...> // не нашел знак закрытия тега
returnError = 'unclosed tag'; // повторим попытку на след. write
return;
};
isTagStart = false;
isTagEnd = true;
// проверяем что тег должен быть закрыт тот-же что и открывался
if (!parseStackNodes.length) {
returnError = 'close tag, requires open tag';
isParseStop = true; // дальнейший разбор невозможен
return;
};
nodeName = parseStackNodes.pop();
iQ = i + 2 + nodeName.length;
if (nodeName !== xml.substring(i + 2, iQ)) {
returnError = 'close tag, not equal to the open tag';
isParseStop = true; // дальнейший разбор невозможен
return;
};
// проверим что в закрываюшем теге нет лишнего
for(; iQ < indexEndNode; iQ++) {
var wNext = xml.charCodeAt(iQ);
if (wNext === 32 || wNext === 9 || wNext === 10 || wNext === 11 || wNext === 12 || wNext === 13) { // \f\n\r\t\v
continue;
};
returnError = 'close tag, unallowable char';
isParseStop = true; // дальнейший разбор невозможен
return;
};
indexStartXML = indexEndNode + 1;
} else {
var indexEndNode = parseNode(i);
if (indexEndNode === -1) { // error ...> // не нашел знак закрытия тега
returnError = returnError || 'unclosed tag'; // повторим попытку на след. write
return;
};
isTagStart = true;
isTagEnd = xml.charCodeAt(indexEndNode - 1) === 47;
nodeName = nodeParseName;
if (!isTagEnd) {
parseStackNodes.push(nodeName);
};
indexStartXML = indexEndNode + 1;
};
if (isNamespace) {
if (stopEmit) { // потомки неизвестного пространства имен
if (isTagEnd) {
if (!isTagStart) {
if (--stopIndexNS === 0) {
nsmatrix = parseStackMatrixNS.pop();
};
};
} else {
stopIndexNS += 1;
};
continue;
};
// добавляем в parseStackMatrixNS только если !isTagEnd, иначе сохраняем контекст пространств в переменной
_nsmatrix = nsmatrix;
if (!isTagEnd) {
parseStackMatrixNS.push(nsmatrix);
};
if (isTagStart && nodeParseHasNS) { // есть подозрение на xmlns // && (nodeParseAttrResult === null)
upNSMATRIX();
};
iD = nodeName.indexOf(':');
if (iD !== -1) {
xmlns = nsmatrix[nodeName.substring(0, iD)];
nodeName = nodeName.substr(iD + 1);
} else {
xmlns = nsmatrix.xmlns;
};
if (!xmlns) {
// элемент неизвестного пространства имен
if (isTagEnd) {
nsmatrix = _nsmatrix; // так как тут всегда isTagStart
} else {
stopIndexNS = 1; // первый элемент для которого не определено пространство имен
};
continue;
};
nodeName = xmlns + ':' + nodeName;
};
stringNodePosStart = i; // stringNodePosStart, stringNodePosEnd - для ручного разбора getStringNode()
stringNodePosEnd = indexStartXML;
if (isTagStart) {
onStartNode(nodeName, getAttrs, isTagEnd, getStringNode);
if (isParseStop) {
return;
};
};
if (isTagEnd) {
onEndNode(nodeName, isTagStart, getStringNode);
if (isParseStop) {
return;
};
if (isNamespace) {
if (isTagStart) {
nsmatrix = _nsmatrix;
} else {
nsmatrix = parseStackMatrixNS.pop();
};
};
};
};
};
var staxStream, staxStateisTagStart, staxStateisTagEnd, staxStatenodeName, staxStateeventType, staxStatetext, staxStatedepth;
function staxInit(_xml) {
init = true;
reset();
staxCleanState();
var xmls = [_xml];
staxStream = {read: function(){return xmls.pop();}};
xml = staxStream.read();
}
function staxCleanState() {
staxStateisTagStart = false;
staxStateisTagEnd = false;
staxStatenodeName = null;
staxStateeventType = null;
staxStatetext = null;
staxStatedepth = 0;
returnError = null; // сброс ошибки неудачного разбора
}
function staxHasNext() {
return !isParseStop;
}
function staxGetEventType() {
return staxStateeventType;
}
function staxGetName() {
return staxStatenodeName;
}
function staxGetText() {
return staxStatetext;
}
function staxGetDepth() {
return staxStatedepth;
}
function staxIsEmptyNode() {
return staxStateisTagStart && staxStateisTagEnd;
}
function staxGetError() {
return returnError;
}
function staxParseWithEvents(xml) {
this.staxInit(xml);
while (staxHasNext()) {
var eventType = staxNext();
switch (eventType) {
case EasySAXEvent.START_ELEMENT:
onStartNode(staxGetName(), getAttrs, staxStateisTagEnd, getStringNode);
break;
case EasySAXEvent.CHARACTERS:
onTextNode(staxGetText());
break;
case EasySAXEvent.END_ELEMENT:
onEndNode(staxGetName(), staxStateisTagStart, getStringNode);
break;
case EasySAXEvent.CDATA:
onCDATA(staxGetText());
break;
case EasySAXEvent.Comment:
if (is_onComment) {
onComment(staxGetText());
}
break;
case EasySAXEvent.Attention:
if (is_onAttention) {
onAttention(staxGetText());
}
break;
case EasySAXEvent.Question:
if (is_onQuestion) {
onQuestion(staxGetText());
}
break;
}
}
this.staxEnd();
}
function staxNext() {
// разбор идет по элементам (тег, текст cdata, ...).
// элемент должен быть целиком в памяти
// var _nsmatrix;
// var isTagStart = false;
// var isTagEnd = false;
// //var nodeBody;
// var stopEmit; // используется при разборе "namespace" . если встретился неизвестное пространство то события не генерируются
// var nodeName;
// var iD;
var iQ;
var w;
var i; // number
if (staxStateisTagEnd) {
if (staxStateeventType === EasySAXEvent.START_ELEMENT) {
staxStateeventType = EasySAXEvent.END_ELEMENT;
return staxStateeventType;
}
staxStatedepth--;
};
staxStateeventType = EasySAXEvent.Unknown;
// поиск начала тега
if (xml.charCodeAt(indexStartXML) === 60) { // "<"
i = indexStartXML;
} else {
i = xml.indexOf('<', indexStartXML);
};
if (i === -1) { // узел не найден. повторим попытку на след. write
// --- нужно подумать как обрабатывать начало файла ---
// if (indexStartXML === 0) { // разбор еше не начат. возможно это начало файла. мусор до первого тега игнор
// returnError = 'missing first tag';
// return;
// };
if (indexStartXML > 0) {
xml = xml.substring(indexStartXML);
indexStartXML = 0;
};
var chunk = staxStream.read();
if(chunk) {
xml = xml + chunk;
// поиск начала тега
if (xml.charCodeAt(indexStartXML) === 60) { // "<"
i = indexStartXML;
} else {
i = xml.indexOf('<', indexStartXML);
};
}
if (i === -1) {
if (parseStackNodes.length) {
returnError = 'unexpected end parse';
};
if (returnError) {
onError(returnError);
returnError = '';
};
isParseStop = true;
return staxStateeventType;
}
};
if (indexStartXML !== i) { // все что до тега это текст
var text = xml.substring(indexStartXML, i);
indexStartXML = i; // до этой позиции разбор завершен
staxStateeventType = EasySAXEvent.CHARACTERS;
staxStatetext = isAutoEntity ? entityDecode(text) : text;
return staxStateeventType;
};
// ELEMENT
// ---------------------------------------------
w = xml.charCodeAt(i + 1);
if (w === 33) { // 33 == "!"
var wNext = xml.charCodeAt(i + 2);
// CDATA
// ---------------------------------------------
if (wNext === 91 && xml.substr(i + 3, 6) === 'CDATA[') { // 91 == "["
var indexStartCDATA = i + 9;
var indexEndCDATA = xml.indexOf(']]>', indexStartCDATA);
if (indexEndCDATA === -1) {
returnError = 'cdata, not found ...]]>'; // не закрыт CDATA. повторим попытку на след. write
isParseStop = true;
return staxStateeventType;
};
indexStartXML = indexEndCDATA + 3;
staxStateeventType = EasySAXEvent.CDATA;
staxStatetext = xml.substring(indexStartCDATA, indexEndCDATA);
return staxStateeventType;
};
// COMMENT
// ---------------------------------------------
if (wNext === 45 && xml.charCodeAt(i + 3) === 45) { // 45 == "-"
var indexStartComment = i + 4;
var indexEndComment = xml.indexOf('-->', indexStartComment);
if (indexEndComment === -1) {
returnError = 'expected -->'; // не закрыт комментарий. повторим попытку на след. write
isParseStop = true;
return staxStateeventType;
};
indexStartXML = indexEndComment + 3;
staxStateeventType = EasySAXEvent.Comment;
staxStatetext = xml.substring(indexStartComment, indexEndComment);
return staxStateeventType;
};
// ATTENTION
// ---------------------------------------------
{
var indexStartAttention = i + 1;
var indexEndAttention = xml.indexOf('>', indexStartAttention);
if (indexEndAttention === -1) {
returnError = 'expected attention ...>'; // повторим попытку на след. write
isParseStop = true;
return staxStateeventType;
};
indexStartXML = indexEndAttention + 1;
staxStateeventType = EasySAXEvent.Attention;
staxStatetext = xml.substring(i, indexStartXML);
return staxStateeventType;
};
return staxStateeventType;
};
// QUESTION
// ---------------------------------------------
if (w === 63) { // "?"
var indexEndQuestion = xml.indexOf('?>', i);
if (indexEndQuestion === -1) { // error
returnError = 'expected question ...?>'; // повторим попытку на след. write
isParseStop = true;
return staxStateeventType;
};
indexStartXML = indexEndQuestion + 2;
staxStateeventType = EasySAXEvent.Question;
staxStatetext = xml.substring(i, indexStartXML);
return staxStateeventType;
};
// NODE ELEMENT
// ---------------------------------------------
if (w === 47) { // </...
var indexEndNode = xml.indexOf('>', i + 1);
if (indexEndNode === -1) { // error ...> // не нашел знак закрытия тега
returnError = 'unclosed tag'; // повторим попытку на след. write
isParseStop = true;
return staxStateeventType;
};
staxStateisTagStart = false;
staxStateisTagEnd = true;
// проверяем что тег должен быть закрыт тот-же что и открывался
if (!parseStackNodes.length) {
returnError = 'close tag, requires open tag';
isParseStop = true; // дальнейший разбор невозможен
return staxStateeventType;
};
staxStatenodeName = parseStackNodes.pop();
iQ = i + 2 + staxStatenodeName.length;
if (staxStatenodeName !== xml.substring(i + 2, iQ)) {
returnError = 'close tag, not equal to the open tag';
isParseStop = true; // дальнейший разбор невозможен
return staxStateeventType;
};
// проверим что в закрываюшем теге нет лишнего
for(; iQ < indexEndNode; iQ++) {
var wNext = xml.charCodeAt(iQ);
if (wNext === 32 || wNext === 9 || wNext === 10 || wNext === 11 || wNext === 12 || wNext === 13) { // \f\n\r\t\v
continue;
};
returnError = 'close tag, unallowable char';
isParseStop = true; // дальнейший разбор невозможен
return staxStateeventType;
};
indexStartXML = indexEndNode + 1;
} else {
var indexEndNode = parseNode(i);
if (indexEndNode === -1) { // error ...> // не нашел знак закрытия тега
returnError = returnError || 'unclosed tag'; // повторим попытку на след. write
isParseStop = true;
return staxStateeventType;
};
staxStateisTagStart = true;
staxStateisTagEnd = xml.charCodeAt(indexEndNode - 1) === 47;
staxStatenodeName = nodeParseName;
if (!staxStateisTagEnd) {
parseStackNodes.push(staxStatenodeName);
};
indexStartXML = indexEndNode + 1;
};
if (staxStateisTagStart) {
staxStatedepth++;
staxStateeventType = EasySAXEvent.START_ELEMENT;
return staxStateeventType;
};
if (staxStateisTagEnd) {
staxStateeventType = EasySAXEvent.END_ELEMENT;
return staxStateeventType;
};
}
this.staxInit = staxInit;
this.staxHasNext = staxHasNext;
this.staxNext = staxNext;
this.staxGetEventType = staxGetEventType;
this.staxGetName = staxGetName;
this.staxGetAttrs = getAttrs;
this.staxGetText = staxGetText;
this.staxGetDepth = staxGetDepth;
this.staxIsEmptyNode = staxIsEmptyNode;
this.staxGetError = staxGetError;
this.staxEnd = this.end;
};
function StaxParser(xml, rels, context) {
this.xml = xml;
this.index = 0;
this.length = xml.length;
this.rels = rels;
this.context = context;
this.isTagStart = null;
this.isInAttr = false;
this.isTagEnd = null;
this.eventType = null;
this.name = null;
this.text = null;
this.value = null;
this.stop = false;
this.depth = 0;
}
StaxParser.prototype.hasNext = function() {
return !this.stop;
};
StaxParser.prototype.next = function() {
if (this.isInAttr) {
this.SkipAttributes();
}
if (this.isTagEnd) {
if (this.eventType === EasySAXEvent.START_ELEMENT) {
this.eventType = EasySAXEvent.END_ELEMENT;
return this.eventType;
}
this.depth--;
}
this.isInAttr = false;
this.eventType = EasySAXEvent.Unknown;
this.isTagStart = this.isTagEnd = this.name = this.text = this.value = null;
var xml = this.xml;
var i = this.index;
if (xml.charCodeAt(i) !== 60) { // '<'
i = xml.indexOf('<', i);
if (i === -1) {
this.stop = true;
return;
}
this.eventType = EasySAXEvent.CHARACTERS;
this.text = xml.substring(this.index, i);
this.index = i;
return this.eventType;
}
// ELEMENT
// ---------------------------------------------
var w = xml.charCodeAt(i + 1);
if (w === 33) { // 33 == "!"
if (i + 3 < this.length && xml.charCodeAt(i + 2) === 45 && xml.charCodeAt(i + 3) === 45) { // COMMENT
this.index = xml.indexOf('-->', i) + 3;
} else { // CDATA
this.index = xml.indexOf(']]>', i) + 3;
}
if (this.index === 2) { // -1 + 3 = 2
this.stop = true;
}
this.eventType = EasySAXEvent.Unknown;
return this.eventType;
}
// QUESTION
// ---------------------------------------------
if (w === 63) { // "?"
this.index = xml.indexOf('>', i);
return this.eventType;
}
// NODE ELEMENT
// ---------------------------------------------
var indexEndNode;
if (w !== 47) { // </...
indexEndNode = this.parseNode(i);
if (indexEndNode === -1) { // error ...> // не нашел знак закрытия тега
this.stop = true;
return this.eventType;
}
this.isTagStart = true;
this.isInAttr = true;
this.isTagEnd = false;
// this.isTagEnd = this.xml.charCodeAt(indexEndNode - 1) === 47;
this.eventType = EasySAXEvent.START_ELEMENT;
this.depth++;
this.index = indexEndNode;
} else {
//todo close tag name not used. don't parse for performance reason
indexEndNode = this.xml.indexOf('>', i + 1);
if (indexEndNode === -1) { // error ...> // не нашел знак закрытия тега
this.stop = true;
return this.eventType;
}
this.isTagStart = false;
this.isTagEnd = true;
this.eventType = EasySAXEvent.END_ELEMENT;
this.index = indexEndNode + 1;
}
return this.eventType;
};
StaxParser.prototype.parseNode = function(indexStart) {
var xml = this.xml;
var len = this.length;
var ixNameStart = indexStart + 1;
var i = ixNameStart;
var w;
while (i < len) {
w = xml.charCodeAt(i);
if ((w | 32) > 96 && (w | 32) < 123 || // letters
(w > 47 && w < 58) || // digits
w === 45 || w === 46 || w === 58 || w === 95) { // - . :_
++i;
continue;
}
// whitespace (space, tab, LF, VT, FF, CR)
if (w === 32 || (w >= 9 && w <= 13)) {
this.name = xml.substring(ixNameStart, i);
return i;
}
// tag end or self-closing slash
if (w === 62 /* > */ || w === 47 /* / */) {
this.name = xml.substring(ixNameStart, i);
return i;
}
// invalid char
return -1;
}
return -1;
};
StaxParser.prototype.MoveToNextAttribute = function() {
var xml = this.xml;
var len = this.length;
var i = this.index;
while (i < len) {
var w = xml.charCodeAt(i);
if (w === 61 /* '=' */ && i + 1 < len) {
// Extract attribute name (likely clean, trim only if needed)
var nameStart = this.index;
var nameEnd = i;
var rawName = xml.substring(nameStart, nameEnd);
// Fast quote detection
var quoteChar = xml.charCodeAt(i + 1);
var textStart = i + 2;
if (quoteChar === 34) { // '"'
i = xml.indexOf('"', textStart);
} else if (quoteChar === 39) { // "'"
i = xml.indexOf("'", textStart);
} else {
// Fallback for other quotes
i = xml.indexOf(xml.charAt(i + 1), textStart);
}
if (i !== -1) {
// Only trim if name has leading/trailing spaces
if (rawName.charCodeAt(0) === 32 || rawName.charCodeAt(nameEnd - nameStart - 1) === 32) {
this.name = rawName.trim();
} else {
this.name = rawName;
}
this.text = xml.substring(textStart, i);
this.index = i + 1;
return true;
} else {
break;
}
}
// whitespace (space, tab, LF, VT, FF, CR)
if (w === 32 || (w >= 9 && w <= 13)) {
++i;
continue;
}
if (w === 62 /* ">" */) {
this.index = i + 1;
this.isInAttr = false;
return false;
}
if (w === 47 /* "/" */ && i + 1 < len && xml.charCodeAt(i + 1) === 62) {
this.index = i + 2;
this.isInAttr = false;
this.isTagEnd = true;
return false;
}
++i;
}
this.stop = true;
this.index = i;
this.isInAttr = false;
return false;
};
StaxParser.prototype.GetAttributes = function() {
let attributes = {};
while (this.MoveToNextAttribute()) {
attributes[this.GetName()] = this.GetValue();
}
return attributes;
};
StaxParser.prototype.SkipAttributes = function() {
var xml = this.xml;
var i = xml.indexOf('>', this.index);
if (i === -1) {
this.stop = true;
return;
}
this.isTagEnd = xml.charCodeAt(i - 1) === 47; // '/'
this.isInAttr = false;
this.index = i + 1;
};
StaxParser.prototype.Read = function() {
var hasNext = this.hasNext();
this.next();
return hasNext;
};
StaxParser.prototype.ReadNextNode = function() {
var type = EasySAXEvent.Unknown;
while (EasySAXEvent.START_ELEMENT !== type && this.hasNext()) {
type = this.next();
}
return EasySAXEvent.START_ELEMENT === type;
};
StaxParser.prototype.ReadNextSiblingNode = function(depth) {
var targetDepth = depth + 1;
var type;
while (this.hasNext()) {
type = this.next();
var curDepth = this.depth;
if (curDepth < depth) {
break;
}
if (type === EasySAXEvent.START_ELEMENT && curDepth === targetDepth) {
return true;
}
if (type === EasySAXEvent.END_ELEMENT && curDepth === depth) {
return false;
}
}
return false;
};
StaxParser.prototype.ReadTillEnd = function (opt_depth) {
var depth = opt_depth;
if (!depth) {
depth = this.depth;
}
var type = EasySAXEvent.Unknown;
while (this.hasNext()) {
type = this.next();
var curDepth = this.GetDepth();
if (curDepth < depth) {
break;
}
if (EasySAXEvent.END_ELEMENT === type && curDepth === depth)
break;
}
return true;
};
StaxParser.prototype.IsEmptyNode = function () {
return this.isTagStart && this.isTagEnd;
};
StaxParser.prototype.GetDepth = function() {
return this.depth;
};
StaxParser.prototype.GetName = function () {
return this.name;
// return this.ConvertToString(this.xml, this.nameStart, this.nameEnd);
};
StaxParser.prototype.GetNameNoNS = function () {
return this.GetNameFromNodeName(this.GetName());
};
StaxParser.prototype.GetValue = function () {
return this.text;
// return this.ConvertToString(this.xml, this.textStart, this.textEnd);
};
StaxParser.prototype.GetBool = function (val) {
return "1" === val || "true" === val || "t" === val || "on" === val;
};
StaxParser.prototype.GetInt = function (val, def, radix) {
var num = parseInt(val, radix);
return !isNaN(num) ? num : def;
};
StaxParser.prototype.GetUInt = function (val, def, radix) {
var num = parseInt(val, radix);
return !isNaN(num) && num >= 0 ? num : def;
};
StaxParser.prototype.GetDouble = function (val, def) {
var num = parseFloat(val);
return !isNaN(num) ? num : def;
};
StaxParser.prototype.GetDoubleOrNaN = function (val, def) {
if(val === "NaN") {
return NaN;
}
if (val === "INF") {
return Infinity;
}
return this.GetDouble(val, def);
};
StaxParser.prototype.GetValueBool = function () {
return this.GetBool(this.GetValue());
};
StaxParser.prototype.GetValueByte = function (def, radix) {
return this.GetValueUInt(def, radix);
};
StaxParser.prototype.GetValueSByte = function (def, radix) {
return this.GetValueInt(def, radix);
};
StaxParser.prototype.GetValueInt = function (def, radix) {
return this.GetInt(this.GetValue(), def, radix);
};
StaxParser.prototype.GetValueUInt = function (def, radix) {
return this.GetUInt(this.GetValue(), def, radix);
};
StaxParser.prototype.GetValueInt64 = function (def, radix) {
return this.GetValueInt(def, radix);
};
StaxParser.prototype.GetValueUInt64 = function (def, radix) {
return this.GetValueUInt(def, radix);
};
StaxParser.prototype.GetValueDouble = function (def) {
return this.GetDouble(this.GetValue(), def);
};
StaxParser.prototype.GetValueDoubleOrNaN = function (def) {
return this.GetDoubleOrNaN(this.GetValue(), def);
};
StaxParser.prototype.GetValueDecodeXml = function () {
return this.DecodeXml(this.text);
};
StaxParser.prototype.GetValueDecodeXmlExt = function () {
return this.GetValueDecodeXml();
};
StaxParser.prototype.DecodeXml = function (text) {
// Detect &amp; and _xHHHH_ patterns
const len = text.length;
let firstSpecial = -1;
let i = 0;
for (i = 0; i < len; ++i) {
const c = text.charCodeAt(i);
if (c === 38 /* & */ || (c === 95 /* _ */ && i + 1 < len && text.charCodeAt(i + 1) === 120 /* x */)) {
firstSpecial = i;
break;
}
}
if (firstSpecial === -1) {
return text;
}
const result = [];
let lastCopied = 0;
for (i = firstSpecial; i < len; ++i) {
const ch = text.charCodeAt(i);
let entityLen = 0;
let decoded = null;
if (ch === 38) { // '&'
const nextChar = i + 1 < len ? text.charCodeAt(i + 1) : 0;
// &lt; (4 chars)
if (nextChar === 108 && i + 3 < len && // 'l'
text.charCodeAt(i + 2) === 116 && // 't'
text.charCodeAt(i + 3) === 59) { // ';'
decoded = '<';
entityLen = 4;
}
// &gt; (4 chars)
else if (nextChar === 103 && i + 3 < len && // 'g'
text.charCodeAt(i + 2) === 116 && // 't'
text.charCodeAt(i + 3) === 59) { // ';'
decoded = '>';
entityLen = 4;
}
// &amp; (5 chars)
else if (nextChar === 97 && i + 4 < len && // 'a'
text.charCodeAt(i + 2) === 109 && // 'm'
text.charCodeAt(i + 3) === 112 && // 'p'
text.charCodeAt(i + 4) === 59) { // ';'
decoded = '&';
entityLen = 5;
}
// &quot; or &apos; (6 chars)
else if (i + 5 < len) {
if (nextChar === 113 && // 'q'
text.charCodeAt(i + 2) === 117 && // 'u'
text.charCodeAt(i + 3) === 111 && // 'o'
text.charCodeAt(i + 4) === 116 && // 't'
text.charCodeAt(i + 5) === 59) { // ';'
decoded = '"';
entityLen = 6;
} else if (nextChar === 97 && // 'a'
text.charCodeAt(i + 2) === 112 && // 'p'
text.charCodeAt(i + 3) === 111 && // 'o'
text.charCodeAt(i + 4) === 115 && // 's'
text.charCodeAt(i + 5) === 59) { // ';'
decoded = "'";
entityLen = 6;
}
}
} else if (ch === 95 && i + 6 < len && // '_'
text.charCodeAt(i + 1) === 120 && // 'x'
text.charCodeAt(i + 6) === 95) { // '_'
// Inline hex parsing for _xHHHH_ pattern
let code = 0;
let isValidHex = true;
for (let j = i + 2; j < i + 6; ++j) {
const hexChar = text.charCodeAt(j);
code *= 16;
if (hexChar >= 48 && hexChar <= 57) { // '0'-'9'
code += hexChar - 48;
} else if (hexChar >= 65 && hexChar <= 70) { // 'A'-'F'
code += hexChar - 55;
} else if (hexChar >= 97 && hexChar <= 102) { // 'a'-'f'
code += hexChar - 87;
} else {
isValidHex = false;
break;
}
}
if (isValidHex) {
decoded = code === 0x005F ? '_' : stringFromCharCode(code);
entityLen = 7;
}
}
if (decoded !== null) {
// Copy text before entity
if (i > lastCopied) {
result.push(text.substring(lastCopied, i));
}
result.push(decoded);
const after = i + entityLen;
i = after - 1; // loop will ++i next iteration
lastCopied = after;
}
}
// Copy remaining text
if (lastCopied < len) {
result.push(text.substring(lastCopied, len));
}
return result.join('');
};
StaxParser.prototype.GetText = function () {
var text = "";
var depth = this.depth;
var type = EasySAXEvent.Unknown;
while (this.hasNext()) {
type = this.next();
var curDepth = this.GetDepth();
if (curDepth < depth) {
break;
}
if (EasySAXEvent.END_ELEMENT === type && curDepth === depth)
break;
if (EasySAXEvent.CHARACTERS === type) {
text += this.GetValue();
}
}
return text;
};
StaxParser.prototype.GetTextDecodeXml = function () {
return this.DecodeXml(this.GetText());
};
StaxParser.prototype.GetTextBool = function () {
return this.GetBool(this.GetText());
};
StaxParser.prototype.GetTextByte = function (def, radix) {
return this.GetTextInt(def, radix);
};
StaxParser.prototype.GetTextSByte = function (def, radix) {
return this.GetTextUInt(def, radix);
};
StaxParser.prototype.GetTextInt = function (def, radix) {
return this.GetInt(this.GetText(), def, radix);
};
StaxParser.prototype.GetTextUInt = function (def, radix) {
return this.GetUInt(this.GetText(), def, radix);
};
StaxParser.prototype.GetTextInt64 = function (def, radix) {
return this.GetTextInt(def, radix);
};
StaxParser.prototype.GetTextUInt64 = function (def, radix) {
return this.GetTextUInt(def, radix);
};
StaxParser.prototype.GetTextDouble = function (def) {
return this.GetDouble(this.GetText(), def);
};
StaxParser.prototype.ConvertToString = function(xml, start, end) {
return xml.substring(start, end);
// return "";
// return name ? String.prototype.fromUtf8(buffer, start, end - start + 1) : "";
// return String.prototype.fromUtf8(buffer, start, end - start + 1);
// return name ? decoder.decode(name) : "";
// return name ? new TextDecoder("utf-8").decode(name) : "";
// return String.fromCharCode.apply(null, name);
};
StaxParser.prototype.GetNSFromNodeName = function(name) {
var index = name.indexOf(':');
if (-1 !== index) {
return name.substring(0, index + 1);
}
return "";
};
StaxParser.prototype.GetNameFromNodeName = function(name) {
var index = name.indexOf(':');
if (-1 !== index) {
return name.substring(index + 1);
}
return name;
};
StaxParser.prototype.GetEventType = function() {
return this.eventType;
};
StaxParser.prototype.GetContext = function() {
return this.context;
};
StaxParser.prototype.GetOformContext = function() {
if (!this.context)
return null;
return this.context.getOformContext();
};
StaxParser.prototype.getState = function() {
return {
depth: this.depth,
eventType: this.eventType,
index: this.index,
isInAttr: this.isInAttr,
isTagEnd: this.isTagEnd,
isTagStart: this.isTagStart,
length: this.length,
name: this.name,
stop: this.stop,
text: this.text,
value: this.value
};
};
StaxParser.prototype.setState = function(state) {
this.depth = state.depth;
this.eventType = state.eventType;
this.index = state.index;
this.isInAttr = state.isInAttr;
this.isTagEnd = state.isTagEnd;
this.isTagStart = state.isTagStart;
this.length = state.length;
this.name = state.name;
this.stop = state.stop;
this.text = state.text;
this.value = state.value;
};
StaxParser.prototype.readXmlArray = function(childName, func) {
if (this.IsEmptyNode()) {
return;
}
var depth = this.GetDepth();
var indexChild = 0;
while (this.ReadNextSiblingNode(depth)) {
if (childName === this.GetNameNoNS()) {
func(indexChild);
indexChild++;
}
}
};
StaxParser.prototype.AddConnectedObject = function(object) {
this.context.addConnectorsPr(object);
};
function XmlParserContext(){
//common
this.zip = null;
this.DrawingDocument = null;
this.imageMap = {};
this.curChart = null;
this.smartarts = [];
//docx
this.commentDataById = {};
this.oReadResult = AscCommonWord.DocReadResult && new AscCommonWord.DocReadResult();
this.maxZIndex = 0;
this.oformContext = null;
this.sdtPrWithFieldPath = [];
this.fieldMasterMap = {};
this.fieldMastersWithUserMasterPath = [];
this.userMasterMap = {};
this.fieldGroupsWithFieldMasterPath = [];
this.fieldWithFieldMastersPath = [];
this.userWithUserMastersPath = [];
//xlsx
this.sharedStrings = [];
this.row = null;
this.cellValue = null;
this.cellBase = null;
this.drawingId = null;
//pptx
this.layoutsMap = {};
this.notesMastersMap = {};
this.TablesMap = {};
this.TableStylesMap = {};
this.ConnectorsPr = [];
}
XmlParserContext.prototype.initFromWS = function(ws) {
this.ws = ws;
this.row = new AscCommonExcel.Row(ws);
this.cellValue = new AscCommonExcel.CT_Value();
this.cellBase = new AscCommon.CellBase(0,0);
this.drawingId = null;
};
XmlParserContext.prototype.clearSlideRelations = function() {
this.layoutsMap = {};
this.notesMastersMap = {};
};
XmlParserContext.prototype.clearFieldRelations = function() {
this.sdtPrWithFieldPath = [];
this.fieldMasterMap = {};
};
XmlParserContext.prototype.addSdtPrRelation = function(oSdtPr, sTarget) {
this.sdtPrWithFieldPath.push({sdtPr: oSdtPr, target: sTarget});
};
XmlParserContext.prototype.addFieldGroupRelation = function(oFieldGroup, sTarget) {
this.fieldGroupsWithFieldMasterPath.push({fieldGroup: oFieldGroup, target: sTarget});
};
XmlParserContext.prototype.addFieldMasterPath = function(oFieldMaster, sTarget) {
this.fieldMasterMap[sTarget] = oFieldMaster;
};
XmlParserContext.prototype.addFieldWithFieldMaterPath = function(oField, sTarget) {
this.fieldWithFieldMastersPath.push({field: oField, target: sTarget});
};
XmlParserContext.prototype.addUserWithUserMastersPath = function(oUser, sTarget) {
this.userWithUserMastersPath.push({user: oUser, target: sTarget});
};
XmlParserContext.prototype.assignFieldsToFieldMasters = function() {
for(let nFld = 0; nFld < this.fieldWithFieldMastersPath.length; ++nFld) {
let oPair = this.fieldWithFieldMastersPath[nFld];
let sTarget = oPair.target;
for(let sKey in this.fieldMasterMap) {
if(this.fieldMasterMap.hasOwnProperty(sKey)) {
if(sKey.indexOf(sTarget) > -1) {
let oFieldMaster = this.fieldMasterMap[sKey];
if(oFieldMaster) {
oFieldMaster.setLogicField(oPair.field);
break;
}
}
}
}
}
};
XmlParserContext.prototype.assignFieldsToSdt = function() {
for(let nSdt = 0; nSdt < this.sdtPrWithFieldPath.length; ++nSdt) {
let oPair = this.sdtPrWithFieldPath[nSdt];
let oFieldMaster = this.fieldMasterMap[oPair.target];
if(oFieldMaster) {
oPair.sdtPr.OForm = oFieldMaster;
}
}
};
XmlParserContext.prototype.addFieldMasterRelation = function(oFieldMaster, sTarget) {
this.fieldMastersWithUserMasterPath.push({fieldMaster: oFieldMaster, target: sTarget});
};
XmlParserContext.prototype.addUserMasterPath = function(oUserMaster, sTarget) {
this.userMasterMap[sTarget] = oUserMaster;
};
XmlParserContext.prototype.assignFieldsToFieldGroup = function() {
for(let nFldGrp = 0; nFldGrp < this.fieldGroupsWithFieldMasterPath.length; ++nFldGrp) {
let oPair = this.fieldGroupsWithFieldMasterPath[nFldGrp];
let sTarget = oPair.target;
for(let sKey in this.fieldMasterMap) {
if(this.fieldMasterMap.hasOwnProperty(sKey)) {
if(sKey.indexOf(sTarget) > -1) {
let oFieldMaster = this.fieldMasterMap[sKey];
if(oFieldMaster) {
oPair.fieldGroup.addField(oFieldMaster);
break;
}
}
}
}
}
};
XmlParserContext.prototype.assignUsersToFieldMasters = function() {
for(let nPair = 0; nPair < this.fieldMastersWithUserMasterPath.length; ++nPair) {
let oPair = this.fieldMastersWithUserMasterPath[nPair];
let oUserMasterMaster = this.userMasterMap[oPair.target];
if(oUserMasterMaster) {
oPair.fieldMaster.addUser(oUserMasterMaster);
}
}
};
XmlParserContext.prototype.assignUsersToUserMasters = function() {
for(let nPair = 0; nPair < this.userWithUserMastersPath.length; ++nPair) {
let oPair = this.userWithUserMastersPath[nPair];
let sTarget = oPair.target;
for(let sKey in this.userMasterMap) {
if(this.userMasterMap.hasOwnProperty(sKey)) {
if(sKey.indexOf(sTarget) > -1) {
let oUserMaster = this.userMasterMap[sKey];
if(oUserMaster) {
oUserMaster.setUserId(oPair.user.Id);
break;
}
}
}
}
}
};
XmlParserContext.prototype.assignFormLinks = function() {
this.assignFieldsToSdt();
this.assignUsersToFieldMasters();
this.assignFieldsToFieldGroup();
this.assignFieldsToFieldMasters();
this.assignUsersToUserMasters();
this.sdtPrWithFieldPath = [];
this.fieldMasterMap = {};
this.fieldMastersWithUserMasterPath = [];
this.userMasterMap = {};
this.fieldGroupsWithFieldMasterPath = [];
this.fieldWithFieldMastersPath = [];
this.userWithUserMastersPath = [];
};
XmlParserContext.prototype.getOformContext = function() {
return this.oformContext;
};
XmlParserContext.prototype.setOformContext = function(context) {
this.oformContext = context;
};
XmlParserContext.prototype.addTableStyle = function(sGuid, oStyle) {
this.TableStylesMap[sGuid] = oStyle;
};
XmlParserContext.prototype.getTableStyle = function(sGuid) {
return this.TableStylesMap[sGuid] || null;
};
XmlParserContext.prototype.addConnectorsPr = function(oPr) {
for(let nIdx = 0; nIdx < this.ConnectorsPr.length; ++nIdx) {
if(oPr === this.ConnectorsPr[nIdx]) {
return;
}
}
this.ConnectorsPr.push(oPr);
};
XmlParserContext.prototype.assignConnectors = function(aSpTree) {
for(let nIdx = 0; nIdx < this.ConnectorsPr.length; ++nIdx) {
this.ConnectorsPr[nIdx].assignConnectors(aSpTree);
}
this.ConnectorsPr.length = 0;
};
XmlParserContext.prototype.checkZIndex = function(nZIndex) {
if(AscFormat.isRealNumber(nZIndex)) {
this.maxZIndex = Math.max(this.maxZIndex, nZIndex);
}
};
XmlParserContext.prototype.loadDataLinks = function() {
let _cur_ind = 0;
let oImageMap = {};
for (let path in this.imageMap) {
if (this.imageMap.hasOwnProperty(path)) {
oImageMap[_cur_ind++] = path;
let data = this.zip.getFile(path);
if (data) {
let blobUrl = AscCommon.g_oDocumentBlobUrls.getBlobUrl(path, this.zip);
AscCommon.g_oDocumentUrls.addImageUrl(path, blobUrl);
this.imageMap[path].forEach(function(blipFill) {
AscCommon.pptx_content_loader.Reader.initAfterBlipFill(path, blipFill);
});
}
}
}
return oImageMap;
};
XmlParserContext.prototype.GenerateSmartArts = function() {
while (this.smartarts.length) {
const smartart = this.smartarts.pop();
smartart.generateDrawingPart();
}
};
XmlParserContext.prototype.ClearSmartArts = function() {
this.smartarts.length = 0;
};
function XmlWriterContext(editorId){
//common
this.editorId = editorId;
this.zip = null;
this.part = null;
this.imageMap = {};
this.currentPartImageMap = {};
this.dataMap = {};
this.currentPartDataMap = {};
this.m_lObjectIdVML = 1025;
this.oUriMap = {};
this.objectId = 1;
this.groupIndex = 0;
this.flag = 0;
switch (editorId) {
case AscCommon.c_oEditorId.Word: {
this.docType = AscFormat.XMLWRITER_DOC_TYPE_DOCX;
break;
}
case AscCommon.c_oEditorId.Spreadsheet: {
this.docType = AscFormat.XMLWRITER_DOC_TYPE_XLSX;
break;
}
case AscCommon.c_oEditorId.Presentation: {
this.docType = AscFormat.XMLWRITER_DOC_TYPE_PPTX;
break;
}
}
//docx
this.document = null;
this.oNumIdMap = {};
this.commentIdIndex = 1;
this.paraIdIndex = 1;
this.commentDataById = {};
this.docSaveParams = null;
this.fieldMastersPartMap = {};
this.userMasterPartMap = {};
//xlsx
this.wb = null;
this.sheetIds = [];
this.sharedStrings = null;
this.isCopyPaste = null;
this.stylesForWrite = AscCommonExcel.StylesForWrite && new AscCommonExcel.StylesForWrite(); //no StylesForWrite in vsdx now
this.oSharedStrings = {index: 0, strings: {}};
this.oleDrawings = [];
this.signatureDrawings = [];
//pptx
this.presentation = null;
this.sldMasterIdLst = [];
this.sldLayoutIdLst = [];
this.sldLayoutsCount = 0;
this.notesMasterIdLst = [];
this.handoutMasterIdLst = [];
this.sldIdLst = [];
this.tableStylesIdToGuid = {};
}
XmlWriterContext.prototype.initFromWS = function(ws) {
this.ws = ws;
this.row = new AscCommonExcel.Row(ws);
this.cellValue = new AscCommonExcel.CT_Value();
this.cellBase = new AscCommon.CellBase(0,0);
this.drawingId = null;
};
XmlWriterContext.prototype.addSlideRel = function(sRel) {
this.sldIdLst.push(sRel);
};
XmlWriterContext.prototype.addSlideLayoutRel = function(sRel) {
this.sldLayoutIdLst.push(sRel);
};
XmlWriterContext.prototype.addSlideMasterRel = function(sRel) {
this.sldMasterIdLst.push(sRel);
};
XmlWriterContext.prototype.addNotesMasterRel = function(sRel) {
this.notesMasterIdLst.push(sRel);
};
XmlWriterContext.prototype.addFieldMasterPart = function(oFieldMaster, oPart) {
this.fieldMastersPartMap[oFieldMaster.Id] = oPart;
};
XmlWriterContext.prototype.addUserMasterPart = function(oUserMaster, oPart) {
this.userMasterPartMap[oUserMaster.Id] = oPart;
};
XmlWriterContext.prototype.clearSlideLayoutRels = function() {
this.sldLayoutIdLst.length = 0;
};
XmlWriterContext.prototype.getSlideMastersCount = function() {
return this.sldMasterIdLst.length;
};
XmlWriterContext.prototype.getSlidesCount = function() {
return this.sldIdLst.length;
};
XmlWriterContext.prototype.clearCurrentPartDataMaps = function() {
this.currentPartImageMap = {};
this.currentPartDataMap = {};
};
XmlWriterContext.prototype.getImageRId = function(sRasterImageId) {
let imagePart = this.imageMap[sRasterImageId];
let type = this.editorId === AscCommon.c_oEditorId.Word ? AscCommon.openXml.Types.imageWord : AscCommon.openXml.Types.image;
if (!imagePart) {
if (this.part) {
let ext = AscCommon.GetFileExtension(sRasterImageId);
type = Object.assign({}, type);
type.filename += ext;
type.contentType = AscCommon.openXml.GetMimeType(ext);
imagePart = this.part.addPart(type);
if (imagePart) {
this.imageMap[sRasterImageId] = imagePart;
this.currentPartImageMap[sRasterImageId] = imagePart.rId;
}
}
}
else {
if(!this.currentPartImageMap[sRasterImageId]) {
if(this.part) {
this.currentPartImageMap[sRasterImageId] = this.part.addRelationship(type.relationType, imagePart.part.uri);
}
}
}
return this.currentPartImageMap[sRasterImageId] ? this.currentPartImageMap[sRasterImageId] : "";
};
XmlWriterContext.prototype.getDataRId = function(sDataLink) {
let dataPart = this.dataMap[sDataLink];
let type = this.editorId === AscCommon.c_oEditorId.Word ? AscCommon.openXml.Types.wordPackage : AscCommon.openXml.Types.package;
if (!dataPart) {
if (this.part) {
let ext = AscCommon.GetFileExtension(sDataLink);
type = Object.assign({}, type);
type.filename = AscCommon.changeFileExtention(type.filename, ext, null);
type.contentType = AscCommon.openXml.GetMimeType(ext);
dataPart = this.part.addPart(type);
if (dataPart) {
this.dataMap[sDataLink] = dataPart;
this.currentPartDataMap[sDataLink] = dataPart.rId;
}
}
}
else {
if(!this.currentPartDataMap[sDataLink]) {
if(this.part) {
this.currentPartDataMap[sDataLink] = this.part.addRelationship(type.relationType, dataPart.part.uri);
}
}
}
return this.currentPartDataMap[sDataLink] ? this.currentPartDataMap[sDataLink] : "";
};
XmlWriterContext.prototype.getSpIdxId = function(sEditorId){
if(typeof sEditorId === "string" && sEditorId.length > 0) {
var oDrawing = AscCommon.g_oTableId.Get_ById(sEditorId);
if(oDrawing && oDrawing.getFormatId) {
return oDrawing.getFormatId();
}
}
return null;
};
function CT_XmlNode(opt_elemReader) {
this.attributes = {};
this.members = {};
this.text = null;
this.elemReader = opt_elemReader || function(){};
}
CT_XmlNode.fromReader = function(reader, opt_elemReader) {
let node = new CT_XmlNode(opt_elemReader);
node.fromXml(reader);
return node;
};
CT_XmlNode.prototype.readAttr = function(reader) {
while (reader.MoveToNextAttribute()) {
this.attributes[reader.GetNameNoNS()] = reader.GetValue();
}
};
CT_XmlNode.prototype.fromXml = function(reader) {
this.readAttr(reader);
var elem, depth = reader.GetDepth();
while (reader.Read()) {
switch(reader.GetEventType()) {
case EasySAXEvent.START_ELEMENT:
var name = reader.GetNameNoNS();
elem = this.elemReader.call(this, reader, name);
if (!elem) {
elem = new CT_XmlNode();
elem.fromXml(reader);
}
this.members[name] = elem;
break;
case EasySAXEvent.CHARACTERS:
if(!this.text) {
this.text = "";
}
this.text += reader.GetValue();
break;
case EasySAXEvent.END_ELEMENT:
if (reader.GetDepth() === depth)
return;
break;
}
}
};
CT_XmlNode.prototype.toXml = function(writer, name) {
var i;
writer.WriteXmlNodeStart(name);
for (i in this.attributes) {
if (this.attributes.hasOwnProperty(i)) {
writer.WriteXmlNullableAttributeString(i, this.attributes[i]);
}
}
writer.WriteXmlAttributesEnd();
for (i in this.members) {
if (this.members.hasOwnProperty(i)) {
var member = this.members[i];
if(Array.isArray(member)) {
for(var nIdx = 0; nIdx < member.length; ++nIdx) {
member[nIdx].toXml(writer, i);
}
}
else {
member.toXml(writer, i);
}
}
}
if (null !== this.text && undefined !== this.text) {
writer.WriteXmlStringEncode(this.text.toString());
}
writer.WriteXmlNodeEnd(name);
};
window['AscCommon'] = window['AscCommon'] || {};
window['AscCommon'].XmlParserContext = XmlParserContext;
window["AscCommon"].XmlWriterContext = XmlWriterContext;
window['AscCommon'].StaxParser = StaxParser;