mirror of
https://github.com/elder-plinius/P4RS3LT0NGV3.git
synced 2026-07-11 23:16:34 +02:00
fix multi spelling bug
This commit is contained in:
@@ -207,6 +207,14 @@ class SpellingAlphabetTool extends Tool {
|
||||
return 'Enter a name for this spelling alphabet.';
|
||||
}
|
||||
|
||||
var duplicateName = (this.saAlphabets || []).some(function(entry) {
|
||||
return entry.id !== this.saEditingId &&
|
||||
String(entry.name || '').trim().toLowerCase() === name.toLowerCase();
|
||||
}, this);
|
||||
if (duplicateName) {
|
||||
return 'Another spelling alphabet already uses this name. Choose a unique name.';
|
||||
}
|
||||
|
||||
var missing = this.saLetters.filter(function(letter) {
|
||||
return !String(this.saAlphabet[letter] || '').trim();
|
||||
}, this);
|
||||
@@ -295,6 +303,9 @@ class SpellingAlphabetTool extends Tool {
|
||||
|
||||
onActivate(vueInstance) {
|
||||
vueInstance.saLoadAlphabets();
|
||||
if (typeof vueInstance.refreshCustomSpellingTransforms === 'function') {
|
||||
vueInstance.refreshCustomSpellingTransforms();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -76,6 +76,8 @@ class TransformTool extends Tool {
|
||||
return true;
|
||||
})
|
||||
.map(([key, transform]) => ({
|
||||
transformKey: key,
|
||||
customSpellingId: transform.customSpellingId || null,
|
||||
name: transform.name,
|
||||
func: transform.func.bind(transform),
|
||||
preview: transform.preview ? transform.preview.bind(transform) : function() { return '[preview]'; },
|
||||
@@ -248,6 +250,12 @@ class TransformTool extends Tool {
|
||||
const transform = this.transforms.find(t => t.name === transformName);
|
||||
return transform ? transform.category : 'special';
|
||||
},
|
||||
getTransformKey: function(transform) {
|
||||
if (!transform) {
|
||||
return '';
|
||||
}
|
||||
return transform.customSpellingId || transform.transformKey || transform.name;
|
||||
},
|
||||
/**
|
||||
* True if this transform should show the options gear (uses saved prefs + defaults in decoder).
|
||||
* Falls back to window.transforms when the Vue copy omits configurableOptions.
|
||||
@@ -644,11 +652,22 @@ class TransformTool extends Tool {
|
||||
return;
|
||||
}
|
||||
|
||||
const previousCustomCount = (this.transforms || []).filter(function(t) {
|
||||
return t.category === 'custom_spelling';
|
||||
}).length;
|
||||
|
||||
this.transforms = transformTool.buildTransformsFromWindow();
|
||||
const categories = transformTool.rebuildTransformCategories(this.transforms);
|
||||
this.legendCategories = categories.legendCategories;
|
||||
this.categories = categories.sectionCategories;
|
||||
|
||||
const nextCustomCount = this.transforms.filter(function(t) {
|
||||
return t.category === 'custom_spelling';
|
||||
}).length;
|
||||
if (nextCustomCount !== previousCustomCount) {
|
||||
this.saveCategoryOrder(this.categories);
|
||||
}
|
||||
|
||||
this.$nextTick(() => {
|
||||
if (typeof this.initializeCategoryNavigation === 'function') {
|
||||
this.initializeCategoryNavigation();
|
||||
@@ -719,6 +738,9 @@ class TransformTool extends Tool {
|
||||
getVueLifecycle() {
|
||||
return {
|
||||
mounted() {
|
||||
if (typeof this.refreshCustomSpellingTransforms === 'function') {
|
||||
this.refreshCustomSpellingTransforms();
|
||||
}
|
||||
this.initializeCategoryNavigation();
|
||||
|
||||
// Save initial category order to localStorage if it doesn't exist
|
||||
@@ -736,6 +758,9 @@ class TransformTool extends Tool {
|
||||
}
|
||||
|
||||
onActivate(vueInstance) {
|
||||
if (typeof vueInstance.refreshCustomSpellingTransforms === 'function') {
|
||||
vueInstance.refreshCustomSpellingTransforms();
|
||||
}
|
||||
vueInstance.$nextTick(() => {
|
||||
vueInstance.initializeCategoryNavigation();
|
||||
});
|
||||
|
||||
@@ -416,7 +416,7 @@
|
||||
</p>
|
||||
<div class="chaos-overlay" aria-hidden="true"></div>
|
||||
<div class="transform-buttons">
|
||||
<div v-for="transform in getTransformsByCategory(category)" :key="transform.name" class="transform-button-group">
|
||||
<div v-for="transform in getTransformsByCategory(category)" :key="getTransformKey(transform)" class="transform-button-group">
|
||||
<button
|
||||
@click="applyTransform(transform, $event)"
|
||||
:class="'transform-button transform-category-' + category + ' randomizer-button'"
|
||||
@@ -486,7 +486,7 @@
|
||||
</span>
|
||||
</h4>
|
||||
<div class="transform-buttons">
|
||||
<div v-for="transform in getTransformsByCategory(category)" :key="transform.name" class="transform-button-group">
|
||||
<div v-for="transform in getTransformsByCategory(category)" :key="getTransformKey(transform)" class="transform-button-group">
|
||||
<button
|
||||
@click="applyTransform(transform, $event)"
|
||||
:class="'transform-button transform-category-' + category"
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const assert = require('assert');
|
||||
const path = require('path');
|
||||
const vm = require('vm');
|
||||
const fs = require('fs');
|
||||
|
||||
function createContext() {
|
||||
const store = {};
|
||||
const ctx = {
|
||||
window: null,
|
||||
globalThis: null,
|
||||
localStorage: {
|
||||
getItem: (key) => store[key] || null,
|
||||
setItem: (key, value) => { store[key] = value; }
|
||||
},
|
||||
console
|
||||
};
|
||||
ctx.window = ctx;
|
||||
ctx.globalThis = ctx;
|
||||
return { ctx, store };
|
||||
}
|
||||
|
||||
function loadScript(ctx, relativePath) {
|
||||
const code = fs.readFileSync(path.join(__dirname, '..', relativePath), 'utf8');
|
||||
vm.runInContext(code, vm.createContext(ctx), { filename: relativePath });
|
||||
}
|
||||
|
||||
function buildAlphabet(prefix) {
|
||||
const alphabet = {};
|
||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('').forEach((letter, index) => {
|
||||
alphabet[letter] = prefix + letter + index;
|
||||
});
|
||||
return alphabet;
|
||||
}
|
||||
|
||||
const { ctx } = createContext();
|
||||
loadScript(ctx, 'dist/js/bundles/transforms-bundle.js');
|
||||
loadScript(ctx, 'js/core/spellingAlphabetTransform.js');
|
||||
loadScript(ctx, 'js/core/customSpellingAlphabets.js');
|
||||
|
||||
const first = ctx.CustomSpellingAlphabets.saveMapping({
|
||||
name: 'Nautical Spelling Alphabet',
|
||||
category: 'nautical',
|
||||
alphabet: buildAlphabet('N')
|
||||
});
|
||||
const second = ctx.CustomSpellingAlphabets.saveMapping({
|
||||
name: 'Kitchen Spelling Alphabet',
|
||||
category: 'kitchen',
|
||||
alphabet: buildAlphabet('K')
|
||||
});
|
||||
|
||||
assert.strictEqual(ctx.CustomSpellingAlphabets.loadAll().length, 2, 'Should persist multiple alphabets');
|
||||
|
||||
const customKeys = Object.keys(ctx.window.transforms).filter((key) => key.indexOf('custom_spelling_') === 0);
|
||||
assert.strictEqual(customKeys.length, 2, 'Each saved alphabet should register as its own transform');
|
||||
|
||||
const names = customKeys.map((key) => ctx.window.transforms[key].name).sort();
|
||||
assert.deepStrictEqual(names, [
|
||||
'Kitchen Spelling Alphabet',
|
||||
'Nautical Spelling Alphabet'
|
||||
]);
|
||||
|
||||
customKeys.forEach((key) => {
|
||||
const transform = ctx.window.transforms[key];
|
||||
assert.strictEqual(transform.category, 'custom_spelling');
|
||||
assert.ok(transform.customSpellingId, 'Custom spelling transforms should expose customSpellingId');
|
||||
assert.strictEqual(typeof transform.func, 'function');
|
||||
});
|
||||
|
||||
ctx.CustomSpellingAlphabets.deleteMapping(first.id);
|
||||
assert.strictEqual(ctx.CustomSpellingAlphabets.loadAll().length, 1);
|
||||
const remainingKeys = Object.keys(ctx.window.transforms).filter((key) => key.indexOf('custom_spelling_') === 0);
|
||||
assert.strictEqual(remainingKeys.length, 1);
|
||||
assert.strictEqual(ctx.window.transforms[remainingKeys[0]].name, 'Kitchen Spelling Alphabet');
|
||||
|
||||
console.log('Custom spelling transform tests passed');
|
||||
Reference in New Issue
Block a user