diff --git a/common/web/types/src/ldml-keyboard/ldml-keyboard-xml-reader.ts b/common/web/types/src/ldml-keyboard/ldml-keyboard-xml-reader.ts index 1d61f59f9d..2ae3c775df 100644 --- a/common/web/types/src/ldml-keyboard/ldml-keyboard-xml-reader.ts +++ b/common/web/types/src/ldml-keyboard/ldml-keyboard-xml-reader.ts @@ -11,6 +11,8 @@ export default class LDMLKeyboardXMLSourceFileReader { */ private boxArrays(source: any) { boxXmlArray(source?.keyboard, 'layers'); + boxXmlArray(source?.keyboard?.displays, 'display'); + boxXmlArray(source?.keyboard?.displays, 'displayOptions'); boxXmlArray(source?.keyboard?.names, 'name'); boxXmlArray(source?.keyboard?.vkeys, 'vkey'); boxXmlArray(source?.keyboard?.keys, 'key'); @@ -32,9 +34,31 @@ export default class LDMLKeyboardXMLSourceFileReader { } } boxXmlArray(source?.keyboard?.reorders, 'reorder'); + this.boxImportsAndSpecials(source); return source; } + /** + * Recurse over object, boxing up any specials or imports + * @param obj any object to be traversed + */ + private boxImportsAndSpecials(obj: any) { + if (!obj) return; + if (Array.isArray(obj)) { + for (const sub of obj) { + this.boxImportsAndSpecials(sub); + } + } else if(typeof obj === 'object') { + for (const key of Object.keys(obj)) { + if (key === 'special' || key === 'import') { + boxXmlArray(obj, key); + } else { + this.boxImportsAndSpecials(obj[key]); + } + } + } + } + public validate(source: LDMLKeyboardXMLSourceFile, schemaSource: Buffer): void { const schema = JSON.parse(schemaSource.toString('utf8')); const ajv = new Ajv(); diff --git a/resources/standards-data/ldml-keyboards/techpreview/fixup-schema.js b/resources/standards-data/ldml-keyboards/techpreview/fixup-schema.js index f8233f06f2..3d908dcfb1 100644 --- a/resources/standards-data/ldml-keyboards/techpreview/fixup-schema.js +++ b/resources/standards-data/ldml-keyboards/techpreview/fixup-schema.js @@ -22,22 +22,40 @@ if (!data['$id'] && data['id']) { delete data['id']; } +/** + * Turn a schema node from an array into a singleton of the specified type + * @param {Object} o + */ +function arrayToSingle(o) { + if (!o) return; + if (o.type === 'array') { + o["$ref"] = o.items["$ref"]; + delete o.items; + delete o.type; + } +} + +/** + * Turn a schema node from a singleton of some type into an array of that type + * @param {Object} o + */ +function singleToArray(o) { + if (!o) return; + if (!o.type) { + o.items = { "$ref": o["$ref"] }; + o.type = "array"; + delete o["$ref"]; + } +} + if (data.title.endsWith('ldmlKeyboard.xsd')) { if (data?.properties?.keyboard) { data.properties.keyboard.type = 'object'; } - if (data?.properties?.keyboard?.properties?.vkeys?.type === 'array') { - data.properties.keyboard.properties.vkeys["$ref"] = data.properties.keyboard.properties.vkeys.items["$ref"]; - delete data.properties.keyboard.properties.vkeys.items; - delete data.properties.keyboard.properties.vkeys.type; - } - - if (!data?.definitions?.keys?.properties?.key?.type) { - data.definitions.keys.properties.key.items = { "$ref": data.definitions.keys.properties.key["$ref"] }; - data.definitions.keys.properties.key.type = "array"; - delete data.definitions.keys.properties.key["$ref"]; - } + arrayToSingle(data?.properties?.keyboard?.properties?.vkeys); + singleToArray(data?.definitions?.keys?.properties?.key); + singleToArray(data?.definitions?.keys?.properties?.flicks); } // Write stuff diff --git a/resources/standards-data/ldml-keyboards/techpreview/ldml-keyboard.schema.json b/resources/standards-data/ldml-keyboards/techpreview/ldml-keyboard.schema.json index 74ef4afdca..d35b5ae2f9 100644 --- a/resources/standards-data/ldml-keyboards/techpreview/ldml-keyboard.schema.json +++ b/resources/standards-data/ldml-keyboards/techpreview/ldml-keyboard.schema.json @@ -187,7 +187,10 @@ "additionalProperties": false, "properties": { "flicks": { - "$ref": "#/definitions/flicks" + "items": { + "$ref": "#/definitions/flicks" + }, + "type": "array" }, "import": { "items": {