helpers.js (3463B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 "use strict"; 6 7 // This file might be required from a node script (./bin/update.js), so don't use 8 // Chrome API here. 9 10 /** 11 * Return the compatibility table from given compatNode and specified terms. 12 * For example, if the terms is ["background-color"], 13 * this function returns compatNode["background-color"].__compat. 14 * 15 * @return {object} compatibility table 16 * { 17 * description: {String} Description of this compatibility table. 18 * mdn_url: {String} Document in the MDN. 19 * support: { 20 * $browserName: {String} $browserName is such as firefox, firefox_android and so on. 21 * [ 22 * { 23 * added: {String} 24 * The version this feature was added. 25 * removed: {String} Optional. 26 * The version this feature was removed. Optional. 27 * prefix: {String} Optional. 28 * The prefix this feature is needed such as "-moz-". 29 * alternative_name: {String} Optional. 30 * The alternative name of this feature such as "-moz-osx-font-smoothing" of "font-smooth". 31 * notes: {String} Optional. 32 * A simple note for this support. 33 * }, 34 * ... 35 * ], 36 * }, 37 * status: { 38 * experimental: {Boolean} If true, this feature is experimental. 39 * standard_track: {Boolean}, If true, this feature is on the standard track. 40 * deprecated: {Boolean} If true, this feature is deprecated. 41 * } 42 * } 43 */ 44 function getCompatTable(compatNode, terms) { 45 let targetNode = getCompatNode(compatNode, terms); 46 47 if (!targetNode) { 48 return null; 49 } 50 51 if (!targetNode.__compat) { 52 for (const field in targetNode) { 53 // TODO: We don't have a way to know the context for now. 54 // Thus, use first context node as the compat table. 55 // e.g. flex_context of align-item 56 // https://github.com/mdn/browser-compat-data/blob/master/css/properties/align-items.json#L5 57 if (field.endsWith("_context")) { 58 targetNode = targetNode[field]; 59 break; 60 } 61 } 62 } 63 64 return targetNode.__compat; 65 } 66 67 /** 68 * Return a compatibility node which is target for `terms` parameter from `compatNode` 69 * parameter. For example, when check `background-clip: content-box;`, the `terms` will 70 * be ["background-clip", "content-box"]. Then, follow the name of terms from the 71 * compatNode node, return the target node. Although this function actually do more 72 * complex a bit, if it says simply, returns a node of 73 * compatNode["background-clip"]["content-box""] . 74 */ 75 function getCompatNode(compatNode, terms) { 76 for (const term of terms) { 77 compatNode = getChildCompatNode(compatNode, term); 78 if (!compatNode) { 79 return null; 80 } 81 } 82 83 return compatNode; 84 } 85 86 function getChildCompatNode(compatNode, term) { 87 term = term.toLowerCase(); 88 89 let child = null; 90 for (const field in compatNode) { 91 if (field.toLowerCase() === term) { 92 child = compatNode[field]; 93 break; 94 } 95 } 96 97 if (!child) { 98 return null; 99 } 100 101 if (child._aliasOf) { 102 // If the node is an alias, returns the node the alias points. 103 child = compatNode[child._aliasOf]; 104 } 105 106 return child; 107 } 108 109 module.exports = { 110 getCompatNode, 111 getCompatTable, 112 };