@coreui/data-grid 0.1.0-rc.0 → 0.2.0-rc.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 +5 -4
- package/dist/css/data-grid.css +149 -31
- package/dist/css/data-grid.css.map +1 -1
- package/dist/css/data-grid.min.css +2 -2
- package/dist/css/data-grid.min.css.map +1 -1
- package/dist/js/clipboard.cjs +56 -0
- package/dist/js/clipboard.cjs.map +1 -0
- package/dist/js/clipboard.mjs +54 -0
- package/dist/js/clipboard.mjs.map +1 -0
- package/dist/js/csv.cjs +36 -59
- package/dist/js/csv.cjs.map +1 -1
- package/dist/js/csv.mjs +35 -55
- package/dist/js/csv.mjs.map +1 -1
- package/dist/js/data-grid.esm.js +14078 -9332
- package/dist/js/data-grid.esm.js.map +1 -1
- package/dist/js/data-grid.esm.min.js +6 -6
- package/dist/js/data-grid.esm.min.js.map +1 -1
- package/dist/js/data-grid.js +14377 -9634
- package/dist/js/data-grid.js.map +1 -1
- package/dist/js/data-grid.lite.esm.js +10476 -0
- package/dist/js/data-grid.lite.esm.js.map +1 -0
- package/dist/js/data-grid.lite.esm.min.js +8 -0
- package/dist/js/data-grid.lite.esm.min.js.map +1 -0
- package/dist/js/data-grid.lite.js +10489 -0
- package/dist/js/data-grid.lite.js.map +1 -0
- package/dist/js/data-grid.lite.min.js +8 -0
- package/dist/js/data-grid.lite.min.js.map +1 -0
- package/dist/js/data-grid.lite.mjs +10476 -0
- package/dist/js/data-grid.lite.mjs.map +1 -0
- package/dist/js/data-grid.min.js +6 -6
- package/dist/js/data-grid.min.js.map +1 -1
- package/dist/js/data-grid.mjs +14078 -9332
- package/dist/js/data-grid.mjs.map +1 -1
- package/dist/js/drag.cjs +459 -0
- package/dist/js/drag.cjs.map +1 -0
- package/dist/js/drag.mjs +456 -0
- package/dist/js/drag.mjs.map +1 -0
- package/dist/js/export-table-CNAKStzj.mjs +26 -0
- package/dist/js/export-table-CNAKStzj.mjs.map +1 -0
- package/dist/js/export-table-doIwvE5U.cjs +55 -0
- package/dist/js/export-table-doIwvE5U.cjs.map +1 -0
- package/dist/js/filters.cjs +89 -132
- package/dist/js/filters.cjs.map +1 -1
- package/dist/js/filters.mjs +88 -128
- package/dist/js/filters.mjs.map +1 -1
- package/dist/js/labels.cjs +65 -70
- package/dist/js/labels.cjs.map +1 -1
- package/dist/js/labels.mjs +64 -66
- package/dist/js/labels.mjs.map +1 -1
- package/dist/js/print.cjs +66 -0
- package/dist/js/print.cjs.map +1 -0
- package/dist/js/print.mjs +64 -0
- package/dist/js/print.mjs.map +1 -0
- package/dist/js/validate.cjs +43 -0
- package/dist/js/validate.cjs.map +1 -0
- package/dist/js/validate.mjs +42 -0
- package/dist/js/validate.mjs.map +1 -0
- package/dist/js/xlsx.cjs +240 -0
- package/dist/js/xlsx.cjs.map +1 -0
- package/dist/js/xlsx.mjs +238 -0
- package/dist/js/xlsx.mjs.map +1 -0
- package/dist/types/base-component.d.ts +28 -18
- package/dist/types/data-grid.d.ts +26 -13
- package/dist/types/dom/data.d.ts +15 -0
- package/dist/types/dom/event-handler.d.ts +21 -10
- package/dist/types/dom/manipulator.d.ts +15 -8
- package/dist/types/engine/data-source.d.ts +1 -1
- package/dist/types/engine/features-lite.d.ts +25 -0
- package/dist/types/engine/features.d.ts +35 -0
- package/dist/types/engine/table.d.ts +3 -3
- package/dist/types/engine/validate.d.mts +1 -0
- package/dist/types/engine/validate.d.ts +20 -0
- package/dist/types/engine/virtualizer.d.ts +2 -0
- package/dist/types/icons.d.ts +6 -4
- package/dist/types/index-lite.d.mts +1 -0
- package/dist/types/index-lite.d.ts +19 -0
- package/dist/types/index.d.ts +11 -2
- package/dist/types/types.d.ts +53 -31
- package/dist/types/ui/body.d.ts +6 -3
- package/dist/types/ui/header.d.ts +3 -2
- package/dist/types/ui/loading.d.ts +1 -1
- package/dist/types/ui/pinning.d.ts +1 -1
- package/dist/types/ui/toolbar.d.ts +10 -2
- package/dist/types/util/clipboard.d.mts +1 -0
- package/dist/types/util/clipboard.d.ts +29 -0
- package/dist/types/util/config.d.ts +27 -10
- package/dist/types/util/csv.d.ts +5 -5
- package/dist/types/util/drag.d.mts +1 -0
- package/dist/types/util/drag.d.ts +48 -0
- package/dist/types/util/export-table.d.ts +47 -0
- package/dist/types/util/index.d.ts +66 -10
- package/dist/types/util/print.d.mts +1 -0
- package/dist/types/util/print.d.ts +32 -0
- package/dist/types/util/sanitizer.d.ts +15 -11
- package/dist/types/util/xlsx.d.mts +1 -0
- package/dist/types/util/xlsx.d.ts +17 -0
- package/dist/types/util/zip.d.ts +11 -0
- package/package.json +88 -10
- package/scss/data-grid.scss +204 -16
- package/src/{base-component.js → base-component.ts} +21 -17
- package/src/data-grid.ts +507 -200
- package/src/dom/{data.js → data.ts} +13 -10
- package/src/dom/event-handler.ts +380 -0
- package/src/dom/{manipulator.js → manipulator.ts} +11 -11
- package/src/engine/data-source.ts +7 -3
- package/src/engine/features-lite.ts +47 -0
- package/src/engine/features.ts +68 -0
- package/src/engine/table.ts +80 -47
- package/src/engine/validate.ts +64 -0
- package/src/engine/virtualizer.ts +17 -1
- package/src/icons.ts +11 -5
- package/src/index-lite.ts +85 -0
- package/src/index.ts +30 -2
- package/src/labels.ts +6 -4
- package/src/types.ts +87 -32
- package/src/ui/body.ts +73 -17
- package/src/ui/header.ts +51 -26
- package/src/ui/loading.ts +2 -2
- package/src/ui/pinning.ts +16 -16
- package/src/ui/toolbar.ts +27 -3
- package/src/util/clipboard.ts +112 -0
- package/src/util/{config.js → config.ts} +25 -11
- package/src/util/csv.ts +11 -30
- package/src/util/drag.ts +798 -0
- package/src/util/export-table.ts +86 -0
- package/src/util/{index.js → index.ts} +55 -35
- package/src/util/print.ts +125 -0
- package/src/util/{sanitizer.js → sanitizer.ts} +17 -13
- package/src/util/xlsx.ts +183 -0
- package/src/util/zip.ts +170 -0
- package/src/base-component.d.ts +0 -19
- package/src/dom/event-handler.d.ts +0 -11
- package/src/dom/event-handler.js +0 -331
- package/src/dom/manipulator.d.ts +0 -9
- package/src/util/config.d.ts +0 -11
- package/src/util/index.d.ts +0 -10
- package/src/util/sanitizer.d.ts +0 -11
package/src/util/xlsx.ts
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* --------------------------------------------------------------------------
|
|
3
|
+
* CoreUI PRO data-grid util/xlsx.ts
|
|
4
|
+
* License (https://coreui.io/pro/license/)
|
|
5
|
+
* --------------------------------------------------------------------------
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
columnsFor, formatterFor, headerFor, rowsFor, widthFor, type ExportColumn, type ExportScope, type ExportTable
|
|
10
|
+
} from './export-table'
|
|
11
|
+
import { zip, type ZipEntry } from './zip'
|
|
12
|
+
|
|
13
|
+
export interface XlsxOptions {
|
|
14
|
+
scope?: ExportScope
|
|
15
|
+
sheetName?: string
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface XlsxDownloadOptions extends XlsxOptions {
|
|
19
|
+
filename?: string
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export type XlsxTable = ExportTable
|
|
23
|
+
|
|
24
|
+
const MIME_TYPE = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
|
25
|
+
const DEFAULT_SHEET_NAME = 'Sheet1'
|
|
26
|
+
// Excel column widths count characters, not pixels: the default 8.43 width is
|
|
27
|
+
// 64 px, and each further character adds 7 px on top of the 5 px padding.
|
|
28
|
+
const PX_PER_CHARACTER = 7
|
|
29
|
+
const CELL_PADDING_PX = 5
|
|
30
|
+
const MIN_COLUMN_WIDTH = 4
|
|
31
|
+
const MAX_COLUMN_WIDTH = 120
|
|
32
|
+
|
|
33
|
+
// XML 1.0 forbids most control characters outright - Excel refuses to open a
|
|
34
|
+
// file containing them, so they are dropped rather than escaped.
|
|
35
|
+
// eslint-disable-next-line no-control-regex -- matching them is the point
|
|
36
|
+
const CONTROL_CHARACTERS = /[\u0000-\u0008\u000B\u000C\u000E-\u001F]/g
|
|
37
|
+
|
|
38
|
+
const escapeXml = (value: string): string =>
|
|
39
|
+
value
|
|
40
|
+
.replace(CONTROL_CHARACTERS, '')
|
|
41
|
+
.replace(/&/g, '&')
|
|
42
|
+
.replace(/</g, '<')
|
|
43
|
+
.replace(/>/g, '>')
|
|
44
|
+
.replace(/"/g, '"')
|
|
45
|
+
|
|
46
|
+
// A1, B1 … Z1, AA1 - Excel's bijective base-26 column reference.
|
|
47
|
+
const cellReference = (columnIndex: number, rowNumber: number): string => {
|
|
48
|
+
let reference = ''
|
|
49
|
+
let index = columnIndex
|
|
50
|
+
while (index >= 0) {
|
|
51
|
+
reference = String.fromCodePoint(65 + (index % 26)) + reference
|
|
52
|
+
index = Math.floor(index / 26) - 1
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return `${reference}${rowNumber}`
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Sheet names cannot contain : \ / ? * [ ] and cap at 31 characters.
|
|
59
|
+
const sheetNameFor = (name: string | undefined): string => {
|
|
60
|
+
const cleaned = (name ?? DEFAULT_SHEET_NAME).replace(/[:\\/?*[\]]/g, ' ').trim().slice(0, 31)
|
|
61
|
+
return cleaned.length > 0 ? cleaned : DEFAULT_SHEET_NAME
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const sheetWidthFor = (column: ExportColumn): number | null => {
|
|
65
|
+
const size = widthFor(column)
|
|
66
|
+
if (typeof size !== 'number' || !Number.isFinite(size) || size <= 0) {
|
|
67
|
+
return null
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const characters = (size - CELL_PADDING_PX) / PX_PER_CHARACTER
|
|
71
|
+
return Math.min(MAX_COLUMN_WIDTH, Math.max(MIN_COLUMN_WIDTH, Math.round(characters * 100) / 100))
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Values reach a cell as one of three Excel types. Inline strings keep the
|
|
75
|
+
// file self-contained (no shared-strings part) and are never parsed as
|
|
76
|
+
// formulas, so a leading "=" is data here, unlike in CSV.
|
|
77
|
+
const cellXml = (reference: string, value: unknown, styleIndex: number): string => {
|
|
78
|
+
const style = styleIndex > 0 ? ` s="${styleIndex}"` : ''
|
|
79
|
+
|
|
80
|
+
if (typeof value === 'number' && Number.isFinite(value)) {
|
|
81
|
+
return `<c r="${reference}"${style}><v>${value}</v></c>`
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (typeof value === 'boolean') {
|
|
85
|
+
return `<c r="${reference}"${style} t="b"><v>${value ? 1 : 0}</v></c>`
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const text = String(value ?? '')
|
|
89
|
+
if (text === '') {
|
|
90
|
+
return `<c r="${reference}"${style}/>`
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return `<c r="${reference}"${style} t="inlineStr"><is><t xml:space="preserve">${escapeXml(text)}</t></is></c>`
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const CONTENT_TYPES = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
97
|
+
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/><Override PartName="/xl/worksheets/sheet1.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/><Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/></Types>`
|
|
98
|
+
|
|
99
|
+
const ROOT_RELS = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
100
|
+
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/></Relationships>`
|
|
101
|
+
|
|
102
|
+
const WORKBOOK_RELS = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
103
|
+
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/sheet1.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/></Relationships>`
|
|
104
|
+
|
|
105
|
+
// Style 0 is the default cell, style 1 the bold header. Excel expects the two
|
|
106
|
+
// conventional fills (none, gray125) and the built-in "Normal" cell style to
|
|
107
|
+
// exist even when unused - without them readers report a missing default
|
|
108
|
+
// style and Excel offers to repair the file.
|
|
109
|
+
const STYLES = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
110
|
+
<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><fonts count="2"><font><sz val="11"/><name val="Calibri"/></font><font><b/><sz val="11"/><name val="Calibri"/></font></fonts><fills count="2"><fill><patternFill patternType="none"/></fill><fill><patternFill patternType="gray125"/></fill></fills><borders count="1"><border><left/><right/><top/><bottom/><diagonal/></border></borders><cellStyleXfs count="1"><xf numFmtId="0" fontId="0" fillId="0" borderId="0"/></cellStyleXfs><cellXfs count="2"><xf numFmtId="0" fontId="0" fillId="0" borderId="0" xfId="0"/><xf numFmtId="0" fontId="1" fillId="0" borderId="0" xfId="0" applyFont="1"/></cellXfs><cellStyles count="1"><cellStyle name="Normal" xfId="0" builtinId="0"/></cellStyles></styleSheet>`
|
|
111
|
+
|
|
112
|
+
const workbookXml = (sheetName: string): string =>
|
|
113
|
+
`<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
114
|
+
<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"><sheets><sheet name="${escapeXml(sheetName)}" sheetId="1" r:id="rId1"/></sheets></workbook>`
|
|
115
|
+
|
|
116
|
+
const worksheetXml = (table: XlsxTable, options: XlsxOptions): string => {
|
|
117
|
+
const columns = columnsFor(table)
|
|
118
|
+
const rows = rowsFor(table, options.scope)
|
|
119
|
+
|
|
120
|
+
const widths = columns
|
|
121
|
+
.map((column, index) => {
|
|
122
|
+
const width = sheetWidthFor(column)
|
|
123
|
+
return width === null ?
|
|
124
|
+
null :
|
|
125
|
+
`<col min="${index + 1}" max="${index + 1}" width="${width}" customWidth="1"/>`
|
|
126
|
+
})
|
|
127
|
+
.filter((entry): entry is string => entry !== null)
|
|
128
|
+
const cols = widths.length > 0 ? `<cols>${widths.join('')}</cols>` : ''
|
|
129
|
+
|
|
130
|
+
const headerCells = columns
|
|
131
|
+
.map((column, index) => cellXml(cellReference(index, 1), headerFor(column), 1))
|
|
132
|
+
.join('')
|
|
133
|
+
|
|
134
|
+
const bodyRows = rows.map((row, rowIndex) => {
|
|
135
|
+
const rowNumber = rowIndex + 2
|
|
136
|
+
const cells = columns
|
|
137
|
+
.map((column, columnIndex) => {
|
|
138
|
+
const value = row.getValue(column.id)
|
|
139
|
+
const formatter = formatterFor(column)
|
|
140
|
+
// A formatted value is text by definition; an unformatted one keeps
|
|
141
|
+
// its native type so numbers stay numeric in Excel.
|
|
142
|
+
return cellXml(
|
|
143
|
+
cellReference(columnIndex, rowNumber),
|
|
144
|
+
formatter ? formatter(value, row.original) ?? '' : value,
|
|
145
|
+
0
|
|
146
|
+
)
|
|
147
|
+
})
|
|
148
|
+
.join('')
|
|
149
|
+
return `<row r="${rowNumber}">${cells}</row>`
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
153
|
+
<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">${cols}<sheetData><row r="1">${headerCells}</row>${bodyRows.join('')}</sheetData></worksheet>`
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export const exportXlsx = (table: XlsxTable, options: XlsxOptions = {}): Uint8Array => {
|
|
157
|
+
const encoder = new TextEncoder()
|
|
158
|
+
const sheetName = sheetNameFor(options.sheetName)
|
|
159
|
+
const entries: ZipEntry[] = [
|
|
160
|
+
{ name: '[Content_Types].xml', data: encoder.encode(CONTENT_TYPES) },
|
|
161
|
+
{ name: '_rels/.rels', data: encoder.encode(ROOT_RELS) },
|
|
162
|
+
{ name: 'xl/workbook.xml', data: encoder.encode(workbookXml(sheetName)) },
|
|
163
|
+
{ name: 'xl/_rels/workbook.xml.rels', data: encoder.encode(WORKBOOK_RELS) },
|
|
164
|
+
{ name: 'xl/styles.xml', data: encoder.encode(STYLES) },
|
|
165
|
+
{ name: 'xl/worksheets/sheet1.xml', data: encoder.encode(worksheetXml(table, options)) }
|
|
166
|
+
]
|
|
167
|
+
|
|
168
|
+
return zip(entries)
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export const downloadXlsx = (table: XlsxTable, options: XlsxDownloadOptions = {}): void => {
|
|
172
|
+
const blob = new Blob([exportXlsx(table, options) as BlobPart], { type: MIME_TYPE })
|
|
173
|
+
const url = URL.createObjectURL(blob)
|
|
174
|
+
const anchor = document.createElement('a')
|
|
175
|
+
anchor.href = url
|
|
176
|
+
anchor.download = options.filename ?? 'export.xlsx'
|
|
177
|
+
anchor.style.display = 'none'
|
|
178
|
+
// Attach before clicking (older Firefox) and defer revoke (Safari race).
|
|
179
|
+
document.body.append(anchor)
|
|
180
|
+
anchor.click()
|
|
181
|
+
anchor.remove()
|
|
182
|
+
setTimeout(() => URL.revokeObjectURL(url))
|
|
183
|
+
}
|
package/src/util/zip.ts
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* --------------------------------------------------------------------------
|
|
3
|
+
* CoreUI PRO data-grid util/zip.ts
|
|
4
|
+
* License (https://coreui.io/pro/license/)
|
|
5
|
+
* --------------------------------------------------------------------------
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/* eslint-disable no-bitwise -- CRC32 and the ZIP header fields are defined
|
|
9
|
+
in bit terms; expressing them any other way would obscure the format. */
|
|
10
|
+
|
|
11
|
+
// A minimal ZIP writer for the xlsx export. Entries are STORED (uncompressed),
|
|
12
|
+
// which the format allows and which keeps the writer dependency-free - an
|
|
13
|
+
// export of a few thousand rows is XML text the browser hands straight to a
|
|
14
|
+
// download, so the deflate round-trip would buy little. Timestamps are fixed
|
|
15
|
+
// at the DOS epoch so the same data always produces the same bytes.
|
|
16
|
+
|
|
17
|
+
const DOS_EPOCH_TIME = 0
|
|
18
|
+
const DOS_EPOCH_DATE = 0x0021
|
|
19
|
+
// UTF-8 filename bit; every name we write is ASCII, but the flag is correct
|
|
20
|
+
// and costs nothing.
|
|
21
|
+
const FLAG_UTF8 = 0x0800
|
|
22
|
+
|
|
23
|
+
let crcTable: Uint32Array | null = null
|
|
24
|
+
|
|
25
|
+
const getCrcTable = (): Uint32Array => {
|
|
26
|
+
if (crcTable) {
|
|
27
|
+
return crcTable
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const table = new Uint32Array(256)
|
|
31
|
+
for (let index = 0; index < 256; index++) {
|
|
32
|
+
let value = index
|
|
33
|
+
for (let bit = 0; bit < 8; bit++) {
|
|
34
|
+
value = value & 1 ? 0xED_B8_83_20 ^ (value >>> 1) : value >>> 1
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
table[index] = value >>> 0
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
crcTable = table
|
|
41
|
+
return table
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const crc32 = (bytes: Uint8Array): number => {
|
|
45
|
+
const table = getCrcTable()
|
|
46
|
+
let crc = 0xFF_FF_FF_FF
|
|
47
|
+
for (const byte of bytes) {
|
|
48
|
+
crc = table[(crc ^ byte) & 0xFF]! ^ (crc >>> 8)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return (crc ^ 0xFF_FF_FF_FF) >>> 0
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface ZipEntry {
|
|
55
|
+
name: string
|
|
56
|
+
data: Uint8Array
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
interface StagedEntry extends ZipEntry {
|
|
60
|
+
crc: number
|
|
61
|
+
nameBytes: Uint8Array
|
|
62
|
+
offset: number
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const LOCAL_HEADER_SIZE = 30
|
|
66
|
+
const CENTRAL_HEADER_SIZE = 46
|
|
67
|
+
const END_RECORD_SIZE = 22
|
|
68
|
+
|
|
69
|
+
class ByteWriter {
|
|
70
|
+
private readonly view: DataView
|
|
71
|
+
private readonly bytes: Uint8Array
|
|
72
|
+
private cursor = 0
|
|
73
|
+
|
|
74
|
+
constructor(size: number) {
|
|
75
|
+
this.bytes = new Uint8Array(size)
|
|
76
|
+
this.view = new DataView(this.bytes.buffer)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
u16(value: number): void {
|
|
80
|
+
this.view.setUint16(this.cursor, value, true)
|
|
81
|
+
this.cursor += 2
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
u32(value: number): void {
|
|
85
|
+
this.view.setUint32(this.cursor, value, true)
|
|
86
|
+
this.cursor += 4
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
raw(value: Uint8Array): void {
|
|
90
|
+
this.bytes.set(value, this.cursor)
|
|
91
|
+
this.cursor += value.length
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
result(): Uint8Array {
|
|
95
|
+
return this.bytes
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export const zip = (entries: ZipEntry[]): Uint8Array => {
|
|
100
|
+
const encoder = new TextEncoder()
|
|
101
|
+
const staged: StagedEntry[] = []
|
|
102
|
+
let offset = 0
|
|
103
|
+
|
|
104
|
+
for (const entry of entries) {
|
|
105
|
+
const nameBytes = encoder.encode(entry.name)
|
|
106
|
+
staged.push({
|
|
107
|
+
...entry,
|
|
108
|
+
crc: crc32(entry.data),
|
|
109
|
+
nameBytes,
|
|
110
|
+
offset
|
|
111
|
+
})
|
|
112
|
+
offset += LOCAL_HEADER_SIZE + nameBytes.length + entry.data.length
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const centralDirectoryOffset = offset
|
|
116
|
+
const centralDirectorySize = staged.reduce(
|
|
117
|
+
(total, entry) => total + CENTRAL_HEADER_SIZE + entry.nameBytes.length,
|
|
118
|
+
0
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
const writer = new ByteWriter(centralDirectoryOffset + centralDirectorySize + END_RECORD_SIZE)
|
|
122
|
+
|
|
123
|
+
for (const entry of staged) {
|
|
124
|
+
writer.u32(0x04_03_4B_50)
|
|
125
|
+
writer.u16(20)
|
|
126
|
+
writer.u16(FLAG_UTF8)
|
|
127
|
+
writer.u16(0)
|
|
128
|
+
writer.u16(DOS_EPOCH_TIME)
|
|
129
|
+
writer.u16(DOS_EPOCH_DATE)
|
|
130
|
+
writer.u32(entry.crc)
|
|
131
|
+
writer.u32(entry.data.length)
|
|
132
|
+
writer.u32(entry.data.length)
|
|
133
|
+
writer.u16(entry.nameBytes.length)
|
|
134
|
+
writer.u16(0)
|
|
135
|
+
writer.raw(entry.nameBytes)
|
|
136
|
+
writer.raw(entry.data)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
for (const entry of staged) {
|
|
140
|
+
writer.u32(0x02_01_4B_50)
|
|
141
|
+
writer.u16(20)
|
|
142
|
+
writer.u16(20)
|
|
143
|
+
writer.u16(FLAG_UTF8)
|
|
144
|
+
writer.u16(0)
|
|
145
|
+
writer.u16(DOS_EPOCH_TIME)
|
|
146
|
+
writer.u16(DOS_EPOCH_DATE)
|
|
147
|
+
writer.u32(entry.crc)
|
|
148
|
+
writer.u32(entry.data.length)
|
|
149
|
+
writer.u32(entry.data.length)
|
|
150
|
+
writer.u16(entry.nameBytes.length)
|
|
151
|
+
writer.u16(0)
|
|
152
|
+
writer.u16(0)
|
|
153
|
+
writer.u16(0)
|
|
154
|
+
writer.u16(0)
|
|
155
|
+
writer.u32(0)
|
|
156
|
+
writer.u32(entry.offset)
|
|
157
|
+
writer.raw(entry.nameBytes)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
writer.u32(0x06_05_4B_50)
|
|
161
|
+
writer.u16(0)
|
|
162
|
+
writer.u16(0)
|
|
163
|
+
writer.u16(staged.length)
|
|
164
|
+
writer.u16(staged.length)
|
|
165
|
+
writer.u32(centralDirectorySize)
|
|
166
|
+
writer.u32(centralDirectoryOffset)
|
|
167
|
+
writer.u16(0)
|
|
168
|
+
|
|
169
|
+
return writer.result()
|
|
170
|
+
}
|
package/src/base-component.d.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
// Hand-written types for the vendored base-component.js (see the provenance header there)
|
|
2
|
-
import Config from './util/config.js'
|
|
3
|
-
|
|
4
|
-
export default class BaseComponent extends Config {
|
|
5
|
-
constructor(element: Element | string, config?: unknown)
|
|
6
|
-
|
|
7
|
-
_element: HTMLElement
|
|
8
|
-
_config: any
|
|
9
|
-
|
|
10
|
-
dispose(): void
|
|
11
|
-
_queueCallback(callback: () => void, element: Element, isAnimated?: boolean): void
|
|
12
|
-
|
|
13
|
-
static getInstance(element: Element | string | null): any
|
|
14
|
-
static getOrCreateInstance(element: Element | string, config?: unknown): any
|
|
15
|
-
static get VERSION(): string
|
|
16
|
-
static get DATA_KEY(): string
|
|
17
|
-
static get EVENT_KEY(): string
|
|
18
|
-
static eventName(name: string): string
|
|
19
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
// Hand-written types for the vendored event-handler.js (see the provenance header there)
|
|
2
|
-
type EventHandlerFunction = (event: Event & Record<string, unknown>) => void
|
|
3
|
-
|
|
4
|
-
declare const EventHandler: {
|
|
5
|
-
on(element: Element | Document | Window, event: string, handler: string | EventHandlerFunction, delegationFunction?: EventHandlerFunction): void
|
|
6
|
-
one(element: Element | Document | Window, event: string, handler: string | EventHandlerFunction, delegationFunction?: EventHandlerFunction): void
|
|
7
|
-
off(element: Element | Document | Window, originalTypeEvent: string, handler?: string | EventHandlerFunction, delegationFunction?: EventHandlerFunction): void
|
|
8
|
-
trigger(element: Element | Document | Window, event: string, args?: Record<string, unknown>): (Event & Record<string, unknown>) | null
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export default EventHandler
|