@a3s-lab/office 0.30.0 → 0.32.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -5
- package/dist/{0~7231.js → 0~4808.js} +190 -3
- package/dist/0~4980.js +1 -1
- package/dist/0~5050.js +10 -1
- package/dist/{0~7360.js → 0~7240.js} +245 -16
- package/dist/0~7614.js +1 -1
- package/dist/0~document-editor.js +1756 -178
- package/dist/0~spreadsheet-editor.js +2 -1
- package/dist/0~work-docx-export.js +215 -27
- package/dist/0~work-docx-import.js +27 -33
- package/dist/0~work-docx-large-document-import.js +1 -1
- package/dist/0~work-office-diagnostics.js +28 -7
- package/dist/0~work-pptx-import.js +1 -1
- package/dist/{1544.js → 3266.js} +17 -1862
- package/dist/4121.js +425 -11
- package/dist/4166.js +3848 -0
- package/dist/{6282.js → 4174.js} +812 -10
- package/dist/9333.js +1849 -0
- package/dist/core.js +5259 -4
- package/dist/index.js +3 -3
- package/dist/internal/features/work/editors/document-command-catalog.d.ts +27 -0
- package/dist/internal/features/work/editors/document-compare-dialog.d.ts +14 -0
- package/dist/internal/features/work/editors/document-dom-selection.d.ts +7 -0
- package/dist/internal/features/work/editors/document-editor-support.d.ts +1 -0
- package/dist/internal/features/work/editors/document-index-dialog.d.ts +10 -0
- package/dist/internal/features/work/editors/document-index-entry-dialog.d.ts +10 -0
- package/dist/internal/features/work/editors/document-references-ribbon.d.ts +19 -0
- package/dist/internal/features/work/editors/document-toolbar.d.ts +6 -1
- package/dist/internal/features/work/editors/use-document-comparison.d.ts +9 -0
- package/dist/internal/features/work/editors/use-document-insert-commands.d.ts +3 -0
- package/dist/internal/features/work/work-document-changes.d.ts +5 -0
- package/dist/internal/features/work/work-document-compare-diff.d.ts +38 -0
- package/dist/internal/features/work/work-document-compare-stability.d.ts +5 -0
- package/dist/internal/features/work/work-document-compare.d.ts +27 -0
- package/dist/internal/features/work/work-document-index-fields.d.ts +19 -0
- package/dist/internal/features/work/work-document-index-nodes.d.ts +32 -0
- package/dist/internal/features/work/work-document-index.d.ts +63 -0
- package/dist/internal/features/work/work-docx-import.d.ts +3 -1
- package/dist/internal/features/work/work-docx-index-export.d.ts +14 -0
- package/dist/internal/features/work/work-docx-index-import.d.ts +23 -0
- package/dist/office-kernel.wasm +0 -0
- package/dist/styles.css +490 -0
- package/docs/latest/en/browser-editor-architecture.md +37 -0
- package/package.json +9 -3
- package/dist/4104.js +0 -9336
package/dist/4121.js
CHANGED
|
@@ -1919,6 +1919,296 @@ function patchDocumentProofingLanguages(source, patch) {
|
|
|
1919
1919
|
function isRecord(source) {
|
|
1920
1920
|
return 'object' == typeof source && null !== source && !Array.isArray(source);
|
|
1921
1921
|
}
|
|
1922
|
+
const DEFAULT_DOCUMENT_INDEX_OPTIONS = {
|
|
1923
|
+
columns: 1,
|
|
1924
|
+
format: 'indented',
|
|
1925
|
+
rightAlignPageNumbers: true,
|
|
1926
|
+
leader: 'dot'
|
|
1927
|
+
};
|
|
1928
|
+
const MAX_DOCUMENT_INDEX_ENTRIES = 512;
|
|
1929
|
+
const MAX_DOCUMENT_INDEX_MARKERS = 2048;
|
|
1930
|
+
const MAX_DOCUMENT_INDEX_TERM_LENGTH = 240;
|
|
1931
|
+
const INDEX_ENTRY_SELECTOR = '[data-document-index-entry]';
|
|
1932
|
+
const INDEX_SELECTOR = '[data-document-index]';
|
|
1933
|
+
const INDEX_ID_PATTERN = /^[a-z0-9][a-z0-9._:-]{0,127}$/i;
|
|
1934
|
+
function normalizeDocumentIndexEntryDraft(source) {
|
|
1935
|
+
const mainEntry = normalizedIndexTerm(source?.mainEntry);
|
|
1936
|
+
if (!mainEntry) return null;
|
|
1937
|
+
const subEntry = normalizedIndexTerm(source?.subEntry);
|
|
1938
|
+
const crossReference = normalizedIndexTerm(source?.crossReference);
|
|
1939
|
+
return {
|
|
1940
|
+
mainEntry,
|
|
1941
|
+
subEntry,
|
|
1942
|
+
crossReference,
|
|
1943
|
+
pageBold: !crossReference && Boolean(source?.pageBold),
|
|
1944
|
+
pageItalic: !crossReference && Boolean(source?.pageItalic)
|
|
1945
|
+
};
|
|
1946
|
+
}
|
|
1947
|
+
function normalizeDocumentIndexEntry(source, fallbackId = 'index-entry') {
|
|
1948
|
+
const value = normalizeDocumentIndexEntryDraft(source);
|
|
1949
|
+
if (!value) return null;
|
|
1950
|
+
return {
|
|
1951
|
+
id: validIndexId(source?.id) ?? fallbackId,
|
|
1952
|
+
...value
|
|
1953
|
+
};
|
|
1954
|
+
}
|
|
1955
|
+
function normalizeDocumentIndexOptions(source) {
|
|
1956
|
+
return {
|
|
1957
|
+
columns: boundedColumns(source?.columns),
|
|
1958
|
+
format: source?.format === 'run-in' ? 'run-in' : 'indented',
|
|
1959
|
+
rightAlignPageNumbers: source?.rightAlignPageNumbers !== false,
|
|
1960
|
+
leader: indexLeader(source?.leader) ?? 'dot'
|
|
1961
|
+
};
|
|
1962
|
+
}
|
|
1963
|
+
function normalizeDocumentIndexValue(source) {
|
|
1964
|
+
return {
|
|
1965
|
+
id: validIndexId(source.id) ?? 'document-index',
|
|
1966
|
+
options: normalizeDocumentIndexOptions(source.options),
|
|
1967
|
+
entries: normalizeGeneratedEntries(source.entries),
|
|
1968
|
+
truncated: Boolean(source.truncated)
|
|
1969
|
+
};
|
|
1970
|
+
}
|
|
1971
|
+
function buildDocumentIndexEntries(document, options = {}) {
|
|
1972
|
+
const grouped = new Map();
|
|
1973
|
+
let markerCount = 0;
|
|
1974
|
+
document.descendants((node, position)=>{
|
|
1975
|
+
if ('documentIndexEntry' !== node.type.name) return;
|
|
1976
|
+
markerCount += 1;
|
|
1977
|
+
if (markerCount > MAX_DOCUMENT_INDEX_MARKERS) return;
|
|
1978
|
+
const marker = normalizeDocumentIndexEntry(node.attrs, `index-entry-${markerCount}`);
|
|
1979
|
+
if (!marker) return;
|
|
1980
|
+
const key = indexEntryKey(marker);
|
|
1981
|
+
let group = grouped.get(key);
|
|
1982
|
+
if (!group) {
|
|
1983
|
+
group = {
|
|
1984
|
+
entry: {
|
|
1985
|
+
mainEntry: marker.mainEntry,
|
|
1986
|
+
subEntry: marker.subEntry,
|
|
1987
|
+
crossReference: marker.crossReference,
|
|
1988
|
+
pages: []
|
|
1989
|
+
},
|
|
1990
|
+
pages: new Map()
|
|
1991
|
+
};
|
|
1992
|
+
grouped.set(key, group);
|
|
1993
|
+
}
|
|
1994
|
+
if (marker.crossReference) return;
|
|
1995
|
+
const pageNumber = positiveInteger(options.resolveContext?.(position)?.pageNumber) ?? fallbackDocumentPageNumber(document, position);
|
|
1996
|
+
const existing = group.pages.get(pageNumber);
|
|
1997
|
+
if (existing) {
|
|
1998
|
+
existing.pageBold ||= marker.pageBold;
|
|
1999
|
+
existing.pageItalic ||= marker.pageItalic;
|
|
2000
|
+
if (!existing.targetIds.includes(marker.id)) existing.targetIds.push(marker.id);
|
|
2001
|
+
return;
|
|
2002
|
+
}
|
|
2003
|
+
group.pages.set(pageNumber, {
|
|
2004
|
+
pageNumber,
|
|
2005
|
+
pageBold: marker.pageBold,
|
|
2006
|
+
pageItalic: marker.pageItalic,
|
|
2007
|
+
targetIds: [
|
|
2008
|
+
marker.id
|
|
2009
|
+
]
|
|
2010
|
+
});
|
|
2011
|
+
});
|
|
2012
|
+
const collator = new Intl.Collator(void 0, {
|
|
2013
|
+
numeric: true,
|
|
2014
|
+
sensitivity: 'base',
|
|
2015
|
+
usage: 'sort'
|
|
2016
|
+
});
|
|
2017
|
+
const allEntries = Array.from(grouped.values()).map(({ entry, pages })=>({
|
|
2018
|
+
...entry,
|
|
2019
|
+
pages: Array.from(pages.values()).sort((left, right)=>left.pageNumber - right.pageNumber)
|
|
2020
|
+
})).sort((left, right)=>collator.compare(left.mainEntry, right.mainEntry) || collator.compare(left.subEntry, right.subEntry) || collator.compare(left.crossReference, right.crossReference));
|
|
2021
|
+
return {
|
|
2022
|
+
entries: allEntries.slice(0, MAX_DOCUMENT_INDEX_ENTRIES),
|
|
2023
|
+
truncated: markerCount > MAX_DOCUMENT_INDEX_MARKERS || allEntries.length > MAX_DOCUMENT_INDEX_ENTRIES
|
|
2024
|
+
};
|
|
2025
|
+
}
|
|
2026
|
+
function documentIndexEntryHtml(source) {
|
|
2027
|
+
const value = normalizeDocumentIndexEntry(source);
|
|
2028
|
+
if (!value) return '';
|
|
2029
|
+
const detail = indexEntryDisplay(value);
|
|
2030
|
+
return [
|
|
2031
|
+
`<span data-document-index-entry="true" data-index-entry-id="${escapeHtmlAttribute(value.id)}" data-index-main-entry="${escapeHtmlAttribute(value.mainEntry)}" data-index-sub-entry="${escapeHtmlAttribute(value.subEntry)}" data-index-cross-reference="${escapeHtmlAttribute(value.crossReference)}" data-index-page-bold="${String(value.pageBold)}" data-index-page-italic="${String(value.pageItalic)}" class="work-document-index-entry" contenteditable="false" aria-label="索引项:${escapeHtmlAttribute(detail)}">`,
|
|
2032
|
+
'<span aria-hidden="true">索引项</span>',
|
|
2033
|
+
`<strong>${escapeHtml(detail)}</strong>`,
|
|
2034
|
+
'</span>'
|
|
2035
|
+
].join('');
|
|
2036
|
+
}
|
|
2037
|
+
function documentIndexHtml(source) {
|
|
2038
|
+
const value = normalizeDocumentIndexValue(source);
|
|
2039
|
+
const rows = value.entries.length ? value.entries.map(documentIndexRowHtml) : [
|
|
2040
|
+
'<li class="work-document-index-empty">没有已标记的索引项</li>'
|
|
2041
|
+
];
|
|
2042
|
+
const status = value.truncated ? `仅显示前 ${MAX_DOCUMENT_INDEX_ENTRIES} 项` : `${value.entries.length} 项`;
|
|
2043
|
+
return [
|
|
2044
|
+
`<div data-document-index="true" data-index-id="${escapeHtmlAttribute(value.id)}" data-index-columns="${value.options.columns}" data-index-format="${value.options.format}" data-index-right-align-page-numbers="${String(value.options.rightAlignPageNumbers)}" data-index-leader="${value.options.leader}" data-index-entries="${escapeHtmlAttribute(JSON.stringify(value.entries))}" data-index-truncated="${String(value.truncated)}" class="work-document-index" contenteditable="false" aria-label="索引">`,
|
|
2045
|
+
`<div class="work-document-index-header"><strong>索引</strong><span>${status}</span></div>`,
|
|
2046
|
+
'<ol class="work-document-index-list">',
|
|
2047
|
+
...rows,
|
|
2048
|
+
'</ol></div>'
|
|
2049
|
+
].join('');
|
|
2050
|
+
}
|
|
2051
|
+
function documentIndexEntryFromElement(element, index = 1) {
|
|
2052
|
+
return normalizeDocumentIndexEntry({
|
|
2053
|
+
id: element.dataset.indexEntryId,
|
|
2054
|
+
mainEntry: element.dataset.indexMainEntry,
|
|
2055
|
+
subEntry: element.dataset.indexSubEntry,
|
|
2056
|
+
crossReference: element.dataset.indexCrossReference,
|
|
2057
|
+
pageBold: 'true' === element.dataset.indexPageBold,
|
|
2058
|
+
pageItalic: 'true' === element.dataset.indexPageItalic
|
|
2059
|
+
}, `index-entry-${index}`);
|
|
2060
|
+
}
|
|
2061
|
+
function documentIndexValueFromElement(element, index = 1) {
|
|
2062
|
+
return normalizeDocumentIndexValue({
|
|
2063
|
+
id: validIndexId(element.dataset.indexId) ?? `document-index-${index}`,
|
|
2064
|
+
options: {
|
|
2065
|
+
columns: Number(element.dataset.indexColumns),
|
|
2066
|
+
format: 'run-in' === element.dataset.indexFormat ? 'run-in' : 'indented',
|
|
2067
|
+
rightAlignPageNumbers: 'false' !== element.dataset.indexRightAlignPageNumbers,
|
|
2068
|
+
leader: indexLeader(element.dataset.indexLeader) ?? 'dot'
|
|
2069
|
+
},
|
|
2070
|
+
entries: parseGeneratedEntries(element.dataset.indexEntries),
|
|
2071
|
+
truncated: 'true' === element.dataset.indexTruncated
|
|
2072
|
+
});
|
|
2073
|
+
}
|
|
2074
|
+
function normalizeDocumentIndexesHtml(source) {
|
|
2075
|
+
const document = new DOMParser().parseFromString(source, 'text/html');
|
|
2076
|
+
const usedEntryIds = new Set();
|
|
2077
|
+
for (const [index, element] of Array.from(document.body.querySelectorAll(INDEX_ENTRY_SELECTOR)).entries()){
|
|
2078
|
+
const value = documentIndexEntryFromElement(element, index + 1);
|
|
2079
|
+
if (!value) {
|
|
2080
|
+
element.remove();
|
|
2081
|
+
continue;
|
|
2082
|
+
}
|
|
2083
|
+
value.id = uniqueIndexId(value.id, 'index-entry', index + 1, usedEntryIds);
|
|
2084
|
+
element.replaceWith(document.createRange().createContextualFragment(documentIndexEntryHtml(value)));
|
|
2085
|
+
}
|
|
2086
|
+
const usedIndexIds = new Set();
|
|
2087
|
+
for (const [index, element] of Array.from(document.body.querySelectorAll(INDEX_SELECTOR)).entries()){
|
|
2088
|
+
const value = documentIndexValueFromElement(element, index + 1);
|
|
2089
|
+
value.id = uniqueIndexId(value.id, 'document-index', index + 1, usedIndexIds);
|
|
2090
|
+
element.replaceWith(document.createRange().createContextualFragment(documentIndexHtml(value)));
|
|
2091
|
+
}
|
|
2092
|
+
return document.body.innerHTML;
|
|
2093
|
+
}
|
|
2094
|
+
function indexLeader(value) {
|
|
2095
|
+
return 'dot' === value || 'dash' === value || 'underline' === value || 'none' === value ? value : null;
|
|
2096
|
+
}
|
|
2097
|
+
function documentIndexRowHtml(entry) {
|
|
2098
|
+
const term = entry.subEntry ? `<span class="work-document-index-main">${escapeHtml(entry.mainEntry)}</span><span class="work-document-index-sub">${escapeHtml(entry.subEntry)}</span>` : `<span class="work-document-index-main">${escapeHtml(entry.mainEntry)}</span>`;
|
|
2099
|
+
const pages = entry.crossReference ? `<span class="work-document-index-cross-reference">参见 ${escapeHtml(entry.crossReference)}</span>` : entry.pages.map((page)=>{
|
|
2100
|
+
const target = page.targetIds[0] ?? '';
|
|
2101
|
+
const classes = [
|
|
2102
|
+
page.pageBold ? 'bold' : '',
|
|
2103
|
+
page.pageItalic ? 'italic' : ''
|
|
2104
|
+
].filter(Boolean).join(' ');
|
|
2105
|
+
return `<a href="#${escapeHtmlAttribute(target)}" data-index-target="${escapeHtmlAttribute(target)}" tabindex="-1"${classes ? ` class="${classes}"` : ''}>${page.pageNumber}</a>`;
|
|
2106
|
+
}).join('<span aria-hidden="true">, </span>');
|
|
2107
|
+
return `<li data-index-main-entry="${escapeHtmlAttribute(entry.mainEntry)}" data-index-sub-entry="${escapeHtmlAttribute(entry.subEntry)}">${term}<i aria-hidden="true"></i><span class="work-document-index-pages">${pages}</span></li>`;
|
|
2108
|
+
}
|
|
2109
|
+
function normalizeGeneratedEntries(source) {
|
|
2110
|
+
const entries = [];
|
|
2111
|
+
for (const item of source.slice(0, MAX_DOCUMENT_INDEX_ENTRIES)){
|
|
2112
|
+
if (!item || 'object' != typeof item) continue;
|
|
2113
|
+
const candidate = item;
|
|
2114
|
+
const draft = normalizeDocumentIndexEntryDraft({
|
|
2115
|
+
mainEntry: normalizedIndexTerm(candidate.mainEntry),
|
|
2116
|
+
subEntry: normalizedIndexTerm(candidate.subEntry),
|
|
2117
|
+
crossReference: normalizedIndexTerm(candidate.crossReference)
|
|
2118
|
+
});
|
|
2119
|
+
if (draft) entries.push({
|
|
2120
|
+
mainEntry: draft.mainEntry,
|
|
2121
|
+
subEntry: draft.subEntry,
|
|
2122
|
+
crossReference: draft.crossReference,
|
|
2123
|
+
pages: draft.crossReference ? [] : normalizeIndexPages(candidate.pages)
|
|
2124
|
+
});
|
|
2125
|
+
}
|
|
2126
|
+
return entries;
|
|
2127
|
+
}
|
|
2128
|
+
function normalizeIndexPages(source) {
|
|
2129
|
+
if (!Array.isArray(source)) return [];
|
|
2130
|
+
const pages = [];
|
|
2131
|
+
const seen = new Set();
|
|
2132
|
+
for (const item of source.slice(0, MAX_DOCUMENT_INDEX_MARKERS)){
|
|
2133
|
+
if (!item || 'object' != typeof item) continue;
|
|
2134
|
+
const candidate = item;
|
|
2135
|
+
const pageNumber = positiveInteger(candidate.pageNumber);
|
|
2136
|
+
if (!pageNumber || seen.has(pageNumber)) continue;
|
|
2137
|
+
const targetIds = Array.isArray(candidate.targetIds) ? candidate.targetIds.flatMap((value)=>validIndexId(value) ? [
|
|
2138
|
+
String(value)
|
|
2139
|
+
] : []).slice(0, 64) : [];
|
|
2140
|
+
if (targetIds.length) {
|
|
2141
|
+
seen.add(pageNumber);
|
|
2142
|
+
pages.push({
|
|
2143
|
+
pageNumber,
|
|
2144
|
+
pageBold: Boolean(candidate.pageBold),
|
|
2145
|
+
pageItalic: Boolean(candidate.pageItalic),
|
|
2146
|
+
targetIds
|
|
2147
|
+
});
|
|
2148
|
+
}
|
|
2149
|
+
}
|
|
2150
|
+
return pages.sort((left, right)=>left.pageNumber - right.pageNumber);
|
|
2151
|
+
}
|
|
2152
|
+
function parseGeneratedEntries(source) {
|
|
2153
|
+
if (!source) return [];
|
|
2154
|
+
try {
|
|
2155
|
+
const parsed = JSON.parse(source);
|
|
2156
|
+
return Array.isArray(parsed) ? normalizeGeneratedEntries(parsed) : [];
|
|
2157
|
+
} catch {
|
|
2158
|
+
return [];
|
|
2159
|
+
}
|
|
2160
|
+
}
|
|
2161
|
+
function fallbackDocumentPageNumber(document, position) {
|
|
2162
|
+
let pageNumber = 1;
|
|
2163
|
+
document.descendants((node, offset)=>{
|
|
2164
|
+
if (offset >= position) return false;
|
|
2165
|
+
if ('pageBreak' === node.type.name) pageNumber += 1;
|
|
2166
|
+
return true;
|
|
2167
|
+
});
|
|
2168
|
+
return pageNumber;
|
|
2169
|
+
}
|
|
2170
|
+
function indexEntryKey(entry) {
|
|
2171
|
+
return [
|
|
2172
|
+
entry.mainEntry,
|
|
2173
|
+
entry.subEntry,
|
|
2174
|
+
entry.crossReference
|
|
2175
|
+
].map((value)=>value.normalize('NFKC').toLocaleLowerCase()).join('\u0000');
|
|
2176
|
+
}
|
|
2177
|
+
function indexEntryDisplay(entry) {
|
|
2178
|
+
const term = entry.subEntry ? `${entry.mainEntry} › ${entry.subEntry}` : entry.mainEntry;
|
|
2179
|
+
return entry.crossReference ? `${term} · 参见 ${entry.crossReference}` : term;
|
|
2180
|
+
}
|
|
2181
|
+
function normalizedIndexTerm(value) {
|
|
2182
|
+
return 'string' == typeof value ? value.replace(/\s+/g, ' ').trim().slice(0, MAX_DOCUMENT_INDEX_TERM_LENGTH) : '';
|
|
2183
|
+
}
|
|
2184
|
+
function boundedColumns(value) {
|
|
2185
|
+
const number = Number(value);
|
|
2186
|
+
return Number.isInteger(number) && number >= 1 && number <= 4 ? number : 1;
|
|
2187
|
+
}
|
|
2188
|
+
function positiveInteger(value) {
|
|
2189
|
+
const number = Number(value);
|
|
2190
|
+
return Number.isSafeInteger(number) && number > 0 ? Math.min(999999, number) : null;
|
|
2191
|
+
}
|
|
2192
|
+
function validIndexId(value) {
|
|
2193
|
+
return 'string' == typeof value && INDEX_ID_PATTERN.test(value) ? value : null;
|
|
2194
|
+
}
|
|
2195
|
+
function uniqueIndexId(source, prefix, index, used) {
|
|
2196
|
+
if (!used.has(source)) {
|
|
2197
|
+
used.add(source);
|
|
2198
|
+
return source;
|
|
2199
|
+
}
|
|
2200
|
+
let suffix = index;
|
|
2201
|
+
while(used.has(`${prefix}-${suffix}`))suffix += 1;
|
|
2202
|
+
const id = `${prefix}-${suffix}`;
|
|
2203
|
+
used.add(id);
|
|
2204
|
+
return id;
|
|
2205
|
+
}
|
|
2206
|
+
function escapeHtml(value) {
|
|
2207
|
+
return value.replaceAll('&', '&').replaceAll('<', '<').replaceAll('>', '>');
|
|
2208
|
+
}
|
|
2209
|
+
function escapeHtmlAttribute(value) {
|
|
2210
|
+
return escapeHtml(value).replaceAll('"', '"').replaceAll("'", ''');
|
|
2211
|
+
}
|
|
1922
2212
|
const DOCUMENT_PARAGRAPH_ID_ATTRIBUTE = 'data-office-paragraph-id';
|
|
1923
2213
|
const DOCUMENT_PARAGRAPH_TEXT_ID_ATTRIBUTE = 'data-office-paragraph-text-id';
|
|
1924
2214
|
const PARAGRAPH_ID_PATTERN = /^[0-9A-F]{8}$/;
|
|
@@ -2310,7 +2600,7 @@ function documentTableOfContentsHtml(source) {
|
|
|
2310
2600
|
];
|
|
2311
2601
|
const status = value.truncated ? `仅显示前 ${MAX_DOCUMENT_TABLE_OF_CONTENTS_ENTRIES} 项` : `${value.entries.length} 项`;
|
|
2312
2602
|
return [
|
|
2313
|
-
`<div data-document-table-of-contents="true" data-toc-id="${
|
|
2603
|
+
`<div data-document-table-of-contents="true" data-toc-id="${work_document_table_of_contents_escapeHtmlAttribute(value.id)}" data-toc-min-level="${options.minLevel}" data-toc-max-level="${options.maxLevel}" data-toc-hyperlinks="${String(options.hyperlinks)}" data-toc-show-page-numbers="${String(options.showPageNumbers)}" data-toc-right-align-page-numbers="${String(options.rightAlignPageNumbers)}" data-toc-leader="${options.leader}" data-toc-entries="${work_document_table_of_contents_escapeHtmlAttribute(JSON.stringify(value.entries))}" data-toc-truncated="${String(value.truncated)}" class="work-document-table-of-contents" contenteditable="false" aria-label="目录">`,
|
|
2314
2604
|
'<div class="work-document-table-of-contents-header"><strong>目录</strong>',
|
|
2315
2605
|
`<span>${status}</span></div>`,
|
|
2316
2606
|
'<ol class="work-document-table-of-contents-list">',
|
|
@@ -2434,10 +2724,10 @@ function tableOfContentsEntryFromOutline(document, item, resolveContext) {
|
|
|
2434
2724
|
targetId: item.id,
|
|
2435
2725
|
title: item.text.slice(0, MAX_TABLE_OF_CONTENTS_TITLE_LENGTH),
|
|
2436
2726
|
level: item.level,
|
|
2437
|
-
pageNumber:
|
|
2727
|
+
pageNumber: work_document_table_of_contents_positiveInteger(resolveContext?.(item.from)?.pageNumber) ?? work_document_table_of_contents_fallbackDocumentPageNumber(document, item.from)
|
|
2438
2728
|
};
|
|
2439
2729
|
}
|
|
2440
|
-
function
|
|
2730
|
+
function work_document_table_of_contents_fallbackDocumentPageNumber(document, position) {
|
|
2441
2731
|
let pageNumber = 1;
|
|
2442
2732
|
document.descendants((node, offset)=>{
|
|
2443
2733
|
if (offset >= position) return false;
|
|
@@ -2447,8 +2737,8 @@ function fallbackDocumentPageNumber(document, position) {
|
|
|
2447
2737
|
return pageNumber;
|
|
2448
2738
|
}
|
|
2449
2739
|
function tableOfContentsEntryHtml(entry, options) {
|
|
2450
|
-
const title =
|
|
2451
|
-
const targetId =
|
|
2740
|
+
const title = work_document_table_of_contents_escapeHtml(entry.title);
|
|
2741
|
+
const targetId = work_document_table_of_contents_escapeHtmlAttribute(entry.targetId);
|
|
2452
2742
|
const label = options.hyperlinks ? `<a href="#${targetId}" data-toc-target="${targetId}" tabindex="-1">${title}</a>` : `<span>${title}</span>`;
|
|
2453
2743
|
const page = options.showPageNumbers ? `<span class="work-document-table-of-contents-page">${entry.pageNumber}</span>` : '';
|
|
2454
2744
|
return `<li data-toc-target="${targetId}" data-toc-level="${entry.level}" style="--work-toc-level:${entry.level}">${label}<i aria-hidden="true"></i>${page}</li>`;
|
|
@@ -2470,7 +2760,7 @@ function normalizeTableOfContentsEntries(source) {
|
|
|
2470
2760
|
const targetId = 'string' == typeof candidate.targetId ? candidate.targetId.trim() : '';
|
|
2471
2761
|
const title = 'string' == typeof candidate.title ? candidate.title.replace(/\s+/g, ' ').trim() : '';
|
|
2472
2762
|
const level = boundedLevel(candidate.level, 0);
|
|
2473
|
-
const pageNumber =
|
|
2763
|
+
const pageNumber = work_document_table_of_contents_positiveInteger(candidate.pageNumber);
|
|
2474
2764
|
if (TABLE_OF_CONTENTS_TARGET_PATTERN.test(targetId) && title && level && pageNumber) entries.push({
|
|
2475
2765
|
targetId,
|
|
2476
2766
|
title: title.slice(0, MAX_TABLE_OF_CONTENTS_TITLE_LENGTH),
|
|
@@ -2499,7 +2789,7 @@ function boundedLevel(value, fallback) {
|
|
|
2499
2789
|
const number = Number(value);
|
|
2500
2790
|
return Number.isInteger(number) && number >= 1 && number <= 9 ? number : fallback;
|
|
2501
2791
|
}
|
|
2502
|
-
function
|
|
2792
|
+
function work_document_table_of_contents_positiveInteger(value) {
|
|
2503
2793
|
const number = Number(value);
|
|
2504
2794
|
return Number.isSafeInteger(number) && number > 0 ? Math.min(999999, number) : null;
|
|
2505
2795
|
}
|
|
@@ -2517,11 +2807,11 @@ function uniqueTableOfContentsId(source, index, usedIds) {
|
|
|
2517
2807
|
usedIds.add(id);
|
|
2518
2808
|
return id;
|
|
2519
2809
|
}
|
|
2520
|
-
function
|
|
2810
|
+
function work_document_table_of_contents_escapeHtml(value) {
|
|
2521
2811
|
return value.replaceAll('&', '&').replaceAll('<', '<').replaceAll('>', '>');
|
|
2522
2812
|
}
|
|
2523
|
-
function
|
|
2524
|
-
return
|
|
2813
|
+
function work_document_table_of_contents_escapeHtmlAttribute(value) {
|
|
2814
|
+
return work_document_table_of_contents_escapeHtml(value).replaceAll('"', '"').replaceAll("'", ''');
|
|
2525
2815
|
}
|
|
2526
2816
|
const WORK_TEMPLATES = [
|
|
2527
2817
|
{
|
|
@@ -2538,6 +2828,13 @@ const WORK_TEMPLATES = [
|
|
|
2538
2828
|
description: '目标、范围、里程碑与风险',
|
|
2539
2829
|
accent: '#536de2'
|
|
2540
2830
|
},
|
|
2831
|
+
{
|
|
2832
|
+
id: 'document-comparison',
|
|
2833
|
+
kind: 'document',
|
|
2834
|
+
name: '文档比较',
|
|
2835
|
+
description: '导入版本并生成可接受或拒绝的确定性修订',
|
|
2836
|
+
accent: '#6a54b8'
|
|
2837
|
+
},
|
|
2541
2838
|
{
|
|
2542
2839
|
id: 'table-of-contents',
|
|
2543
2840
|
kind: 'document',
|
|
@@ -2545,6 +2842,13 @@ const WORK_TEMPLATES = [
|
|
|
2545
2842
|
description: '标题级别、超链接、页码、前导符与原生 DOCX 往返',
|
|
2546
2843
|
accent: '#315f9f'
|
|
2547
2844
|
},
|
|
2845
|
+
{
|
|
2846
|
+
id: 'document-index',
|
|
2847
|
+
kind: 'document',
|
|
2848
|
+
name: '原生索引',
|
|
2849
|
+
description: '主次索引项、交叉引用、页码样式与原生 DOCX 往返',
|
|
2850
|
+
accent: '#4d6398'
|
|
2851
|
+
},
|
|
2548
2852
|
{
|
|
2549
2853
|
id: 'text-effects',
|
|
2550
2854
|
kind: 'document',
|
|
@@ -2638,7 +2942,9 @@ function createWorkId(prefix) {
|
|
|
2638
2942
|
function initialTitle(templateId, kind) {
|
|
2639
2943
|
const titles = {
|
|
2640
2944
|
'project-brief': '新项目方案',
|
|
2945
|
+
'document-comparison': '文档比较示例',
|
|
2641
2946
|
'table-of-contents': '可更新目录示例',
|
|
2947
|
+
'document-index': '原生索引示例',
|
|
2642
2948
|
'text-effects': '文字效果示例',
|
|
2643
2949
|
'run-borders': '字符边框示例',
|
|
2644
2950
|
'run-shading': '字符底纹示例',
|
|
@@ -2659,6 +2965,11 @@ function contentForTemplate(templateId) {
|
|
|
2659
2965
|
pageSize: 'a4',
|
|
2660
2966
|
html: "<h1>新项目方案</h1><p><strong>负责人:</strong>项目团队 <strong>更新日期:</strong>今天</p><blockquote><p>用一句话说明这项工作的目标,以及完成后会带来什么变化。</p></blockquote><h2>背景与目标</h2><p>描述当前情况、核心问题和可衡量的成功标准。</p><h2>工作范围</h2><ul><li><p>需要完成的关键交付物</p></li><li><p>明确不在本期范围内的事项</p></li></ul><h2>里程碑</h2><ol><li><p>方案确认</p></li><li><p>执行与评审</p></li><li><p>交付与复盘</p></li></ol><h2>风险与决策</h2><p>记录尚未解决的问题、依赖和决策负责人。</p>"
|
|
2661
2967
|
};
|
|
2968
|
+
if ('document-comparison' === templateId) return {
|
|
2969
|
+
type: 'document',
|
|
2970
|
+
pageSize: 'a4',
|
|
2971
|
+
html: "<h1>发布审阅基线</h1><p><strong>基线版本:</strong>1.0</p><h2>比较步骤</h2><p>打开“审阅”,选择“比较文档”,再导入 DOCX、HTML 或 TXT 修订版本。</p><h2>审阅范围</h2><p>当前基线包含架构说明与发布说明。</p><h2>决策要求</h2><p>发布前必须逐项接受或拒绝所有生成的修订。</p>"
|
|
2972
|
+
};
|
|
2662
2973
|
if ('table-of-contents' === templateId) return {
|
|
2663
2974
|
type: 'document',
|
|
2664
2975
|
pageSize: 'a4',
|
|
@@ -2703,6 +3014,109 @@ function contentForTemplate(templateId) {
|
|
|
2703
3014
|
'<p>导出 DOCX 后仍保留原生 TOC 域、缓存目录项、超链接和前导符。</p>'
|
|
2704
3015
|
].join('')
|
|
2705
3016
|
};
|
|
3017
|
+
if ('document-index' === templateId) return {
|
|
3018
|
+
type: 'document',
|
|
3019
|
+
pageSize: 'a4',
|
|
3020
|
+
html: [
|
|
3021
|
+
documentIndexHtml({
|
|
3022
|
+
id: 'playground-document-index',
|
|
3023
|
+
options: {
|
|
3024
|
+
columns: 2,
|
|
3025
|
+
format: 'indented',
|
|
3026
|
+
rightAlignPageNumbers: true,
|
|
3027
|
+
leader: 'dot'
|
|
3028
|
+
},
|
|
3029
|
+
entries: [
|
|
3030
|
+
{
|
|
3031
|
+
mainEntry: 'Architecture',
|
|
3032
|
+
subEntry: '',
|
|
3033
|
+
crossReference: '',
|
|
3034
|
+
pages: [
|
|
3035
|
+
{
|
|
3036
|
+
pageNumber: 1,
|
|
3037
|
+
pageBold: false,
|
|
3038
|
+
pageItalic: false,
|
|
3039
|
+
targetIds: [
|
|
3040
|
+
'index-entry-architecture'
|
|
3041
|
+
]
|
|
3042
|
+
}
|
|
3043
|
+
]
|
|
3044
|
+
},
|
|
3045
|
+
{
|
|
3046
|
+
mainEntry: 'Architecture',
|
|
3047
|
+
subEntry: 'Runtime',
|
|
3048
|
+
crossReference: '',
|
|
3049
|
+
pages: [
|
|
3050
|
+
{
|
|
3051
|
+
pageNumber: 1,
|
|
3052
|
+
pageBold: true,
|
|
3053
|
+
pageItalic: false,
|
|
3054
|
+
targetIds: [
|
|
3055
|
+
'index-entry-runtime'
|
|
3056
|
+
]
|
|
3057
|
+
}
|
|
3058
|
+
]
|
|
3059
|
+
},
|
|
3060
|
+
{
|
|
3061
|
+
mainEntry: 'Collaboration',
|
|
3062
|
+
subEntry: '',
|
|
3063
|
+
crossReference: 'Architecture',
|
|
3064
|
+
pages: []
|
|
3065
|
+
},
|
|
3066
|
+
{
|
|
3067
|
+
mainEntry: 'Performance',
|
|
3068
|
+
subEntry: '',
|
|
3069
|
+
crossReference: '',
|
|
3070
|
+
pages: [
|
|
3071
|
+
{
|
|
3072
|
+
pageNumber: 2,
|
|
3073
|
+
pageBold: false,
|
|
3074
|
+
pageItalic: true,
|
|
3075
|
+
targetIds: [
|
|
3076
|
+
'index-entry-performance'
|
|
3077
|
+
]
|
|
3078
|
+
}
|
|
3079
|
+
]
|
|
3080
|
+
}
|
|
3081
|
+
]
|
|
3082
|
+
}),
|
|
3083
|
+
'<h1>原生索引</h1>',
|
|
3084
|
+
`<p>选择正文后,从“引用 → 标记索引项”创建主索引项、次索引项或交叉引用。${documentIndexEntryHtml({
|
|
3085
|
+
id: 'index-entry-architecture',
|
|
3086
|
+
mainEntry: 'Architecture',
|
|
3087
|
+
subEntry: '',
|
|
3088
|
+
crossReference: '',
|
|
3089
|
+
pageBold: false,
|
|
3090
|
+
pageItalic: false
|
|
3091
|
+
})}</p>`,
|
|
3092
|
+
`<p>Runtime 项的页码使用粗体,并作为 Architecture 的次索引项。${documentIndexEntryHtml({
|
|
3093
|
+
id: 'index-entry-runtime',
|
|
3094
|
+
mainEntry: 'Architecture',
|
|
3095
|
+
subEntry: 'Runtime',
|
|
3096
|
+
crossReference: '',
|
|
3097
|
+
pageBold: true,
|
|
3098
|
+
pageItalic: false
|
|
3099
|
+
})}</p>`,
|
|
3100
|
+
`<p>Collaboration 使用“参见 Architecture”交叉引用,不生成当前页码。${documentIndexEntryHtml({
|
|
3101
|
+
id: 'index-entry-collaboration',
|
|
3102
|
+
mainEntry: 'Collaboration',
|
|
3103
|
+
subEntry: '',
|
|
3104
|
+
crossReference: 'Architecture',
|
|
3105
|
+
pageBold: false,
|
|
3106
|
+
pageItalic: false
|
|
3107
|
+
})}</p>`,
|
|
3108
|
+
'<hr class="work-page-break" data-page-break="true">',
|
|
3109
|
+
`<p>Performance 位于第二页,页码使用斜体。${documentIndexEntryHtml({
|
|
3110
|
+
id: 'index-entry-performance',
|
|
3111
|
+
mainEntry: 'Performance',
|
|
3112
|
+
subEntry: '',
|
|
3113
|
+
crossReference: '',
|
|
3114
|
+
pageBold: false,
|
|
3115
|
+
pageItalic: true
|
|
3116
|
+
})}</p>`,
|
|
3117
|
+
'<p>修改索引项后选择“更新索引”,再导出 DOCX 验证原生 XE 与 INDEX 域。</p>'
|
|
3118
|
+
].join('')
|
|
3119
|
+
};
|
|
2706
3120
|
if ('text-effects' === templateId) return {
|
|
2707
3121
|
type: 'document',
|
|
2708
3122
|
pageSize: 'a4',
|
|
@@ -3445,4 +3859,4 @@ new TextEncoder();
|
|
|
3445
3859
|
function isOfficeKernelSpreadsheetError(value) {
|
|
3446
3860
|
return 'string' == typeof value && spreadsheetErrors.has(value);
|
|
3447
3861
|
}
|
|
3448
|
-
export { DEFAULT_DOCUMENT_TABLE_OF_CONTENTS_OPTIONS, DOCUMENT_HIGHLIGHT_ATTRIBUTE, DOCUMENT_NO_PROOF_ATTRIBUTE, DOCUMENT_PARAGRAPH_BORDERS_ATTRIBUTE, DOCUMENT_PARAGRAPH_BORDER_EDGES, DOCUMENT_PARAGRAPH_BORDER_STYLES, DOCUMENT_PARAGRAPH_ID_ATTRIBUTE, DOCUMENT_PARAGRAPH_TEXT_ID_ATTRIBUTE, DOCUMENT_PROOFING_LANGUAGES_ATTRIBUTE, DOCUMENT_RUN_BORDER_ATTRIBUTE, DOCUMENT_RUN_BORDER_STYLES, DOCUMENT_RUN_SHADING_ATTRIBUTE, DOCUMENT_SCRIPT_FONTS_ATTRIBUTE, DOCUMENT_SCRIPT_FONT_SLOT_ATTRIBUTE, DocumentParagraphIdentity, DocxThemePatchCollector, OFFICE_KERNEL_SPREADSHEET_MAX_ROWS, OoxmlPackage, WORK_TEMPLATES as officeTemplates, applyDocumentParagraphIdentityToElement, attribute, buildDocumentTableOfContentsEntries, bytesToDataUrl, childPath, collectWorkDocumentOutline, contentTypeForPart, createDocumentParagraphIdentity, createDocumentParagraphIdentityRegistry, createWorkArtifact as createArtifact, createWorkId as createOfficeId, cssDocumentFontFamily, currentWorkDocumentOutlineItem, decodeXmlBytes, descendants, directChild, directChildren, documentBorderPresentation, documentFontNameFromCssFamily, documentHasIntegrityFeature, documentHighlightCssColor, documentHighlightDomAttributes, documentHighlightForCssColor, documentHighlightFromDocxValue, documentHighlightFromElement, documentNoProofFromElement, documentParagraphBordersDomAttributes, documentParagraphIdentityFromElement, documentParagraphShadingDomAttributes, documentProofingDomAttributes, documentProofingLanguagesFromElement, documentRunBorderDomAttributes, documentRunBorderIsVisible, documentRunShadingDomAttributes, documentScriptFontDirectFamily, documentScriptFontFallbackSlots, documentScriptFontFamily, documentScriptFontFamilyForRendering, documentScriptFontSegments, documentScriptFontSlotFromElement, documentScriptFontSlotFromHint, documentScriptFontsDomAttributes, documentScriptFontsForAllText, documentScriptFontsFromElement, documentTableOfContentsHtml, documentTableOfContentsValueFromElement, firstDescendant, isDocumentParagraphArtBorderStyle, isOfficeKernelSpreadsheetError, normalizeCssColor, normalizeDocumentFontName, normalizeDocumentHighlight, normalizeDocumentLanguageTag, normalizeDocumentNoProof, normalizeDocumentParagraphBorder, normalizeDocumentParagraphBorders, normalizeDocumentParagraphId, normalizeDocumentParagraphIdentity, normalizeDocumentProofingLanguages, normalizeDocumentRunBorder, normalizeDocumentRunShading, normalizeDocumentScriptFontHint, normalizeDocumentScriptFontSlot, normalizeDocumentScriptFonts, normalizeDocumentTableOfContentsHtml, normalizeDocumentTableOfContentsOptions, normalizeDocumentTableOfContentsValue, normalizeDocumentThemeFont, parseDocumentParagraphBorders, parseDocumentParagraphBordersElement, parseDocumentParagraphShading, parseDocumentParagraphShadingElement, parseDocumentProofingLanguages, parseDocumentRunBorder, parseDocumentRunBorderElement, parseDocumentRunShading, parseDocumentRunShadingElement, parseDocumentScriptFonts, parseDocumentTableOfContentsInstruction, parseDocxThemeReference, parseXml, patchDocumentProofingLanguages, patchDocumentScriptFonts, patchDocxThemeReferences, primeDocumentIntegrityFeatures, resolvePartTarget, serializeDocumentParagraphBorders, serializeDocumentParagraphShading, serializeDocumentProofingLanguages, serializeDocumentRunBorder, serializeDocumentRunShading, serializeDocumentScriptFonts, serializeDocxThemeReference, serializeUtf8Xml, uniqueDocumentParagraphIdentity, visibleWorkDocumentOutlineItems, workDocumentOutlineLevel, work_document_paragraph_shading_DOCUMENT_PARAGRAPH_SHADING_PATTERNS, xmlContainsAnyElement, xmlNamespacePrefix };
|
|
3862
|
+
export { DEFAULT_DOCUMENT_INDEX_OPTIONS, DEFAULT_DOCUMENT_TABLE_OF_CONTENTS_OPTIONS, DOCUMENT_HIGHLIGHT_ATTRIBUTE, DOCUMENT_NO_PROOF_ATTRIBUTE, DOCUMENT_PARAGRAPH_BORDERS_ATTRIBUTE, DOCUMENT_PARAGRAPH_BORDER_EDGES, DOCUMENT_PARAGRAPH_BORDER_STYLES, DOCUMENT_PARAGRAPH_ID_ATTRIBUTE, DOCUMENT_PARAGRAPH_TEXT_ID_ATTRIBUTE, DOCUMENT_PROOFING_LANGUAGES_ATTRIBUTE, DOCUMENT_RUN_BORDER_ATTRIBUTE, DOCUMENT_RUN_BORDER_STYLES, DOCUMENT_RUN_SHADING_ATTRIBUTE, DOCUMENT_SCRIPT_FONTS_ATTRIBUTE, DOCUMENT_SCRIPT_FONT_SLOT_ATTRIBUTE, DocumentParagraphIdentity, DocxThemePatchCollector, OFFICE_KERNEL_SPREADSHEET_MAX_ROWS, OoxmlPackage, WORK_TEMPLATES as officeTemplates, applyDocumentParagraphIdentityToElement, attribute, buildDocumentIndexEntries, buildDocumentTableOfContentsEntries, bytesToDataUrl, childPath, collectWorkDocumentOutline, contentTypeForPart, createDocumentParagraphIdentity, createDocumentParagraphIdentityRegistry, createWorkArtifact as createArtifact, createWorkId as createOfficeId, cssDocumentFontFamily, currentWorkDocumentOutlineItem, decodeXmlBytes, descendants, directChild, directChildren, documentBorderPresentation, documentFontNameFromCssFamily, documentHasIntegrityFeature, documentHighlightCssColor, documentHighlightDomAttributes, documentHighlightForCssColor, documentHighlightFromDocxValue, documentHighlightFromElement, documentIndexEntryFromElement, documentIndexEntryHtml, documentIndexHtml, documentIndexValueFromElement, documentNoProofFromElement, documentParagraphBordersDomAttributes, documentParagraphIdentityFromElement, documentParagraphShadingDomAttributes, documentProofingDomAttributes, documentProofingLanguagesFromElement, documentRunBorderDomAttributes, documentRunBorderIsVisible, documentRunShadingDomAttributes, documentScriptFontDirectFamily, documentScriptFontFallbackSlots, documentScriptFontFamily, documentScriptFontFamilyForRendering, documentScriptFontSegments, documentScriptFontSlotFromElement, documentScriptFontSlotFromHint, documentScriptFontsDomAttributes, documentScriptFontsForAllText, documentScriptFontsFromElement, documentTableOfContentsHtml, documentTableOfContentsValueFromElement, firstDescendant, isDocumentParagraphArtBorderStyle, isOfficeKernelSpreadsheetError, normalizeCssColor, normalizeDocumentFontName, normalizeDocumentHighlight, normalizeDocumentIndexEntry, normalizeDocumentIndexEntryDraft, normalizeDocumentIndexOptions, normalizeDocumentIndexValue, normalizeDocumentIndexesHtml, normalizeDocumentLanguageTag, normalizeDocumentNoProof, normalizeDocumentParagraphBorder, normalizeDocumentParagraphBorders, normalizeDocumentParagraphId, normalizeDocumentParagraphIdentity, normalizeDocumentProofingLanguages, normalizeDocumentRunBorder, normalizeDocumentRunShading, normalizeDocumentScriptFontHint, normalizeDocumentScriptFontSlot, normalizeDocumentScriptFonts, normalizeDocumentTableOfContentsHtml, normalizeDocumentTableOfContentsOptions, normalizeDocumentTableOfContentsValue, normalizeDocumentThemeFont, parseDocumentParagraphBorders, parseDocumentParagraphBordersElement, parseDocumentParagraphShading, parseDocumentParagraphShadingElement, parseDocumentProofingLanguages, parseDocumentRunBorder, parseDocumentRunBorderElement, parseDocumentRunShading, parseDocumentRunShadingElement, parseDocumentScriptFonts, parseDocumentTableOfContentsInstruction, parseDocxThemeReference, parseXml, patchDocumentProofingLanguages, patchDocumentScriptFonts, patchDocxThemeReferences, primeDocumentIntegrityFeatures, resolvePartTarget, serializeDocumentParagraphBorders, serializeDocumentParagraphShading, serializeDocumentProofingLanguages, serializeDocumentRunBorder, serializeDocumentRunShading, serializeDocumentScriptFonts, serializeDocxThemeReference, serializeUtf8Xml, uniqueDocumentParagraphIdentity, visibleWorkDocumentOutlineItems, workDocumentOutlineLevel, work_document_paragraph_shading_DOCUMENT_PARAGRAPH_SHADING_PATTERNS, xmlContainsAnyElement, xmlNamespacePrefix };
|