UNPKG

@openui5/sap.m

Version:

OpenUI5 UI Library sap.m

295 lines (257 loc) 9.1 kB
/*! * OpenUI5 * (c) Copyright 2009-2023 SAP SE or an SAP affiliate company. * Licensed under the Apache License, Version 2.0 - see LICENSE.txt. */ // Provides Mixin sap.m.HyphenationSupport sap.ui.define([ "sap/base/config", "./library", "sap/ui/core/hyphenation/Hyphenation", "sap/base/Log" ], function ( BaseConfig, library, Hyphenation, Log ) { "use strict"; // shortcut for sap.m.WrappingType var WrappingType = library.WrappingType; // get xx-hyphenation config function getHyphenation() { return BaseConfig.get({ name: "sapUiXxHyphenation", type: BaseConfig.Type.String, external: true }); } /** * Checks if the given control implements IHyphenation. * * @param {sap.ui.core.Control} oControl The control to validate * @returns {boolean} True if the control is valid * @private */ function isValidControl(oControl) { if (!oControl.isA("sap.m.IHyphenation")) { Log.error("[UI5 Hyphenation] The given control does not implement interface sap.m.IHyphenation and can not use HyphenationSupport mixin."); return false; } return true; } /** * Checks if the required text key is present in the texts map. * * @param {sap.m.IHyphenation} oControl The control to be checked * @param {string} sKey The key to look for * @returns {boolean} True if the key is correct * @private */ function isValidTextKey(oControl, sKey) { var mTexts = oControl.getTextsToBeHyphenated(); if (typeof mTexts !== "object") { Log.error("[UI5 Hyphenation] The result of getTextsToBeHyphenated method is not a map object.", oControl.getId()); return false; } if (Object.keys(mTexts).indexOf(sKey) < 0) { Log.error("[UI5 Hyphenation] The key " + sKey + " is not found in the result of getTextsToBeHyphenated method.", oControl.getId()); return false; } return true; } /** * To prevent from the layout thrashing of the <code>textContent</code> call, this method * first tries to set the <code>nodeValue</code> of the first child if it exists. * * @param {HTMLElement} oDomRef DOM reference of the text node container. * @param {string} [sNodeValue] new Node value. * @private */ function setNodeValue(oDomRef, sNodeValue) { sNodeValue = sNodeValue || ""; var aChildNodes = oDomRef.childNodes; if (aChildNodes.length === 1 && aChildNodes[0].nodeType === window.Node.TEXT_NODE) { aChildNodes[0].nodeValue = sNodeValue; } else { oDomRef.textContent = sNodeValue; } } /** * Checks which keys are not present in mTextsToDiff or their values are different * * @param {Object<string,string>} mTextsMain The map of texts to compare * @param {Object<string,string>} mTextsToDiff The map of texts to compare against * @returns {Array} An array containing all keys for which there is difference * @private */ function diffTexts(mTextsMain, mTextsToDiff) { var aDiffs = []; Object.keys(mTextsMain).forEach(function(sKey) { if (!(sKey in mTextsToDiff && mTextsMain[sKey] === mTextsToDiff[sKey])) { aDiffs.push(sKey); } }); return aDiffs; } /** * Checks if the third-party hyphenation is required. * * @returns {boolean} True if third-party hyphenation is required. False if native hyphenation is available or required * @private */ function shouldUseThirdParty() { var sHyphenationConfig = getHyphenation(), oHyphenationInstance = Hyphenation.getInstance(); if (sHyphenationConfig === "native" || sHyphenationConfig === "disable") { return false; } if (sHyphenationConfig === "thirdparty") { return true; } return oHyphenationInstance.isLanguageSupported() && !oHyphenationInstance.canUseNativeHyphenation() && oHyphenationInstance.canUseThirdPartyHyphenation(); } /** * Checks whether the control's text should be hyphenated. * * @param {sap.m.IHyphenation} oControl The control to be checked * @returns {boolean} True if the control should hyphenate * @private */ function shouldControlHyphenate(oControl) { var sHyphenationConfig = getHyphenation(); if (sHyphenationConfig === 'disable') { return false; } return (!oControl.getWrapping || oControl.getWrapping()) && oControl.getWrappingType() === WrappingType.Hyphenated; } /** * Hyphenates all texts needed for the given control. * * @param {sap.m.IHyphenation} oControl The control whose texts need hyphenation * @private */ function hyphenateTexts(oControl) { if (!shouldControlHyphenate(oControl) || !shouldUseThirdParty()) { // no hyphenation needed oControl._mHyphenatedTexts = {}; oControl._mUnhyphenatedTexts = {}; return; } var mTexts = oControl.getTextsToBeHyphenated(), aChangedTextKeys = diffTexts(mTexts, oControl._mUnhyphenatedTexts); if (aChangedTextKeys.length > 0) { oControl._mUnhyphenatedTexts = mTexts; aChangedTextKeys.forEach(function(sKey) { delete oControl._mHyphenatedTexts[sKey]; }); var oHyphenation = Hyphenation.getInstance(); if (!oHyphenation.isLanguageInitialized()) { oHyphenation.initialize().then(function () { var mDomRefs = oControl.isActive() ? oControl.getDomRefsForHyphenatedTexts() : null, bNeedInvalidate = false; aChangedTextKeys.forEach(function(sKey) { oControl._mHyphenatedTexts[sKey] = oHyphenation.hyphenate(mTexts[sKey]); if (mDomRefs && sKey in mDomRefs) { setNodeValue(mDomRefs[sKey], oControl._mHyphenatedTexts[sKey]); } else { bNeedInvalidate = true; } }); if (bNeedInvalidate) { oControl.invalidate(); } }); } else { aChangedTextKeys.forEach(function(sKey) { oControl._mHyphenatedTexts[sKey] = oHyphenation.hyphenate(mTexts[sKey]); }); } } } /** * @class Mixin which enables the use of hyphenation for controls. * * The control has to implement sap.m.IHyphenation interface. * The mixin attaches to onBeforeRendering and prepares all texts which are needed for the control, provided by method sap.m.IHyphenation#getTextsToBeHyphenated. * In the control renderer, the methods sap.m.HyphenationSupport#writeHyphenationClass and sap.m.HyphenationSupport#getTextForRender have to be used. * If native hyphenation is available, the class for hyphenation will be added. If not - third-party hyphenation will be used. * * @name sap.m.HyphenationSupport * @see sap.m.IHyphenation * @private */ var HyphenationSupport = {}; /** * Extends the control with ability to use hyphenation. * * @param {sap.m.IHyphenation} oControlPrototype The control prototype to extend * @private */ HyphenationSupport.mixInto = function (oControlPrototype) { if (!isValidControl(oControlPrototype)) { return; } var fnInit = oControlPrototype.init; oControlPrototype.init = function (sId) { var res = fnInit.apply(this, arguments); this._mHyphenatedTexts = {}; this._mUnhyphenatedTexts = {}; return res; }; var fnOnBeforeRendering = oControlPrototype.onBeforeRendering; oControlPrototype.onBeforeRendering = function () { var res = fnOnBeforeRendering.apply(this, arguments); hyphenateTexts(this); return res; }; }; /** * Adds sapUiHyphenation class to control if native hyphenation will be used. * * @param {sap.ui.core.RenderManager} oRm The render manager * @param {sap.m.IHyphenation} oControl A hyphenation enabled control * @private */ HyphenationSupport.writeHyphenationClass = function (oRm, oControl) { if (!isValidControl(oControl)) { return; } if (shouldControlHyphenate(oControl) && !shouldUseThirdParty()) { oRm.class("sapUiHyphenation"); } }; /** * Gets the text which should be rendered. This is either the hyphenated text if hyphenation is required and available, or the original text. * * @param {sap.m.IHyphenation} oControl The control for which the text is needed * @param {string} sKey Which text to get. Out of multiple texts for the control sap.m.IHyphenation#getTextsToBeHyphenated * @see sap.m.IHyphenation#getTextsToBeHyphenated * @returns {string} The hyphenated or the original text * @private */ HyphenationSupport.getTextForRender = function (oControl, sKey) { if (!isValidControl(oControl)) { return null; } if (!isValidTextKey(oControl, sKey)) { return null; } var mTexts = oControl.getTextsToBeHyphenated(); if (shouldControlHyphenate(oControl) && shouldUseThirdParty()) { // if hyphenated texts are not prepared already prepare them now, needed in case of custom setText if (mTexts[sKey] !== oControl._mUnhyphenatedTexts[sKey]) { hyphenateTexts(oControl); } if (sKey in oControl._mHyphenatedTexts) { return oControl._mHyphenatedTexts[sKey]; } } // hyphenation is not needed or not available yet - return the unmodified text return mTexts[sKey]; }; return HyphenationSupport; });