@willwade/aac-processors 0.1.20 → 0.1.21
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/core/baseProcessor.js +4 -0
- package/dist/browser/processors/applePanelsProcessor.js +24 -31
- package/dist/browser/processors/astericsGridProcessor.js +10 -3
- package/dist/browser/processors/dotProcessor.js +5 -2
- package/dist/browser/processors/gridset/colorUtils.js +354 -0
- package/dist/browser/processors/gridset/helpers.js +49 -45
- package/dist/browser/processors/gridset/index.js +61 -0
- package/dist/browser/processors/gridset/styleHelpers.js +205 -0
- package/dist/browser/processors/gridset/symbolExtractor.js +331 -0
- package/dist/browser/processors/gridset/symbolSearch.js +248 -0
- package/dist/browser/processors/gridset/symbols.js +35 -68
- package/dist/browser/processors/gridsetProcessor.js +32 -41
- package/dist/browser/processors/obfProcessor.js +20 -33
- package/dist/browser/processors/opmlProcessor.js +5 -2
- package/dist/browser/processors/snap/helpers.js +49 -45
- package/dist/browser/processors/snapProcessor.js +39 -42
- package/dist/browser/processors/touchchatProcessor.js +54 -45
- package/dist/browser/utilities/analytics/reference/index.js +27 -19
- package/dist/browser/utils/io.js +67 -14
- package/dist/browser/utils/sqlite.js +6 -8
- package/dist/browser/utils/zip.js +45 -43
- package/dist/browser/validation/baseValidator.js +5 -0
- package/dist/browser/validation/gridsetValidator.js +12 -20
- package/dist/browser/validation/obfValidator.js +5 -4
- package/dist/browser/validation/snapValidator.js +9 -5
- package/dist/browser/validation/touchChatValidator.js +21 -11
- package/dist/cli/index.js +10 -15
- package/dist/core/baseProcessor.d.ts +7 -7
- package/dist/core/baseProcessor.js +4 -0
- package/dist/processors/applePanelsProcessor.js +29 -36
- package/dist/processors/astericsGridProcessor.js +20 -13
- package/dist/processors/dotProcessor.js +10 -7
- package/dist/processors/excelProcessor.js +9 -12
- package/dist/processors/gridset/helpers.d.ts +9 -11
- package/dist/processors/gridset/helpers.js +49 -71
- package/dist/processors/gridset/imageDebug.d.ts +3 -5
- package/dist/processors/gridset/imageDebug.js +4 -4
- package/dist/processors/gridset/password.d.ts +1 -1
- package/dist/processors/gridset/symbolExtractor.d.ts +5 -3
- package/dist/processors/gridset/symbolExtractor.js +15 -38
- package/dist/processors/gridset/symbolSearch.d.ts +3 -2
- package/dist/processors/gridset/symbolSearch.js +12 -34
- package/dist/processors/gridset/symbols.d.ts +8 -6
- package/dist/processors/gridset/symbols.js +34 -67
- package/dist/processors/gridset/wordlistHelpers.d.ts +4 -6
- package/dist/processors/gridset/wordlistHelpers.js +15 -74
- package/dist/processors/gridsetProcessor.js +36 -68
- package/dist/processors/obfProcessor.js +26 -62
- package/dist/processors/obfsetProcessor.js +2 -2
- package/dist/processors/opmlProcessor.js +10 -7
- package/dist/processors/snap/helpers.d.ts +8 -8
- package/dist/processors/snap/helpers.js +50 -72
- package/dist/processors/snapProcessor.js +38 -41
- package/dist/processors/touchchatProcessor.js +54 -45
- package/dist/utilities/analytics/index.d.ts +3 -2
- package/dist/utilities/analytics/index.js +8 -10
- package/dist/utilities/analytics/reference/index.d.ts +5 -3
- package/dist/utilities/analytics/reference/index.js +26 -18
- package/dist/utilities/symbolTools.d.ts +4 -2
- package/dist/utilities/symbolTools.js +16 -15
- package/dist/utils/io.d.ts +24 -6
- package/dist/utils/io.js +64 -14
- package/dist/utils/sqlite.d.ts +2 -0
- package/dist/utils/sqlite.js +6 -8
- package/dist/utils/zip.d.ts +7 -3
- package/dist/utils/zip.js +45 -43
- package/dist/validation/applePanelsValidator.d.ts +2 -1
- package/dist/validation/applePanelsValidator.js +9 -11
- package/dist/validation/astericsValidator.d.ts +2 -1
- package/dist/validation/astericsValidator.js +5 -4
- package/dist/validation/baseValidator.d.ts +2 -2
- package/dist/validation/baseValidator.js +5 -0
- package/dist/validation/dotValidator.d.ts +2 -1
- package/dist/validation/dotValidator.js +5 -4
- package/dist/validation/excelValidator.d.ts +2 -1
- package/dist/validation/excelValidator.js +5 -4
- package/dist/validation/gridsetValidator.d.ts +2 -1
- package/dist/validation/gridsetValidator.js +11 -22
- package/dist/validation/index.d.ts +2 -2
- package/dist/validation/index.js +5 -4
- package/dist/validation/obfValidator.d.ts +2 -1
- package/dist/validation/obfValidator.js +5 -4
- package/dist/validation/obfsetValidator.d.ts +2 -1
- package/dist/validation/obfsetValidator.js +5 -4
- package/dist/validation/opmlValidator.d.ts +2 -1
- package/dist/validation/opmlValidator.js +5 -4
- package/dist/validation/snapValidator.d.ts +2 -1
- package/dist/validation/snapValidator.js +9 -5
- package/dist/validation/touchChatValidator.d.ts +4 -6
- package/dist/validation/touchChatValidator.js +21 -11
- package/dist/validation/validationTypes.d.ts +8 -1
- package/package.json +1 -1
- package/dist/core/fileProcessor.d.ts +0 -7
- package/dist/core/fileProcessor.js +0 -57
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { XMLBuilder } from 'fast-xml-parser';
|
|
2
2
|
import { AACSemanticCategory, AACSemanticIntent, } from '../../core/treeStructure';
|
|
3
|
-
import * as fs from 'fs';
|
|
4
|
-
import * as path from 'path';
|
|
5
|
-
import { execSync } from 'child_process';
|
|
6
|
-
import Database from 'better-sqlite3';
|
|
7
3
|
import { dotNetTicksToDate } from '../../utils/dotnetTicks';
|
|
8
4
|
import { getZipEntriesFromAdapter, resolveGridsetPasswordFromEnv } from './password';
|
|
9
|
-
import {
|
|
5
|
+
import { defaultFileAdapter, extname, getNodeRequire, joinWin32, } from '../../utils/io';
|
|
6
|
+
import { getZipAdapter } from '../../utils/zip';
|
|
7
|
+
import { requireBetterSqlite3 } from '../../utils/sqlite';
|
|
10
8
|
function normalizeZipPath(p) {
|
|
11
9
|
const unified = p.replace(/\\/g, '/');
|
|
12
10
|
try {
|
|
@@ -52,11 +50,11 @@ export function getAllowedImageEntries(tree) {
|
|
|
52
50
|
* @param entryPath Entry name inside the zip
|
|
53
51
|
* @returns Image data buffer or null if not found
|
|
54
52
|
*/
|
|
55
|
-
export async function openImage(gridsetBuffer, entryPath, password = resolveGridsetPasswordFromEnv(), zipAdapter) {
|
|
53
|
+
export async function openImage(gridsetBuffer, entryPath, password = resolveGridsetPasswordFromEnv(), fileAdapter = defaultFileAdapter, zipAdapter) {
|
|
56
54
|
try {
|
|
57
|
-
const
|
|
55
|
+
const zip = zipAdapter
|
|
58
56
|
? await zipAdapter(gridsetBuffer)
|
|
59
|
-
: await
|
|
57
|
+
: await getZipAdapter(gridsetBuffer, fileAdapter);
|
|
60
58
|
const entries = getZipEntriesFromAdapter(zip, password);
|
|
61
59
|
const want = normalizeZipPath(entryPath);
|
|
62
60
|
const entry = entries.find((e) => normalizeZipPath(e.entryName) === want);
|
|
@@ -149,8 +147,9 @@ export function getCommonDocumentsPath() {
|
|
|
149
147
|
}
|
|
150
148
|
try {
|
|
151
149
|
// Query registry for Common Documents path
|
|
150
|
+
const child_process = getNodeRequire()('child_process');
|
|
152
151
|
const command = 'REG.EXE QUERY "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders" /V "Common Documents"';
|
|
153
|
-
const output = execSync(command, { encoding: 'utf-8', windowsHide: true });
|
|
152
|
+
const output = child_process.execSync(command, { encoding: 'utf-8', windowsHide: true });
|
|
154
153
|
// Parse the output to extract the path
|
|
155
154
|
const match = output.match(/Common Documents\s+REG_SZ\s+(.+)/);
|
|
156
155
|
if (match && match[1]) {
|
|
@@ -171,7 +170,8 @@ export function getCommonDocumentsPath() {
|
|
|
171
170
|
* C:\Users\Public\Documents\Smartbox\Grid 3\Users\{UserName}\Grid Sets\
|
|
172
171
|
* @returns Array of Grid3 user path information
|
|
173
172
|
*/
|
|
174
|
-
export function findGrid3UserPaths() {
|
|
173
|
+
export function findGrid3UserPaths(fileAdapter = defaultFileAdapter) {
|
|
174
|
+
const { pathExists, listDir, isDirectory } = fileAdapter;
|
|
175
175
|
const results = [];
|
|
176
176
|
// Only works on Windows
|
|
177
177
|
if (process.platform !== 'win32') {
|
|
@@ -180,28 +180,28 @@ export function findGrid3UserPaths() {
|
|
|
180
180
|
try {
|
|
181
181
|
const commonDocs = getCommonDocumentsPath();
|
|
182
182
|
// Use Windows path joining so tests that mock a Windows platform stay consistent even on POSIX runners
|
|
183
|
-
const grid3BasePath =
|
|
183
|
+
const grid3BasePath = joinWin32(commonDocs, 'Smartbox', 'Grid 3', 'Users');
|
|
184
184
|
// Check if Grid3 Users directory exists
|
|
185
|
-
if (!
|
|
185
|
+
if (!pathExists(grid3BasePath)) {
|
|
186
186
|
return results;
|
|
187
187
|
}
|
|
188
188
|
// Enumerate users
|
|
189
|
-
const users =
|
|
189
|
+
const users = listDir(grid3BasePath);
|
|
190
190
|
for (const userDir of users) {
|
|
191
|
-
if (!
|
|
191
|
+
if (!isDirectory(userDir))
|
|
192
192
|
continue;
|
|
193
|
-
const userName = userDir
|
|
194
|
-
const userPath =
|
|
193
|
+
const userName = userDir;
|
|
194
|
+
const userPath = joinWin32(grid3BasePath, userName);
|
|
195
195
|
// Enumerate language codes
|
|
196
|
-
const langDirs =
|
|
196
|
+
const langDirs = listDir(userPath);
|
|
197
197
|
for (const langDir of langDirs) {
|
|
198
|
-
if (!
|
|
198
|
+
if (!isDirectory(langDir))
|
|
199
199
|
continue;
|
|
200
|
-
const langCode = langDir
|
|
201
|
-
const basePath =
|
|
202
|
-
const historyDbPath =
|
|
200
|
+
const langCode = langDir;
|
|
201
|
+
const basePath = joinWin32(userPath, langCode);
|
|
202
|
+
const historyDbPath = joinWin32(basePath, 'Phrases', 'history.sqlite');
|
|
203
203
|
// Only include if history database exists
|
|
204
|
-
if (
|
|
204
|
+
if (pathExists(historyDbPath)) {
|
|
205
205
|
results.push({
|
|
206
206
|
userName,
|
|
207
207
|
langCode,
|
|
@@ -222,8 +222,8 @@ export function findGrid3UserPaths() {
|
|
|
222
222
|
* Convenience method that returns just the database file paths
|
|
223
223
|
* @returns Array of paths to history.sqlite files
|
|
224
224
|
*/
|
|
225
|
-
export function findGrid3HistoryDatabases() {
|
|
226
|
-
return findGrid3UserPaths().map((userPath) => userPath.historyDbPath);
|
|
225
|
+
export function findGrid3HistoryDatabases(fileAdapter) {
|
|
226
|
+
return findGrid3UserPaths(fileAdapter).map((userPath) => userPath.historyDbPath);
|
|
227
227
|
}
|
|
228
228
|
/**
|
|
229
229
|
* Get Grid 3 users (alias of findGrid3UserPaths for clarity)
|
|
@@ -236,36 +236,37 @@ export function findGrid3Users() {
|
|
|
236
236
|
* @param userName Optional user filter; matches case-insensitively
|
|
237
237
|
* @returns Array of user/gridset path pairs
|
|
238
238
|
*/
|
|
239
|
-
export function findGrid3Vocabularies(userName) {
|
|
239
|
+
export function findGrid3Vocabularies(userName, fileAdapter = defaultFileAdapter) {
|
|
240
|
+
const { pathExists, listDir, isDirectory } = fileAdapter;
|
|
240
241
|
const results = [];
|
|
241
242
|
if (process.platform !== 'win32') {
|
|
242
243
|
return results;
|
|
243
244
|
}
|
|
244
245
|
const commonDocs = getCommonDocumentsPath();
|
|
245
|
-
const grid3BasePath =
|
|
246
|
-
if (!
|
|
246
|
+
const grid3BasePath = joinWin32(commonDocs, 'Smartbox', 'Grid 3', 'Users');
|
|
247
|
+
if (!pathExists(grid3BasePath)) {
|
|
247
248
|
return results;
|
|
248
249
|
}
|
|
249
250
|
const normalizedUser = userName?.toLowerCase();
|
|
250
|
-
const users =
|
|
251
|
+
const users = listDir(grid3BasePath);
|
|
251
252
|
for (const userDir of users) {
|
|
252
|
-
if (!
|
|
253
|
+
if (!isDirectory(userDir))
|
|
253
254
|
continue;
|
|
254
|
-
if (normalizedUser && userDir.
|
|
255
|
+
if (normalizedUser && userDir.toLowerCase() !== normalizedUser)
|
|
255
256
|
continue;
|
|
256
|
-
const userRoot =
|
|
257
|
-
const gridSetsDir =
|
|
258
|
-
if (!
|
|
257
|
+
const userRoot = joinWin32(grid3BasePath, userDir);
|
|
258
|
+
const gridSetsDir = joinWin32(userRoot, 'Grid Sets');
|
|
259
|
+
if (!pathExists(gridSetsDir))
|
|
259
260
|
continue;
|
|
260
|
-
const entries =
|
|
261
|
+
const entries = listDir(gridSetsDir);
|
|
261
262
|
for (const entry of entries) {
|
|
262
|
-
if (!entry
|
|
263
|
+
if (!pathExists(entry) || isDirectory(entry))
|
|
263
264
|
continue;
|
|
264
|
-
const ext =
|
|
265
|
+
const ext = extname(entry).toLowerCase();
|
|
265
266
|
if (ext === '.gridset' || ext === '.gridsetx' || ext === '.grd' || ext === '.grdl') {
|
|
266
267
|
results.push({
|
|
267
|
-
userName: userDir
|
|
268
|
-
gridsetPath:
|
|
268
|
+
userName: userDir,
|
|
269
|
+
gridsetPath: joinWin32(gridSetsDir, entry),
|
|
269
270
|
});
|
|
270
271
|
}
|
|
271
272
|
}
|
|
@@ -278,26 +279,27 @@ export function findGrid3Vocabularies(userName) {
|
|
|
278
279
|
* @param langCode Optional language code filter (case-insensitive)
|
|
279
280
|
* @returns Path to history.sqlite or null if not found
|
|
280
281
|
*/
|
|
281
|
-
export function findGrid3UserHistory(userName, langCode) {
|
|
282
|
+
export function findGrid3UserHistory(userName, langCode, fileAdapter) {
|
|
282
283
|
if (!userName)
|
|
283
284
|
return null;
|
|
284
285
|
const normalizedUser = userName.toLowerCase();
|
|
285
286
|
const normalizedLang = langCode?.toLowerCase();
|
|
286
|
-
const match = findGrid3UserPaths().find((u) => u.userName.toLowerCase() === normalizedUser &&
|
|
287
|
+
const match = findGrid3UserPaths(fileAdapter).find((u) => u.userName.toLowerCase() === normalizedUser &&
|
|
287
288
|
(!normalizedLang || u.langCode.toLowerCase() === normalizedLang));
|
|
288
289
|
return match?.historyDbPath ?? null;
|
|
289
290
|
}
|
|
290
291
|
/**
|
|
291
292
|
* Check whether Grid 3 appears to be installed (Windows only)
|
|
292
293
|
*/
|
|
293
|
-
export function isGrid3Installed() {
|
|
294
|
+
export function isGrid3Installed(fileAdapter = defaultFileAdapter) {
|
|
295
|
+
const { pathExists } = fileAdapter;
|
|
294
296
|
if (process.platform !== 'win32')
|
|
295
297
|
return false;
|
|
296
298
|
const commonDocs = getCommonDocumentsPath();
|
|
297
299
|
if (!commonDocs)
|
|
298
300
|
return false;
|
|
299
|
-
const grid3BasePath =
|
|
300
|
-
return
|
|
301
|
+
const grid3BasePath = joinWin32(commonDocs, 'Smartbox', 'Grid 3', 'Users');
|
|
302
|
+
return pathExists(grid3BasePath);
|
|
301
303
|
}
|
|
302
304
|
function parseGrid3ContentXml(xmlContent) {
|
|
303
305
|
const regex = /<r>(?:<!\[CDATA\[)?(.*?)(?:\]\]>)?<\/r>/gis;
|
|
@@ -316,9 +318,11 @@ function parseGrid3ContentXml(xmlContent) {
|
|
|
316
318
|
* @param historyDbPath Absolute path to the history database
|
|
317
319
|
* @returns Parsed history entries grouped by phrase
|
|
318
320
|
*/
|
|
319
|
-
export function readGrid3History(historyDbPath) {
|
|
320
|
-
|
|
321
|
+
export function readGrid3History(historyDbPath, fileAdapter = defaultFileAdapter) {
|
|
322
|
+
const { pathExists } = fileAdapter;
|
|
323
|
+
if (!pathExists(historyDbPath))
|
|
321
324
|
return [];
|
|
325
|
+
const Database = requireBetterSqlite3();
|
|
322
326
|
const db = new Database(historyDbPath, { readonly: true });
|
|
323
327
|
const rows = db
|
|
324
328
|
.prepare(`
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Grid 3 Enhanced Support Module
|
|
3
|
+
*
|
|
4
|
+
* This module exports all enhanced Grid 3 functionality including:
|
|
5
|
+
* - Cell shape detection and support
|
|
6
|
+
* - Plugin cell type detection (Workspace, LiveCell, AutoContent)
|
|
7
|
+
* - Comprehensive command definitions and detection
|
|
8
|
+
* - Color utilities and style helpers
|
|
9
|
+
* - Image resolution helpers
|
|
10
|
+
*/
|
|
11
|
+
// Style helpers
|
|
12
|
+
export { CellBackgroundShape, SHAPE_NAMES, DEFAULT_GRID3_STYLES, CATEGORY_STYLES, createDefaultStylesXml, createCategoryStyle, } from './styleHelpers';
|
|
13
|
+
// Plugin cell type detection
|
|
14
|
+
export { detectPluginCellType, Grid3CellType, WORKSPACE_TYPES, LIVECELL_TYPES, AUTOCONTENT_TYPES, getCellTypeDisplayName, isWorkspaceCell, isLiveCell, isAutoContentCell, isRegularCell, } from './pluginTypes';
|
|
15
|
+
// Command definitions and detection
|
|
16
|
+
export { detectCommand, getCommandDefinition, getCommandsByPlugin, getCommandsByCategory, getAllCommandIds, getAllPluginIds, extractCommandParameters, GRID3_COMMANDS, Grid3CommandCategory, } from './commands';
|
|
17
|
+
// Import for local use in constant definitions
|
|
18
|
+
import { getAllCommandIds, getAllPluginIds } from './commands';
|
|
19
|
+
import { CellBackgroundShape } from './styleHelpers';
|
|
20
|
+
import { Grid3CellType } from './pluginTypes';
|
|
21
|
+
import { Grid3CommandCategory } from './commands';
|
|
22
|
+
// Color utilities
|
|
23
|
+
export { ensureAlphaChannel, darkenColor, lightenColor, hexToRgba, rgbaToHex } from './colorUtils';
|
|
24
|
+
// Password handling
|
|
25
|
+
export { resolveGridsetPassword, getZipEntriesWithPassword, getZipEntriesFromAdapter, resolveGridsetPasswordFromEnv, } from './password';
|
|
26
|
+
// Helper functions
|
|
27
|
+
export { getPageTokenImageMap, getAllowedImageEntries, openImage, generateGrid3Guid, createSettingsXml, createFileMapXml, getCommonDocumentsPath, findGrid3UserPaths, findGrid3HistoryDatabases, findGrid3Vocabularies, findGrid3UserHistory, findGrid3Users, isGrid3Installed, readGrid3History, readGrid3HistoryForUser, readAllGrid3History, } from './helpers';
|
|
28
|
+
// Symbol library handling
|
|
29
|
+
export { parseSymbolReference, isSymbolReference, resolveSymbolReference, getAvailableSymbolLibraries, getSymbolLibraryInfo, extractSymbolReferences, analyzeSymbolUsage, createSymbolReference, getSymbolLibraryName, getSymbolPath, isKnownSymbolLibrary, getSymbolLibraryDisplayName, getDefaultGrid3Path, getSymbolLibrariesDir, getSymbolSearchIndexesDir, symbolReferenceToFilename, SYMBOL_LIBRARIES, } from './symbols';
|
|
30
|
+
// Backward compatibility aliases for old function names
|
|
31
|
+
export { getSymbolsDir, getSymbolSearchDir } from './symbols';
|
|
32
|
+
// Image resolution
|
|
33
|
+
export { resolveGrid3CellImage, isSymbolLibraryReference, parseImageSymbolReference, } from './resolver';
|
|
34
|
+
// Symbol extraction and conversion
|
|
35
|
+
export { extractButtonImage, extractSymbolLibraryImage, convertToAstericsImage, analyzeSymbolExtraction, suggestExtractionStrategy, exportSymbolReferencesToCsv, createSymbolManifest, } from './symbolExtractor';
|
|
36
|
+
// Symbol search functionality
|
|
37
|
+
export { parsePixFile, loadSearchIndexes, searchSymbols, searchSymbolsWithReferences, getSymbolFilename, getSymbolDisplayName, getAllSearchTerms, getSearchSuggestions, countLibrarySymbols, getSymbolSearchStats, } from './symbolSearch';
|
|
38
|
+
/**
|
|
39
|
+
* Get all Grid 3 command IDs as a readonly array
|
|
40
|
+
* Useful for validation and autocomplete
|
|
41
|
+
*/
|
|
42
|
+
export const GRID3_COMMAND_IDS = Object.freeze(getAllCommandIds());
|
|
43
|
+
/**
|
|
44
|
+
* Get all Grid 3 plugin IDs as a readonly array
|
|
45
|
+
*/
|
|
46
|
+
export const GRID3_PLUGIN_IDS = Object.freeze(getAllPluginIds());
|
|
47
|
+
/**
|
|
48
|
+
* Grid 3 cell shapes enum values
|
|
49
|
+
*/
|
|
50
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
51
|
+
export const GRID3_CELL_SHAPES = Object.freeze(Object.values(CellBackgroundShape));
|
|
52
|
+
/**
|
|
53
|
+
* Grid 3 cell types enum values
|
|
54
|
+
*/
|
|
55
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
56
|
+
export const GRID3_CELL_TYPES = Object.freeze(Object.values(Grid3CellType));
|
|
57
|
+
/**
|
|
58
|
+
* Grid 3 command categories enum values
|
|
59
|
+
*/
|
|
60
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
61
|
+
export const GRID3_COMMAND_CATEGORIES = Object.freeze(Object.values(Grid3CommandCategory));
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Grid3 Style Helpers
|
|
3
|
+
*
|
|
4
|
+
* Utilities for creating and managing Grid3 styles, including default styles,
|
|
5
|
+
* style XML generation, and style conversion utilities.
|
|
6
|
+
*/
|
|
7
|
+
import { XMLBuilder } from 'fast-xml-parser';
|
|
8
|
+
import { ensureAlphaChannel, darkenColor } from './colorUtils';
|
|
9
|
+
/**
|
|
10
|
+
* Cell background shapes supported by Grid 3
|
|
11
|
+
* Maps to Grid 3's CellBackgroundShape enum
|
|
12
|
+
*/
|
|
13
|
+
export var CellBackgroundShape;
|
|
14
|
+
(function (CellBackgroundShape) {
|
|
15
|
+
CellBackgroundShape[CellBackgroundShape["Rectangle"] = 0] = "Rectangle";
|
|
16
|
+
CellBackgroundShape[CellBackgroundShape["RoundedRectangle"] = 1] = "RoundedRectangle";
|
|
17
|
+
CellBackgroundShape[CellBackgroundShape["FoldedCorner"] = 2] = "FoldedCorner";
|
|
18
|
+
CellBackgroundShape[CellBackgroundShape["Octagon"] = 3] = "Octagon";
|
|
19
|
+
CellBackgroundShape[CellBackgroundShape["Folder"] = 4] = "Folder";
|
|
20
|
+
CellBackgroundShape[CellBackgroundShape["Ellipse"] = 5] = "Ellipse";
|
|
21
|
+
CellBackgroundShape[CellBackgroundShape["SpeechBubble"] = 6] = "SpeechBubble";
|
|
22
|
+
CellBackgroundShape[CellBackgroundShape["ThoughtBubble"] = 7] = "ThoughtBubble";
|
|
23
|
+
CellBackgroundShape[CellBackgroundShape["Star"] = 8] = "Star";
|
|
24
|
+
CellBackgroundShape[CellBackgroundShape["Circle"] = 9] = "Circle";
|
|
25
|
+
CellBackgroundShape[CellBackgroundShape["ColouredCorner"] = 10] = "ColouredCorner";
|
|
26
|
+
})(CellBackgroundShape || (CellBackgroundShape = {}));
|
|
27
|
+
/**
|
|
28
|
+
* Human-readable shape names
|
|
29
|
+
*/
|
|
30
|
+
export const SHAPE_NAMES = {
|
|
31
|
+
[CellBackgroundShape.Rectangle]: 'Rectangle',
|
|
32
|
+
[CellBackgroundShape.RoundedRectangle]: 'Rounded Rectangle',
|
|
33
|
+
[CellBackgroundShape.FoldedCorner]: 'Folded Corner',
|
|
34
|
+
[CellBackgroundShape.Octagon]: 'Octagon',
|
|
35
|
+
[CellBackgroundShape.Folder]: 'Folder',
|
|
36
|
+
[CellBackgroundShape.Ellipse]: 'Ellipse',
|
|
37
|
+
[CellBackgroundShape.SpeechBubble]: 'Speech Bubble',
|
|
38
|
+
[CellBackgroundShape.ThoughtBubble]: 'Thought Bubble',
|
|
39
|
+
[CellBackgroundShape.Star]: 'Star',
|
|
40
|
+
[CellBackgroundShape.Circle]: 'Circle',
|
|
41
|
+
[CellBackgroundShape.ColouredCorner]: 'Coloured Corner',
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Default Grid3 styles for common use cases
|
|
45
|
+
* Colors are in 8-digit ARGB hex format (#AARRGGBBFF)
|
|
46
|
+
*/
|
|
47
|
+
export const DEFAULT_GRID3_STYLES = {
|
|
48
|
+
Default: {
|
|
49
|
+
BackColour: '#E2EDF8FF',
|
|
50
|
+
TileColour: '#FFFFFFFF',
|
|
51
|
+
BorderColour: '#000000FF',
|
|
52
|
+
FontColour: '#000000FF',
|
|
53
|
+
FontName: 'Arial',
|
|
54
|
+
FontSize: '16',
|
|
55
|
+
},
|
|
56
|
+
Workspace: {
|
|
57
|
+
BackColour: '#FFFFFFFF',
|
|
58
|
+
TileColour: '#FFFFFFFF',
|
|
59
|
+
BorderColour: '#CCCCCCFF',
|
|
60
|
+
FontColour: '#000000FF',
|
|
61
|
+
FontName: 'Arial',
|
|
62
|
+
FontSize: '14',
|
|
63
|
+
},
|
|
64
|
+
'Auto content': {
|
|
65
|
+
BackColour: '#E8F4F8FF',
|
|
66
|
+
TileColour: '#E8F4F8FF',
|
|
67
|
+
BorderColour: '#2C82C9FF',
|
|
68
|
+
FontColour: '#000000FF',
|
|
69
|
+
FontName: 'Arial',
|
|
70
|
+
FontSize: '14',
|
|
71
|
+
},
|
|
72
|
+
'Vocab cell': {
|
|
73
|
+
BackColour: '#E8F4F8FF',
|
|
74
|
+
TileColour: '#E8F4F8FF',
|
|
75
|
+
BorderColour: '#2C82C9FF',
|
|
76
|
+
FontColour: '#000000FF',
|
|
77
|
+
FontName: 'Arial',
|
|
78
|
+
FontSize: '14',
|
|
79
|
+
},
|
|
80
|
+
'Keyboard key': {
|
|
81
|
+
BackColour: '#F0F0F0FF',
|
|
82
|
+
TileColour: '#F0F0F0FF',
|
|
83
|
+
BorderColour: '#808080FF',
|
|
84
|
+
FontColour: '#000000FF',
|
|
85
|
+
FontName: 'Arial',
|
|
86
|
+
FontSize: '12',
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* Category-specific styles for navigation and organization
|
|
91
|
+
*/
|
|
92
|
+
export const CATEGORY_STYLES = {
|
|
93
|
+
'Actions category style': {
|
|
94
|
+
BackColour: '#4472C4FF',
|
|
95
|
+
TileColour: '#4472C4FF',
|
|
96
|
+
BorderColour: '#2F5496FF',
|
|
97
|
+
FontColour: '#FFFFFFFF',
|
|
98
|
+
FontName: 'Arial',
|
|
99
|
+
FontSize: '16',
|
|
100
|
+
},
|
|
101
|
+
'People category style': {
|
|
102
|
+
BackColour: '#ED7D31FF',
|
|
103
|
+
TileColour: '#ED7D31FF',
|
|
104
|
+
BorderColour: '#C65911FF',
|
|
105
|
+
FontColour: '#FFFFFFFF',
|
|
106
|
+
FontName: 'Arial',
|
|
107
|
+
FontSize: '16',
|
|
108
|
+
},
|
|
109
|
+
'Places category style': {
|
|
110
|
+
BackColour: '#A5A5A5FF',
|
|
111
|
+
TileColour: '#A5A5A5FF',
|
|
112
|
+
BorderColour: '#595959FF',
|
|
113
|
+
FontColour: '#FFFFFFFF',
|
|
114
|
+
FontName: 'Arial',
|
|
115
|
+
FontSize: '16',
|
|
116
|
+
},
|
|
117
|
+
'Descriptive category style': {
|
|
118
|
+
BackColour: '#70AD47FF',
|
|
119
|
+
TileColour: '#70AD47FF',
|
|
120
|
+
BorderColour: '#4F7C2FFF',
|
|
121
|
+
FontColour: '#FFFFFFFF',
|
|
122
|
+
FontName: 'Arial',
|
|
123
|
+
FontSize: '16',
|
|
124
|
+
},
|
|
125
|
+
'Social category style': {
|
|
126
|
+
BackColour: '#FFC000FF',
|
|
127
|
+
TileColour: '#FFC000FF',
|
|
128
|
+
BorderColour: '#BF8F00FF',
|
|
129
|
+
FontColour: '#000000FF',
|
|
130
|
+
FontName: 'Arial',
|
|
131
|
+
FontSize: '16',
|
|
132
|
+
},
|
|
133
|
+
'Questions category style': {
|
|
134
|
+
BackColour: '#5B9BD5FF',
|
|
135
|
+
TileColour: '#5B9BD5FF',
|
|
136
|
+
BorderColour: '#2E5C8AFF',
|
|
137
|
+
FontColour: '#FFFFFFFF',
|
|
138
|
+
FontName: 'Arial',
|
|
139
|
+
FontSize: '16',
|
|
140
|
+
},
|
|
141
|
+
'Little words category style': {
|
|
142
|
+
BackColour: '#C55A11FF',
|
|
143
|
+
TileColour: '#C55A11FF',
|
|
144
|
+
BorderColour: '#8B3F0AFF',
|
|
145
|
+
FontColour: '#FFFFFFFF',
|
|
146
|
+
FontName: 'Arial',
|
|
147
|
+
FontSize: '16',
|
|
148
|
+
},
|
|
149
|
+
};
|
|
150
|
+
/**
|
|
151
|
+
* Re-export ensureAlphaChannel from colorUtils for backward compatibility
|
|
152
|
+
* @deprecated Use ensureAlphaChannel from colorUtils instead
|
|
153
|
+
*/
|
|
154
|
+
export { ensureAlphaChannel } from './colorUtils';
|
|
155
|
+
/**
|
|
156
|
+
* Create a Grid3 style XML string with default and category styles
|
|
157
|
+
* @param includeCategories - Whether to include category-specific styles (default: true)
|
|
158
|
+
* @returns XML string for Settings0/styles.xml
|
|
159
|
+
*/
|
|
160
|
+
export function createDefaultStylesXml(includeCategories = true) {
|
|
161
|
+
const builder = new XMLBuilder({
|
|
162
|
+
ignoreAttributes: false,
|
|
163
|
+
format: true,
|
|
164
|
+
indentBy: ' ',
|
|
165
|
+
});
|
|
166
|
+
const styles = { ...DEFAULT_GRID3_STYLES };
|
|
167
|
+
if (includeCategories) {
|
|
168
|
+
Object.assign(styles, CATEGORY_STYLES);
|
|
169
|
+
}
|
|
170
|
+
const styleArray = Object.entries(styles).map(([key, style]) => ({
|
|
171
|
+
'@_Key': key,
|
|
172
|
+
BackColour: style.BackColour,
|
|
173
|
+
TileColour: style.TileColour,
|
|
174
|
+
BorderColour: style.BorderColour,
|
|
175
|
+
FontColour: style.FontColour,
|
|
176
|
+
FontName: style.FontName,
|
|
177
|
+
FontSize: style.FontSize?.toString(),
|
|
178
|
+
}));
|
|
179
|
+
const stylesData = {
|
|
180
|
+
StyleData: {
|
|
181
|
+
'@_xmlns:xsi': 'http://www.w3.org/2001/XMLSchema-instance',
|
|
182
|
+
Styles: {
|
|
183
|
+
Style: styleArray,
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
};
|
|
187
|
+
return builder.build(stylesData);
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Create a custom category style
|
|
191
|
+
* @param categoryName - Name of the category
|
|
192
|
+
* @param backgroundColor - Background color in hex format
|
|
193
|
+
* @param fontColor - Font color in hex format (default: white)
|
|
194
|
+
* @returns Grid3Style object
|
|
195
|
+
*/
|
|
196
|
+
export function createCategoryStyle(categoryName, backgroundColor, fontColor = '#FFFFFFFF') {
|
|
197
|
+
return {
|
|
198
|
+
BackColour: ensureAlphaChannel(backgroundColor),
|
|
199
|
+
TileColour: ensureAlphaChannel(backgroundColor),
|
|
200
|
+
BorderColour: ensureAlphaChannel(darkenColor(backgroundColor, 30)),
|
|
201
|
+
FontColour: ensureAlphaChannel(fontColor),
|
|
202
|
+
FontName: 'Arial',
|
|
203
|
+
FontSize: '16',
|
|
204
|
+
};
|
|
205
|
+
}
|