blob: a1f1d61e3abc053fa7ca3e86842c0f334be11b50 [file] [log] [blame]
Victor Porof1a8a30d2022-06-13 13:07:10 +00001// Copyright 2022 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5/**
6 * Merges objects or arrays of objects. This is a simplistic merge operation
7 * that is only useful for generating the DOM pinned properties dataset.
8 *
9 * The merge happens in-place: b is merged *into* a.
10 * Both objects must be of the same type.
11 * Arrays are merged as unions with simple same-value-zero equality.
12 * Objects are merged with truthy-property precedence.
13 *
14 * @param {array|object} a
15 * @param {array|object} b
16 */
17export function merge(a, b) {
18 if (Array.isArray(a) && Array.isArray(b)) {
19 mergeArrays(a, b);
20 } else if (isNonNullObject(a) && isNonNullObject(b)) {
21 mergeObjects(a, b);
22 } else {
23 throw Error;
24 }
25
26 function isNonNullObject(value) {
27 return typeof value === 'object' && value !== null;
28 }
29
30 function mergeArrays(a, b) {
Victor Porofd8a8db72022-06-13 13:24:36 +000031 const set = new Set(a);
Victor Porof1a8a30d2022-06-13 13:07:10 +000032 for (const value of b) {
Victor Porofd8a8db72022-06-13 13:24:36 +000033 if (!set.has(value)) {
Victor Porof1a8a30d2022-06-13 13:07:10 +000034 a.push(value);
35 }
36 }
37 }
38
39 function mergeObjects(a, b) {
40 for (const key of Object.keys(b)) {
41 if (isNonNullObject(a[key]) && isNonNullObject(b[key])) {
42 merge(a[key], b[key]);
43 } else {
44 a[key] = a[key] ?? b[key];
45 }
46 }
47 }
48}
49
50/**
51 * Finds "missing" types in a DOM pinned properties dataset.
52 * A "missing" type is defined as a type that is inherited or included by/in
53 * another type, but for which a definition wasn't found in the specs.
54 *
55 * This is a helper which helps to ensure that all relevant specs are parsed.
56 * E.g. some specs might reference types defined in other specs.
57 *
58 * @param {object} data
59 * @returns {array}
60 */
61export function getMissingTypes(data) {
62 const missing = new Set();
63 const keys = new Set(Object.keys(data));
64
65 for (const value of Object.values(data)) {
66 if (value.inherits) {
67 if (!keys.has(value.inherits)) {
68 missing.add(value.inherits);
69 }
70 }
71 if (value.includes) {
72 for (const include of value.includes) {
73 if (!keys.has(include)) {
74 missing.add(include);
75 }
76 }
77 }
78 }
79
80 return [...missing];
81}