/*
 * Copyright (c) 2018, 2025, Oracle and/or its affiliates.
 * Licensed under The Universal Permissive License (UPL), Version 1.0
 * as shown at https://oss.oracle.com/licenses/upl/
 */
const{LENGTH_MEMBER_PROP_SET}=require("./helpers/cssHelper");const RULENAME="oj-tsx-style-abs-units";const DESCRIPTION="In general it is preferable to use relative length units in place of absolute units. "+"Specifically, 'rem' units are recommended because they proportionately adjust to the root "+"font size.  'rem' can be used for anything that takes a length unit - e.g. font-size, line-height, "+"width, height, padding, margin, etc.  However, there are cases where absolute units are "+"required.  This project is configured to allow absolute units in selector names that include "+"one of the following terms: 'image, and 'picture'.";const SHORT_DESCRIPTION="In general it is preferable to use relative length units in place of absolute units.";const ABS_UNITS=["px","cm","mm","in","pt","pc","all"];const COLON=":";const ALL="all";const NUMBER="number";class Rule{getName(){return RULENAME}getDescription(){return DESCRIPTION}getShortDescription(){return SHORT_DESCRIPTION}register(regCtx){this._tsxUtils=regCtx.utils.tsxUtils;if(!this._checkRuleOptions(regCtx)){return false}return{"Tsx<style=>":this._onStyle}}_onStyle(ruleCtx,tsxProp){var prop,values,val,unit;this._CssUtils=ruleCtx.utils.CssUtils;if((values=this._tsxUtils.getPropertyStringValue(tsxProp))!==null){values=_convertToObj(values)}else{values=this._tsxUtils.getExpressionObject(tsxProp)}if(values){let style;for(style in values){if(val=values[style]){if(!LENGTH_MEMBER_PROP_SET.has(style)){continue}{if(unit=_hasAbsUnits(val)){this._prop(ruleCtx,style,val,unit)}}}}}}_prop(ruleCtx,prop,val,unit){var m,qty,s,i;m=val.match(/[0-9]+(px|cm|mm|in|pt|pc)/g);if(m&&m.length){for(i=0;i<m.length;i++){s=m[i];unit=s.substring(s.length-2);qty=s.substring(0,s.length-unit.length);qty=parseInt(qty);if(!this._okThreshold(unit,qty)||qty===0){this._emitIssue(ruleCtx,prop,m[i],unit,qty)}}}else if(_isExpr(val)){this._emitIssue2(ruleCtx,prop,val,unit)}}_emitIssue(ruleCtx,prop,val,unit,qty){var issue,unit;if(qty){issue=new ruleCtx.Issue(`style '${prop}' value '${val}' - best practices: replace absolute unit '${unit}' with a relative unit (e.g. 'rem' or '%')`)}else{issue=new ruleCtx.Issue(`style '${prop}' value '${val}' - best practices: remove '${unit}' for zero quantity`);issue.setMsgKey(RULENAME+"_1");issue.setSeverity("minor")}if(issue){this._reportIssue(ruleCtx,issue)}}_emitIssue2(ruleCtx,prop,val,unit){var issue;issue=new ruleCtx.Issue(`style '${prop}' expression '${val}' generates a '${unit}' length - best practices: convert to a relative unit (e.g. 'rem' or '%')`);issue.setMsgKey(RULENAME+"_2");this._reportIssue(ruleCtx,issue)}_reportIssue(ruleCtx,issue){this._tsxUtils.setIssuePosition(issue,ruleCtx.node);ruleCtx.reporter.addIssue(issue,ruleCtx)}_okThreshold(unit,qty){var th;if(!this._unitOpts||typeof qty!==NUMBER){return true}th=this._unitOpts[unit];if(th===undefined){th=this._unitOpts[ALL]}return th?Math.abs(qty)<=th:true}_checkRuleOptions(regCtx){var units,unit,th,b,customOpts;if(customOpts=regCtx.ruleOpts.customOpts){if(units=customOpts.absunits){if(!regCtx.utils.utils.isObject(units)){regCtx.utils.msgLib.error(`Rule ${regCtx.ruleName} :  option 'absunits' is not an object`);this._fail=true;return false}for(unit in units){if(!ABS_UNITS.includes(unit)){regCtx.utils.msgLib.error(`Rule ${regCtx.ruleName} :  option 'absunits' value '${unit}' is not absolute`);b=true;continue}if(units.hasOwnProperty(unit)){th=units[unit];if(typeof th!==NUMBER){regCtx.utils.msgLib.error(`Rule ${regCtx.ruleName} :  option 'absunits' threshold '${th}' is not a number`);b=true}}}this._unitOpts=units}}return!b}}function _convertToObj(s){var a,x,elem,prop,val,n=0,obj={};a=s.split(";");if(a?.length){for(i=0;i<a.length;i++){elem=a[i];if((x=elem.indexOf(COLON))>0){prop=elem.substring(0,x).trimEnd();val=elem.substring(x+1).trimStart();n++;obj[prop]=val}}}return n?obj:null}function _hasAbsUnits(s){var expr,unit,start,end,i,x;for(i=0;i<ABS_UNITS.length;i++){unit=ABS_UNITS[i];if(unit!==ALL&&s.includes(unit)){return unit}}expr=_isExpr(s);if(!expr){return false}for(i=0;i<ABS_UNITS.length;i++){unit=ABS_UNITS[i];if(unit===ALL){continue}x=s.indexOf(unit);if(x>=0){end=s[x+1];start=s[x-1].toLowerCase();if(start==="."||start==="+"||start.match(/[a-z]/i)){continue}return unit}}return false};function _isExpr(s){return s.includes("$")};module.exports=Rule;