UNPKG

@openui5/sap.m

Version:

OpenUI5 UI Library sap.m

151 lines (121 loc) 4.65 kB
/*! * OpenUI5 * (c) Copyright 2026 SAP SE or an SAP affiliate company. * Licensed under the Apache License, Version 2.0 - see LICENSE.txt. */ /** * Defines support rules of the Image control of sap.m library. */ sap.ui.define(["sap/ui/support/library"], function(SupportLib) { "use strict"; // shortcuts var Categories = SupportLib.Categories, // Accessibility, Performance, Memory, ... Severity = SupportLib.Severity, // Low, Medium, High Audiences = SupportLib.Audiences; // Control, Internal, Application //********************************************************** // Utils //********************************************************** var HIGH_DENSITIES = [1.5, 2], // these are the densities mostly expected to be supported by the app (3x and 4x will be skipped to avoid too many requests that prolong the check) REQUEST_TIMEOUT = 3000; //ms function downloadHighDensityImage(oImage, iDensity) { return new Promise(function(resolve, reject) { var sSrc = oImage.getSrc(), sDensityAwareSrc = oImage._generateSrcByDensity(sSrc, iDensity), oDomElement = document.createElement("IMG"), bDone = false; // check src availability using src property of a dummy dom element // to avoid making AJAX request (may be forbidden if conflicts with CORS) oDomElement.setAttribute("src", sDensityAwareSrc); oDomElement.style.position = "absolute"; oDomElement.style.left = "-10000px"; oDomElement.style.top = "-10000px"; function onLoad() { cleanup(); resolve(true); } function onError() { cleanup(); resolve(false); } function cleanup() { if (oDomElement && oDomElement.parentNode !== null) { // allow this element and its attached listeners be picked up by the GC oDomElement.parentNode.removeChild(oDomElement); } bDone = true; } oDomElement.addEventListener("load", onLoad); oDomElement.addEventListener("error", onError); document.body.appendChild(oDomElement); // ensure check is completed even if none of the events are called // (e.g. iOS may not fire load for an already loaded and cached image) setTimeout(function() { if (!bDone) { reject(); // densityAwareSrc availability is not confirmed } }, REQUEST_TIMEOUT); }); } //********************************************************** // Rule Definitions //********************************************************** /** * Checks if the <code>densityAware</code> property of <code>sap.m.Image</code> is enabled when density-perfect image version exists */ var oImageRule = { id : "densityAwareImage", audiences: [Audiences.Control], categories: [Categories.Usability], enabled: true, async: true, minversion: "1.60", title: "Image: Density awareness disabled", description: "We checked that your application provides high-density version(s) of the listed image(s). " + "However, the high-density version(s) will be ignored, because the \"densityAware\" property of this image is disabled. " + "Since UI5 1.60, the \"densityAware\" property is no longer enabled by default. You need to enable it explicitly.", resolution: "Enable the \"densityAware\" property of this image control", resolutionurls: [{ text: "API Refrence for sap.m.Image", href: "https://sdk.openui5.org/api/sap.m.Image" }], check: function (oIssueManager, oCoreFacade, oScope, fnResolve) { var aAsyncTasks = [], aIssuedImageIds = [], oTask, sImageId, sImageName; oScope.getElementsByClassName("sap.m.Image") .forEach(function(oImage) { if (!oImage.getDensityAware()) { HIGH_DENSITIES.forEach(function(iDensity) { oTask = downloadHighDensityImage(oImage, iDensity); aAsyncTasks.push(oTask); oTask.then(function(bSuccess) { if (!bSuccess) { return; } sImageId = oImage.getId(); if (aIssuedImageIds.indexOf(sImageId) > -1) { return; // already issued warning for this image } aIssuedImageIds.push(sImageId); sImageName = oImage.getMetadata().getElementName(); oIssueManager.addIssue({ severity: Severity.Low, details: "Image '" + sImageName + "' (" + sImageId + ") has 'densityAware' disabled even though high-density version is also available", context: { id: sImageId } }); }) .catch(function() { // ignore as only the cases of successful executions are of interest to this rule }); }); } }); Promise.all(aAsyncTasks).then(fnResolve); } }; return [oImageRule]; }, true);