compatibility.js (5702B)
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 const { Actor } = require("resource://devtools/shared/protocol.js"); 8 const { 9 compatibilitySpec, 10 } = require("resource://devtools/shared/specs/compatibility.js"); 11 12 loader.lazyGetter(this, "mdnCompatibility", () => { 13 const MDNCompatibility = require("resource://devtools/server/actors/compatibility/lib/MDNCompatibility.js"); 14 const cssPropertiesCompatData = require("resource://devtools/shared/compatibility/dataset/css-properties.json"); 15 return new MDNCompatibility(cssPropertiesCompatData); 16 }); 17 18 class CompatibilityActor extends Actor { 19 /** 20 * Create a CompatibilityActor. 21 * CompatibilityActor is responsible for providing the compatibility information 22 * for the web page using the data from the Inspector and the `MDNCompatibility` 23 * and conveys them to the compatibility panel in the DevTool Inspector. Currently, 24 * the `CompatibilityActor` only detects compatibility issues in the CSS declarations 25 * but plans are in motion to extend it to evaluate compatibility information for 26 * HTML and JavaScript. 27 * The design below has the InspectorActor own the CompatibilityActor, but it's 28 * possible we will want to move it into it's own panel in the future. 29 * 30 * @param inspector 31 * The InspectorActor that owns this CompatibilityActor. 32 * 33 * @class 34 */ 35 constructor(inspector) { 36 super(inspector.conn, compatibilitySpec); 37 this.inspector = inspector; 38 } 39 40 destroy() { 41 super.destroy(); 42 this.inspector = null; 43 } 44 45 form() { 46 return { 47 actor: this.actorID, 48 }; 49 } 50 51 getTraits() { 52 return { 53 traits: {}, 54 }; 55 } 56 57 /** 58 * Responsible for computing the compatibility issues for a list of CSS declaration blocks 59 * 60 * @param {Array<Array<object>>} domRulesDeclarations: An array of arrays of CSS declaration object 61 * @param {string} domRulesDeclarations[][].name: Declaration name 62 * @param {string} domRulesDeclarations[][].value: Declaration value 63 * @param {Array<object>} targetBrowsers: Array of target browsers () to be used to check CSS compatibility against 64 * @param {string} targetBrowsers[].id: Browser id as specified in `devtools/shared/compatibility/datasets/browser.json` 65 * @param {string} targetBrowsers[].name 66 * @param {string} targetBrowsers[].version 67 * @param {string} targetBrowsers[].status: Browser status - esr, current, beta, nightly 68 * @returns {Array<Array<object>>} An Array of arrays of JSON objects with compatibility 69 * information in following form: 70 * { 71 * // Type of compatibility issue 72 * type: <string>, 73 * // The CSS declaration that has compatibility issues 74 * property: <string>, 75 * // Alias to the given CSS property 76 * alias: <Array>, 77 * // Link to MDN documentation for the particular CSS rule 78 * url: <string>, 79 * deprecated: <boolean>, 80 * experimental: <boolean>, 81 * // An array of all the browsers that don't support the given CSS rule 82 * unsupportedBrowsers: <Array>, 83 * } 84 */ 85 getCSSDeclarationBlockIssues(domRulesDeclarations, targetBrowsers) { 86 return domRulesDeclarations.map(declarationBlock => 87 mdnCompatibility.getCSSDeclarationBlockIssues( 88 declarationBlock, 89 targetBrowsers 90 ) 91 ); 92 } 93 94 /** 95 * Responsible for computing the compatibility issues in the 96 * CSS declaration of the given node. 97 * 98 * @param NodeActor node 99 * @param targetBrowsers Array 100 * An Array of JSON object of target browser to check compatibility against in following form: 101 * { 102 * // Browser id as specified in `devtools/server/actors/compatibility/lib/datasets/browser.json` 103 * id: <string>, 104 * name: <string>, 105 * version: <string>, 106 * // Browser status - esr, current, beta, nightly 107 * status: <string>, 108 * } 109 * @returns An Array of JSON objects with compatibility information in following form: 110 * { 111 * // Type of compatibility issue 112 * type: <string>, 113 * // The CSS declaration that has compatibility issues 114 * property: <string>, 115 * // Alias to the given CSS property 116 * alias: <Array>, 117 * // Link to MDN documentation for the particular CSS rule 118 * url: <string>, 119 * deprecated: <boolean>, 120 * experimental: <boolean>, 121 * // An array of all the browsers that don't support the given CSS rule 122 * unsupportedBrowsers: <Array>, 123 * } 124 */ 125 async getNodeCssIssues(node, targetBrowsers) { 126 const pageStyle = await this.inspector.getPageStyle(); 127 const styles = await pageStyle.getApplied(node, { 128 skipPseudo: false, 129 }); 130 131 const declarations = []; 132 const propertyNames = new Set(); 133 134 for (const { rule } of styles.entries) { 135 for (const declaration of rule.parseRuleDeclarations({ 136 parseComments: false, 137 })) { 138 // For now (see Bug 1636301), we only check compat issues based on the declaration 139 // name, so we can only pass a single declaration for a given property and save 140 // some time in getCSSDeclarationBlockIssues. 141 if (propertyNames.has(declaration.name)) { 142 continue; 143 } 144 propertyNames.add(declaration.name); 145 declarations.push(declaration); 146 } 147 } 148 149 return mdnCompatibility.getCSSDeclarationBlockIssues( 150 declarations, 151 targetBrowsers 152 ); 153 } 154 } 155 156 exports.CompatibilityActor = CompatibilityActor;