/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ "use strict"; const { TIMELINE_BLUEPRINT } = require("devtools/client/performance/modules/markers"); /** * This file contains utilities for parsing out the markers blueprint * to generate strings to be displayed in the UI. */ exports.MarkerBlueprintUtils = { /** * Takes a marker and a list of marker names that should be hidden, and * determines if this marker should be filtered or not. * * @param object marker * @return boolean */ shouldDisplayMarker: function (marker, hiddenMarkerNames) { if (!hiddenMarkerNames || hiddenMarkerNames.length == 0) { return true; } // If this marker isn't yet defined in the blueprint, simply check if the // entire category of "UNKNOWN" markers are supposed to be visible or not. let isUnknown = !(marker.name in TIMELINE_BLUEPRINT); if (isUnknown) { return hiddenMarkerNames.indexOf("UNKNOWN") == -1; } return hiddenMarkerNames.indexOf(marker.name) == -1; }, /** * Takes a marker and returns the blueprint definition for that marker type, * falling back to the UNKNOWN blueprint definition if undefined. * * @param object marker * @return object */ getBlueprintFor: function (marker) { return TIMELINE_BLUEPRINT[marker.name] || TIMELINE_BLUEPRINT.UNKNOWN; }, /** * Returns the label to display for a marker, based off the blueprints. * * @param object marker * @return string */ getMarkerLabel: function (marker) { let blueprint = this.getBlueprintFor(marker); let dynamic = typeof blueprint.label === "function"; let label = dynamic ? blueprint.label(marker) : blueprint.label; return label; }, /** * Returns the generic label to display for a marker name. * (e.g. "Function Call" for JS markers, rather than "setTimeout", etc.) * * @param string type * @return string */ getMarkerGenericName: function (markerName) { let blueprint = this.getBlueprintFor({ name: markerName }); let dynamic = typeof blueprint.label === "function"; let generic = dynamic ? blueprint.label() : blueprint.label; // If no class name found, attempt to throw a descriptive error as to // how the marker implementor can fix this. if (!generic) { let message = `Could not find marker generic name for "${markerName}".`; if (typeof blueprint.label === "function") { message += ` The following function must return a generic name string when no` + ` marker passed: ${blueprint.label}`; } else { message += ` ${markerName}.label must be defined in the marker blueprint.`; } throw new Error(message); } return generic; }, /** * Returns an array of objects with key/value pairs of what should be rendered * in the marker details view. * * @param object marker * @return array */ getMarkerFields: function (marker) { let blueprint = this.getBlueprintFor(marker); let dynamic = typeof blueprint.fields === "function"; let fields = dynamic ? blueprint.fields(marker) : blueprint.fields; return Object.entries(fields || {}) .filter(([_, value]) => dynamic ? true : value in marker) .map(([label, value]) => ({ label, value: dynamic ? value : marker[value] })); }, };