@cj-tech-master/excelts 1.5.0 → 1.6.1
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/dist/browser/excelts.iife.js +1057 -201
- package/dist/browser/excelts.iife.js.map +1 -1
- package/dist/browser/excelts.iife.min.js +63 -33
- package/dist/cjs/doc/column.js +7 -3
- package/dist/cjs/doc/pivot-table.js +149 -61
- package/dist/cjs/doc/workbook.js +3 -1
- package/dist/cjs/doc/worksheet.js +0 -2
- package/dist/cjs/stream/xlsx/worksheet-writer.js +1 -1
- package/dist/cjs/utils/unzip/zip-parser.js +2 -5
- package/dist/cjs/xlsx/xform/book/workbook-xform.js +3 -0
- package/dist/cjs/xlsx/xform/core/content-types-xform.js +19 -14
- package/dist/cjs/xlsx/xform/pivot-table/cache-field-xform.js +135 -0
- package/dist/cjs/xlsx/xform/pivot-table/cache-field.js +7 -4
- package/dist/cjs/xlsx/xform/pivot-table/pivot-cache-definition-xform.js +135 -13
- package/dist/cjs/xlsx/xform/pivot-table/pivot-cache-records-xform.js +193 -45
- package/dist/cjs/xlsx/xform/pivot-table/pivot-table-xform.js +390 -39
- package/dist/cjs/xlsx/xform/sheet/cell-xform.js +6 -0
- package/dist/cjs/xlsx/xform/sheet/worksheet-xform.js +14 -3
- package/dist/cjs/xlsx/xlsx.js +261 -38
- package/dist/esm/doc/column.js +7 -3
- package/dist/esm/doc/pivot-table.js +150 -62
- package/dist/esm/doc/workbook.js +3 -1
- package/dist/esm/doc/worksheet.js +0 -2
- package/dist/esm/stream/xlsx/worksheet-writer.js +1 -1
- package/dist/esm/utils/unzip/zip-parser.js +2 -5
- package/dist/esm/xlsx/xform/book/workbook-xform.js +3 -0
- package/dist/esm/xlsx/xform/core/content-types-xform.js +19 -14
- package/dist/esm/xlsx/xform/pivot-table/cache-field-xform.js +132 -0
- package/dist/esm/xlsx/xform/pivot-table/cache-field.js +7 -4
- package/dist/esm/xlsx/xform/pivot-table/pivot-cache-definition-xform.js +135 -13
- package/dist/esm/xlsx/xform/pivot-table/pivot-cache-records-xform.js +193 -45
- package/dist/esm/xlsx/xform/pivot-table/pivot-table-xform.js +390 -39
- package/dist/esm/xlsx/xform/sheet/cell-xform.js +6 -0
- package/dist/esm/xlsx/xform/sheet/worksheet-xform.js +14 -3
- package/dist/esm/xlsx/xlsx.js +261 -38
- package/dist/types/doc/column.d.ts +13 -6
- package/dist/types/doc/pivot-table.d.ts +135 -9
- package/dist/types/doc/workbook.d.ts +2 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/xlsx/xform/pivot-table/cache-field-xform.d.ts +42 -0
- package/dist/types/xlsx/xform/pivot-table/pivot-cache-definition-xform.d.ts +45 -6
- package/dist/types/xlsx/xform/pivot-table/pivot-cache-records-xform.d.ts +52 -5
- package/dist/types/xlsx/xform/pivot-table/pivot-table-xform.d.ts +98 -5
- package/dist/types/xlsx/xlsx.d.ts +27 -0
- package/package.json +17 -17
|
@@ -1,20 +1,48 @@
|
|
|
1
1
|
import { BaseXform } from "../base-xform.js";
|
|
2
2
|
import { CacheField } from "./cache-field.js";
|
|
3
|
+
import { CacheFieldXform } from "./cache-field-xform.js";
|
|
3
4
|
import { XmlStream } from "../../../utils/xml-stream.js";
|
|
4
5
|
class PivotCacheDefinitionXform extends BaseXform {
|
|
5
6
|
constructor() {
|
|
6
7
|
super();
|
|
7
8
|
this.map = {};
|
|
9
|
+
this.model = null;
|
|
10
|
+
this.currentCacheField = null;
|
|
11
|
+
this.inCacheFields = false;
|
|
12
|
+
this.inCacheSource = false;
|
|
8
13
|
}
|
|
9
14
|
prepare(_model) {
|
|
10
|
-
//
|
|
15
|
+
// No preparation needed for writing
|
|
11
16
|
}
|
|
12
17
|
get tag() {
|
|
13
18
|
// http://www.datypic.com/sc/ooxml/e-ssml_pivotCacheDefinition.html
|
|
14
19
|
return "pivotCacheDefinition";
|
|
15
20
|
}
|
|
21
|
+
reset() {
|
|
22
|
+
this.model = null;
|
|
23
|
+
this.currentCacheField = null;
|
|
24
|
+
this.inCacheFields = false;
|
|
25
|
+
this.inCacheSource = false;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Render pivot cache definition XML.
|
|
29
|
+
* Supports both newly created models (with PivotTableSource) and loaded models.
|
|
30
|
+
*/
|
|
16
31
|
render(xmlStream, model) {
|
|
17
|
-
|
|
32
|
+
// Check if this is a loaded model (has isLoaded flag or no source property)
|
|
33
|
+
const isLoaded = model.isLoaded || !("source" in model);
|
|
34
|
+
if (isLoaded) {
|
|
35
|
+
this.renderLoaded(xmlStream, model);
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
this.renderNew(xmlStream, model);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Render newly created pivot cache definition
|
|
43
|
+
*/
|
|
44
|
+
renderNew(xmlStream, model) {
|
|
45
|
+
const { source, cacheFields } = model;
|
|
18
46
|
xmlStream.openXml(XmlStream.StdDocAttributes);
|
|
19
47
|
xmlStream.openNode(this.tag, {
|
|
20
48
|
...PivotCacheDefinitionXform.PIVOT_CACHE_DEFINITION_ATTRIBUTES,
|
|
@@ -29,8 +57,8 @@ class PivotCacheDefinitionXform extends BaseXform {
|
|
|
29
57
|
});
|
|
30
58
|
xmlStream.openNode("cacheSource", { type: "worksheet" });
|
|
31
59
|
xmlStream.leafNode("worksheetSource", {
|
|
32
|
-
ref:
|
|
33
|
-
sheet:
|
|
60
|
+
ref: source.dimensions.shortRange,
|
|
61
|
+
sheet: source.name
|
|
34
62
|
});
|
|
35
63
|
xmlStream.closeNode();
|
|
36
64
|
xmlStream.openNode("cacheFields", { count: cacheFields.length });
|
|
@@ -39,19 +67,113 @@ class PivotCacheDefinitionXform extends BaseXform {
|
|
|
39
67
|
xmlStream.closeNode();
|
|
40
68
|
xmlStream.closeNode();
|
|
41
69
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
70
|
+
/**
|
|
71
|
+
* Render loaded pivot cache definition (preserving original structure)
|
|
72
|
+
*/
|
|
73
|
+
renderLoaded(xmlStream, model) {
|
|
74
|
+
const { cacheFields, sourceRef, sourceSheet, recordCount } = model;
|
|
75
|
+
xmlStream.openXml(XmlStream.StdDocAttributes);
|
|
76
|
+
xmlStream.openNode(this.tag, {
|
|
77
|
+
...PivotCacheDefinitionXform.PIVOT_CACHE_DEFINITION_ATTRIBUTES,
|
|
78
|
+
"r:id": model.rId || "rId1",
|
|
79
|
+
refreshOnLoad: model.refreshOnLoad || "1",
|
|
80
|
+
refreshedBy: model.refreshedBy || "Author",
|
|
81
|
+
refreshedDate: model.refreshedDate || "45125.026046874998",
|
|
82
|
+
createdVersion: model.createdVersion || "8",
|
|
83
|
+
refreshedVersion: model.refreshedVersion || "8",
|
|
84
|
+
minRefreshableVersion: model.minRefreshableVersion || "3",
|
|
85
|
+
recordCount: recordCount || cacheFields.length + 1
|
|
86
|
+
});
|
|
87
|
+
xmlStream.openNode("cacheSource", { type: "worksheet" });
|
|
88
|
+
xmlStream.leafNode("worksheetSource", {
|
|
89
|
+
ref: sourceRef,
|
|
90
|
+
sheet: sourceSheet
|
|
91
|
+
});
|
|
92
|
+
xmlStream.closeNode();
|
|
93
|
+
xmlStream.openNode("cacheFields", { count: cacheFields.length });
|
|
94
|
+
xmlStream.writeXml(cacheFields
|
|
95
|
+
.map((cacheField) => new CacheField(cacheField).render())
|
|
96
|
+
.join("\n "));
|
|
97
|
+
xmlStream.closeNode();
|
|
98
|
+
xmlStream.closeNode();
|
|
99
|
+
}
|
|
100
|
+
parseOpen(node) {
|
|
101
|
+
const { name, attributes } = node;
|
|
102
|
+
// Delegate to current cacheField parser if active
|
|
103
|
+
if (this.currentCacheField) {
|
|
104
|
+
this.currentCacheField.parseOpen(node);
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
switch (name) {
|
|
108
|
+
case this.tag:
|
|
109
|
+
// pivotCacheDefinition root element
|
|
110
|
+
this.reset();
|
|
111
|
+
this.model = {
|
|
112
|
+
cacheFields: [],
|
|
113
|
+
rId: attributes["r:id"],
|
|
114
|
+
refreshOnLoad: attributes.refreshOnLoad,
|
|
115
|
+
refreshedBy: attributes.refreshedBy,
|
|
116
|
+
refreshedDate: attributes.refreshedDate,
|
|
117
|
+
createdVersion: attributes.createdVersion,
|
|
118
|
+
refreshedVersion: attributes.refreshedVersion,
|
|
119
|
+
minRefreshableVersion: attributes.minRefreshableVersion,
|
|
120
|
+
recordCount: attributes.recordCount ? parseInt(attributes.recordCount, 10) : undefined,
|
|
121
|
+
isLoaded: true
|
|
122
|
+
};
|
|
123
|
+
break;
|
|
124
|
+
case "cacheSource":
|
|
125
|
+
this.inCacheSource = true;
|
|
126
|
+
break;
|
|
127
|
+
case "worksheetSource":
|
|
128
|
+
if (this.inCacheSource && this.model) {
|
|
129
|
+
this.model.sourceRef = attributes.ref;
|
|
130
|
+
this.model.sourceSheet = attributes.sheet;
|
|
131
|
+
}
|
|
132
|
+
break;
|
|
133
|
+
case "cacheFields":
|
|
134
|
+
this.inCacheFields = true;
|
|
135
|
+
break;
|
|
136
|
+
case "cacheField":
|
|
137
|
+
if (this.inCacheFields) {
|
|
138
|
+
this.currentCacheField = new CacheFieldXform();
|
|
139
|
+
this.currentCacheField.parseOpen(node);
|
|
140
|
+
}
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
return true;
|
|
45
144
|
}
|
|
46
|
-
parseText(
|
|
47
|
-
|
|
145
|
+
parseText(text) {
|
|
146
|
+
if (this.currentCacheField) {
|
|
147
|
+
this.currentCacheField.parseText(text);
|
|
148
|
+
}
|
|
48
149
|
}
|
|
49
|
-
parseClose(
|
|
50
|
-
//
|
|
51
|
-
|
|
150
|
+
parseClose(name) {
|
|
151
|
+
// Delegate to current cacheField parser if active
|
|
152
|
+
if (this.currentCacheField) {
|
|
153
|
+
if (!this.currentCacheField.parseClose(name)) {
|
|
154
|
+
// cacheField parsing complete, add to model
|
|
155
|
+
if (this.model && this.currentCacheField.model) {
|
|
156
|
+
this.model.cacheFields.push(this.currentCacheField.model);
|
|
157
|
+
}
|
|
158
|
+
this.currentCacheField = null;
|
|
159
|
+
}
|
|
160
|
+
return true;
|
|
161
|
+
}
|
|
162
|
+
switch (name) {
|
|
163
|
+
case this.tag:
|
|
164
|
+
// End of pivotCacheDefinition
|
|
165
|
+
return false;
|
|
166
|
+
case "cacheSource":
|
|
167
|
+
this.inCacheSource = false;
|
|
168
|
+
break;
|
|
169
|
+
case "cacheFields":
|
|
170
|
+
this.inCacheFields = false;
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
return true;
|
|
52
174
|
}
|
|
53
175
|
reconcile(_model, _options) {
|
|
54
|
-
//
|
|
176
|
+
// No reconciliation needed
|
|
55
177
|
}
|
|
56
178
|
}
|
|
57
179
|
PivotCacheDefinitionXform.PIVOT_CACHE_DEFINITION_ATTRIBUTES = {
|
|
@@ -1,79 +1,227 @@
|
|
|
1
1
|
import { XmlStream } from "../../../utils/xml-stream.js";
|
|
2
|
+
import { xmlEncode, xmlDecode } from "../../../utils/utils.js";
|
|
2
3
|
import { BaseXform } from "../base-xform.js";
|
|
3
4
|
class PivotCacheRecordsXform extends BaseXform {
|
|
4
5
|
constructor() {
|
|
5
6
|
super();
|
|
6
7
|
this.map = {};
|
|
8
|
+
this.model = null;
|
|
9
|
+
this.currentRecord = null;
|
|
7
10
|
}
|
|
8
11
|
prepare(_model) {
|
|
9
|
-
//
|
|
12
|
+
// No preparation needed
|
|
10
13
|
}
|
|
11
14
|
get tag() {
|
|
12
15
|
// http://www.datypic.com/sc/ooxml/e-ssml_pivotCacheRecords.html
|
|
13
16
|
return "pivotCacheRecords";
|
|
14
17
|
}
|
|
18
|
+
reset() {
|
|
19
|
+
this.model = null;
|
|
20
|
+
this.currentRecord = null;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Render pivot cache records XML.
|
|
24
|
+
* Supports both newly created models (with PivotTableSource) and loaded models.
|
|
25
|
+
*/
|
|
15
26
|
render(xmlStream, model) {
|
|
16
|
-
|
|
17
|
-
const
|
|
27
|
+
// Check if this is a loaded model
|
|
28
|
+
const isLoaded = model.isLoaded || !("source" in model);
|
|
29
|
+
if (isLoaded) {
|
|
30
|
+
this.renderLoaded(xmlStream, model);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
this.renderNew(xmlStream, model);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Render newly created pivot cache records
|
|
38
|
+
*/
|
|
39
|
+
renderNew(xmlStream, model) {
|
|
40
|
+
const { source, cacheFields } = model;
|
|
41
|
+
const sourceBodyRows = source.getSheetValues().slice(2);
|
|
18
42
|
xmlStream.openXml(XmlStream.StdDocAttributes);
|
|
19
43
|
xmlStream.openNode(this.tag, {
|
|
20
44
|
...PivotCacheRecordsXform.PIVOT_CACHE_RECORDS_ATTRIBUTES,
|
|
21
45
|
count: sourceBodyRows.length
|
|
22
46
|
});
|
|
23
|
-
xmlStream.writeXml(
|
|
47
|
+
xmlStream.writeXml(this.renderTableNew(sourceBodyRows, cacheFields));
|
|
24
48
|
xmlStream.closeNode();
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Render loaded pivot cache records
|
|
52
|
+
*/
|
|
53
|
+
renderLoaded(xmlStream, model) {
|
|
54
|
+
xmlStream.openXml(XmlStream.StdDocAttributes);
|
|
55
|
+
xmlStream.openNode(this.tag, {
|
|
56
|
+
...PivotCacheRecordsXform.PIVOT_CACHE_RECORDS_ATTRIBUTES,
|
|
57
|
+
count: model.count
|
|
58
|
+
});
|
|
59
|
+
// Render each record
|
|
60
|
+
for (const record of model.records) {
|
|
61
|
+
xmlStream.writeXml("\n <r>");
|
|
62
|
+
for (const value of record) {
|
|
63
|
+
xmlStream.writeXml("\n ");
|
|
64
|
+
xmlStream.writeXml(this.renderRecordValue(value));
|
|
40
65
|
}
|
|
41
|
-
|
|
66
|
+
xmlStream.writeXml("\n </r>");
|
|
42
67
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
68
|
+
xmlStream.closeNode();
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Render a single record value to XML
|
|
72
|
+
*/
|
|
73
|
+
renderRecordValue(value) {
|
|
74
|
+
switch (value.type) {
|
|
75
|
+
case "x":
|
|
76
|
+
return `<x v="${value.value}" />`;
|
|
77
|
+
case "n":
|
|
78
|
+
return `<n v="${value.value}" />`;
|
|
79
|
+
case "s":
|
|
80
|
+
return `<s v="${xmlEncode(String(value.value))}" />`;
|
|
81
|
+
case "b":
|
|
82
|
+
return `<b v="${value.value ? "1" : "0"}" />`;
|
|
83
|
+
case "m":
|
|
84
|
+
return "<m />";
|
|
85
|
+
case "d":
|
|
86
|
+
return `<d v="${value.value.toISOString()}" />`;
|
|
87
|
+
case "e":
|
|
88
|
+
return `<e v="${value.value}" />`;
|
|
89
|
+
default:
|
|
90
|
+
return "<m />";
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// Helper methods for rendering new records
|
|
94
|
+
renderTableNew(sourceBodyRows, cacheFields) {
|
|
95
|
+
const parts = [];
|
|
96
|
+
for (const row of sourceBodyRows) {
|
|
97
|
+
const realRow = row.slice(1);
|
|
98
|
+
parts.push("\n <r>");
|
|
99
|
+
for (let i = 0; i < realRow.length; i++) {
|
|
100
|
+
parts.push("\n ");
|
|
101
|
+
parts.push(this.renderCellNew(realRow[i], cacheFields[i].sharedItems));
|
|
53
102
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
103
|
+
parts.push("\n </r>");
|
|
104
|
+
}
|
|
105
|
+
return parts.join("");
|
|
106
|
+
}
|
|
107
|
+
renderCellNew(value, sharedItems) {
|
|
108
|
+
// Handle null/undefined values first
|
|
109
|
+
if (value === null || value === undefined) {
|
|
110
|
+
return "<m />";
|
|
111
|
+
}
|
|
112
|
+
// no shared items
|
|
113
|
+
if (sharedItems === null) {
|
|
114
|
+
if (Number.isFinite(value)) {
|
|
115
|
+
return `<n v="${value}" />`;
|
|
59
116
|
}
|
|
60
|
-
|
|
61
|
-
|
|
117
|
+
return `<s v="${xmlEncode(String(value))}" />`;
|
|
118
|
+
}
|
|
119
|
+
// shared items
|
|
120
|
+
const sharedItemsIndex = sharedItems.indexOf(value);
|
|
121
|
+
if (sharedItemsIndex < 0) {
|
|
122
|
+
throw new Error(`${JSON.stringify(value)} not in sharedItems ${JSON.stringify(sharedItems)}`);
|
|
62
123
|
}
|
|
124
|
+
return `<x v="${sharedItemsIndex}" />`;
|
|
63
125
|
}
|
|
64
|
-
parseOpen(
|
|
65
|
-
|
|
66
|
-
|
|
126
|
+
parseOpen(node) {
|
|
127
|
+
const { name, attributes } = node;
|
|
128
|
+
switch (name) {
|
|
129
|
+
case this.tag:
|
|
130
|
+
// pivotCacheRecords root element
|
|
131
|
+
this.reset();
|
|
132
|
+
this.model = {
|
|
133
|
+
records: [],
|
|
134
|
+
count: parseInt(attributes.count || "0", 10),
|
|
135
|
+
isLoaded: true
|
|
136
|
+
};
|
|
137
|
+
break;
|
|
138
|
+
case "r":
|
|
139
|
+
// Start of a new record
|
|
140
|
+
this.currentRecord = [];
|
|
141
|
+
break;
|
|
142
|
+
case "x":
|
|
143
|
+
// Shared item index
|
|
144
|
+
if (this.currentRecord) {
|
|
145
|
+
this.currentRecord.push({
|
|
146
|
+
type: "x",
|
|
147
|
+
value: parseInt(attributes.v || "0", 10)
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
break;
|
|
151
|
+
case "n":
|
|
152
|
+
// Numeric value
|
|
153
|
+
if (this.currentRecord) {
|
|
154
|
+
this.currentRecord.push({
|
|
155
|
+
type: "n",
|
|
156
|
+
value: parseFloat(attributes.v || "0")
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
break;
|
|
160
|
+
case "s":
|
|
161
|
+
// String value
|
|
162
|
+
if (this.currentRecord) {
|
|
163
|
+
this.currentRecord.push({
|
|
164
|
+
type: "s",
|
|
165
|
+
value: xmlDecode(attributes.v || "")
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
break;
|
|
169
|
+
case "b":
|
|
170
|
+
// Boolean value
|
|
171
|
+
if (this.currentRecord) {
|
|
172
|
+
this.currentRecord.push({
|
|
173
|
+
type: "b",
|
|
174
|
+
value: attributes.v === "1"
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
break;
|
|
178
|
+
case "m":
|
|
179
|
+
// Missing/null value
|
|
180
|
+
if (this.currentRecord) {
|
|
181
|
+
this.currentRecord.push({ type: "m" });
|
|
182
|
+
}
|
|
183
|
+
break;
|
|
184
|
+
case "d":
|
|
185
|
+
// Date value
|
|
186
|
+
if (this.currentRecord) {
|
|
187
|
+
this.currentRecord.push({
|
|
188
|
+
type: "d",
|
|
189
|
+
value: new Date(attributes.v || "")
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
break;
|
|
193
|
+
case "e":
|
|
194
|
+
// Error value
|
|
195
|
+
if (this.currentRecord) {
|
|
196
|
+
this.currentRecord.push({
|
|
197
|
+
type: "e",
|
|
198
|
+
value: attributes.v || ""
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
break;
|
|
202
|
+
}
|
|
203
|
+
return true;
|
|
67
204
|
}
|
|
68
205
|
parseText(_text) {
|
|
69
|
-
//
|
|
206
|
+
// No text content in cache records elements
|
|
70
207
|
}
|
|
71
|
-
parseClose(
|
|
72
|
-
|
|
73
|
-
|
|
208
|
+
parseClose(name) {
|
|
209
|
+
switch (name) {
|
|
210
|
+
case this.tag:
|
|
211
|
+
// End of pivotCacheRecords
|
|
212
|
+
return false;
|
|
213
|
+
case "r":
|
|
214
|
+
// End of record - add to model
|
|
215
|
+
if (this.model && this.currentRecord) {
|
|
216
|
+
this.model.records.push(this.currentRecord);
|
|
217
|
+
this.currentRecord = null;
|
|
218
|
+
}
|
|
219
|
+
break;
|
|
220
|
+
}
|
|
221
|
+
return true;
|
|
74
222
|
}
|
|
75
223
|
reconcile(_model, _options) {
|
|
76
|
-
//
|
|
224
|
+
// No reconciliation needed
|
|
77
225
|
}
|
|
78
226
|
}
|
|
79
227
|
PivotCacheRecordsXform.PIVOT_CACHE_RECORDS_ATTRIBUTES = {
|