1// helper functions for keyboard 2 3/** 4 * Unescape an escaped string 5 * @param str input string such as '\u017c' 6 * @returns 7 */ 8function unescapeStr(str) { 9 str = str.replace(/\\u{([0-9a-fA-F]+)}/g, (a, b) => 10 String.fromCodePoint(Number.parseInt(b, 16)) 11 ); 12 return str; 13} 14 15function getKeyboardLayers(id) { 16 let q = _KeyboardData.keyboards[id].keyboard3.layers; 17 if (!Array.isArray(q)) { 18 q = [q]; 19 } 20 mogrifyAttrs(q); 21 const keybag = getKeyboardKeys(id); 22 mogrifyLayerList(q, keybag); 23 return q; 24} 25 26function mogrifyLayerList(layerList, keybag) { 27 layerList.forEach(({ layer }) => { 28 layer.forEach(({ row }) => { 29 row.forEach((r) => { 30 r.keys = r.keys.split(" ").map((id) => 31 Object.assign( 32 { 33 id, 34 }, 35 keybag[id] 36 ) 37 ); 38 }); 39 }); 40 }); 41} 42 43function getImportFile(id) { 44 return _KeyboardData.imports[id["@_path"].split("/")[1]]; 45} 46 47function getImportKeys(id) { 48 const imp = getImportFile(id); 49 if (!imp) { 50 throw Error(`Could not load import ${JSON.stringify(id)}`); 51 } 52 return imp.keys.key; 53} 54 55function mogrifyKeys(keys) { 56 // drop @' 57 if (!keys) { 58 return []; 59 } 60 return keys.reduce((p, v) => { 61 // TODO: any other swapping 62 mogrifyAttrs(v); 63 const { id, output } = v; 64 if (output) { 65 v.output = unescapeStr(output); 66 } 67 p[id] = v; 68 return p; 69 }, {}); 70} 71 72function mogrifyAttrs(o) { 73 for (const k of Object.keys(o)) { 74 const ok = o[k]; 75 if (/^@_/.test(k)) { 76 const attr = k.substring(2); 77 o[attr] = ok; 78 delete o[k]; 79 } else if (Array.isArray(ok)) { 80 ok.forEach((e) => mogrifyAttrs(e)); 81 } else if (typeof ok === "object") { 82 mogrifyAttrs(ok); 83 } 84 } 85 return o; 86} 87 88function getKeyboardKeys(id) { 89 const keys = _KeyboardData.keyboards[id].keyboard3.keys.key || []; 90 if (!keys) { 91 throw Error(`No keys for ${id}`); 92 } 93 let imports = [ 94 { 95 // add implied import 96 "@_base": "cldr", 97 "@_path": "45/keys-Latn-implied.xml", 98 }, 99 ...(_KeyboardData.keyboards[id].keyboard3.keys.import || []), 100 ]; 101 102 const importedKeys = []; 103 for (const fn of imports) { 104 for (const k of getImportKeys(fn)) { 105 importedKeys.push(k); 106 } 107 } 108 109 return mogrifyKeys([...importedKeys, ...keys]); 110} 111 112function getIds() { 113 return Object.keys(_KeyboardData.keyboards); 114} 115