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