/* 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 { createFactory, PureComponent, } = require("resource://devtools/client/shared/vendor/react.js"); const dom = require("resource://devtools/client/shared/vendor/react-dom-factories.js"); const PropTypes = require("resource://devtools/client/shared/vendor/react-prop-types.js"); const FontAxis = createFactory( require("resource://devtools/client/inspector/fonts/components/FontAxis.js") ); const FontName = createFactory( require("resource://devtools/client/inspector/fonts/components/FontName.js") ); const FontSize = createFactory( require("resource://devtools/client/inspector/fonts/components/FontSize.js") ); const FontStyle = createFactory( require("resource://devtools/client/inspector/fonts/components/FontStyle.js") ); const FontWeight = createFactory( require("resource://devtools/client/inspector/fonts/components/FontWeight.js") ); const LetterSpacing = createFactory( require("resource://devtools/client/inspector/fonts/components/LetterSpacing.js") ); const LineHeight = createFactory( require("resource://devtools/client/inspector/fonts/components/LineHeight.js") ); const { getStr, } = require("resource://devtools/client/inspector/fonts/utils/l10n.js"); const Types = require("resource://devtools/client/inspector/fonts/types.js"); // Maximum number of font families to be shown by default. Any others will be hidden // under a collapsed
element with a toggle to reveal them. const MAX_FONTS = 3; class FontEditor extends PureComponent { static get propTypes() { return { fontEditor: PropTypes.shape(Types.fontEditor).isRequired, onInstanceChange: PropTypes.func.isRequired, onPropertyChange: PropTypes.func.isRequired, onToggleFontHighlight: PropTypes.func.isRequired, }; } /** * Get an array of FontAxis components with editing controls for of the given variable * font axes. If no axes were given, return null. * If an axis' value was declared on the font-variation-settings CSS property or was * changed using the font editor, use that value, otherwise use the axis default. * * @param {Array} fontAxes * Array of font axis instances * @param {Object} editedAxes * Object with axes and values edited by the user or defined in the CSS * declaration for font-variation-settings. * @return {Array|null} */ renderAxes(fontAxes = [], editedAxes) { if (!fontAxes.length) { return null; } return fontAxes.map(axis => { return FontAxis({ key: axis.tag, axis, disabled: this.props.fontEditor.disabled, onChange: this.props.onPropertyChange, minLabel: true, maxLabel: true, value: editedAxes[axis.tag] || axis.defaultValue, }); }); } /** * Render fonts used on the selected node grouped by font-family. * * @param {Array} fonts * Fonts used on selected node. * @return {DOMNode} */ renderUsedFonts(fonts) { if (!fonts.length) { return null; } // Group fonts by family name. const fontGroups = fonts.reduce((acc, font) => { const family = font.CSSFamilyName.toString(); acc[family] = acc[family] || []; acc[family].push(font); return acc; }, {}); const renderedFontGroups = Object.keys(fontGroups).map(family => { return this.renderFontGroup(family, fontGroups[family]); }); const topFontsList = renderedFontGroups.slice(0, MAX_FONTS); const moreFontsList = renderedFontGroups.slice( MAX_FONTS, renderedFontGroups.length ); const moreFonts = !moreFontsList.length ? null : dom.details( {}, dom.summary( {}, dom.span( { className: "label-open" }, getStr("fontinspector.showMore") ), dom.span( { className: "label-close" }, getStr("fontinspector.showLess") ) ), moreFontsList ); return dom.label( { className: "font-control font-control-used-fonts", }, dom.span( { className: "font-control-label", }, getStr("fontinspector.fontsUsedLabel") ), dom.div( { className: "font-control-box", }, topFontsList, moreFonts ) ); } renderFontGroup(family, fonts = []) { const group = fonts.map(font => { return FontName({ key: font.name, font, onToggleFontHighlight: this.props.onToggleFontHighlight, }); }); return dom.div( { key: family, className: "font-group", }, dom.div( { className: "font-family-name", }, family ), group ); } renderFontSize(value) { return ( value !== null && FontSize({ key: `${this.props.fontEditor.id}:font-size`, disabled: this.props.fontEditor.disabled, onChange: this.props.onPropertyChange, value, }) ); } renderLineHeight(value) { return ( value !== null && LineHeight({ key: `${this.props.fontEditor.id}:line-height`, disabled: this.props.fontEditor.disabled, onChange: this.props.onPropertyChange, value, }) ); } renderLetterSpacing(value) { return ( value !== null && LetterSpacing({ key: `${this.props.fontEditor.id}:letter-spacing`, disabled: this.props.fontEditor.disabled, onChange: this.props.onPropertyChange, value, }) ); } renderFontStyle(value) { return ( value && FontStyle({ onChange: this.props.onPropertyChange, disabled: this.props.fontEditor.disabled, value, }) ); } renderFontWeight(value) { return ( value !== null && FontWeight({ onChange: this.props.onPropertyChange, disabled: this.props.fontEditor.disabled, value, }) ); } /** * Get a dropdown which allows selecting between variation instances defined by a font. * * @param {Array} fontInstances * Named variation instances as provided with the font file. * @param {Object} selectedInstance * Object with information about the currently selected variation instance. * Example: * { * name: "Custom", * values: [] * } * @return {DOMNode} */ renderInstances(fontInstances = [], selectedInstance = {}) { // Append a "Custom" instance entry which represents the latest manual axes changes. const customInstance = { name: getStr("fontinspector.customInstanceName"), values: this.props.fontEditor.customInstanceValues, }; fontInstances = [...fontInstances, customInstance]; // Generate the