parseLength static method

CSSLengthValue parseLength(
  1. String text,
  2. RenderStyle? renderStyle, [
  3. String? propertyName,
  4. Axis? axisType,
])

Implementation

static CSSLengthValue parseLength(String text, RenderStyle? renderStyle, [String? propertyName, Axis? axisType]) {
  double? value;
  CSSLengthType unit = CSSLengthType.PX;
  if (text == ZERO) {
    // Only '0' is accepted with no unit.
    return CSSLengthValue.zero;
  } else if (text == INITIAL) {
    return CSSLengthValue.initial;
  } else if (text == INHERIT) {
    // Per CSS Cascade, `inherit` sets the computed value on the element to
    // the computed value of its parent. For <length-percentage> properties,
    // this means percentage should remain a percentage (e.g. `100%`) and then
    // be resolved against the *child's* containing block during layout.
    //
    // Avoid resolving percentages using the parent's containing block (which
    // would incorrectly turn `100%` into an absolute px length here).
    if (renderStyle != null && propertyName != null) {
      final parent = renderStyle.target.parentElement;
      if (parent != null) {
        final dynamic parentComputed = parent.renderStyle.getProperty(propertyName);
        if (parentComputed is CSSLengthValue) {
          final String computedText = parentComputed.cssText();
          if (computedText.isNotEmpty) {
            return parseLength(computedText, renderStyle, propertyName, axisType);
          }
        }

        // Fallback to parent's serialized specified value when computed is unavailable.
        final String specified = parent.style.getPropertyValue(propertyName);
        if (specified.isNotEmpty) {
          return parseLength(specified, renderStyle, propertyName, axisType);
        }
      }

      // Root element (or missing parent): fall back to initial value.
      final String initialValue = (cssInitialValues[propertyName] as String?) ?? AUTO;
      return parseLength(initialValue, renderStyle, propertyName, axisType);
    }

    return CSSLengthValue.unknown;
  } else if (text == AUTO) {
    return CSSLengthValue.auto;
  } else if (text == NONE) {
    return CSSLengthValue.none;
  } else if (text.toLowerCase() == 'content') {
    // flex-basis: content
    return CSSLengthValue(null, CSSLengthType.CONTENT, renderStyle, propertyName, axisType);
  } else if (text.toLowerCase() == 'min-content') {
    return CSSLengthValue(null, CSSLengthType.MIN_CONTENT, renderStyle, propertyName, axisType);
  } else if (text.toLowerCase() == 'max-content') {
    return CSSLengthValue(null, CSSLengthType.MAX_CONTENT, renderStyle, propertyName, axisType);
  } else if (text.toLowerCase() == 'fit-content') {
    return CSSLengthValue(null, CSSLengthType.FIT_CONTENT, renderStyle, propertyName, axisType);
  } else if (text.endsWith(REM)) {
    value = double.tryParse(text.split(REM)[0]);
    unit = CSSLengthType.REM;
  } else if (text.endsWith(EM)) {
    value = double.tryParse(text.split(EM)[0]);
    unit = CSSLengthType.EM;
  } else if (text.endsWith(EX)) {
    value = double.tryParse(text.split(EX)[0]);
    unit = CSSLengthType.EX;
  } else if (text.endsWith(CH)) {
    value = double.tryParse(text.split(CH)[0]);
    unit = CSSLengthType.CH;
  } else if (text.endsWith(RPX)) {
    value = double.tryParse(text.split(RPX)[0]);
    unit = CSSLengthType.RPX;
  } else if (text.endsWith(PX)) {
    value = double.tryParse(text.split(PX)[0]);
  } else if (text.endsWith(VW)) {
    value = double.tryParse(text.split(VW)[0]);
    if (value != null) value = value / 100;
    unit = CSSLengthType.VW;
  } else if (text.endsWith(VH)) {
    value = double.tryParse(text.split(VH)[0]);
    if (value != null) value = value / 100;
    unit = CSSLengthType.VH;
  } else if (text.endsWith(CM)) {
    value = double.tryParse(text.split(CM)[0]);
    if (value != null) value = value * _1cm;
  } else if (text.endsWith(MM)) {
    value = double.tryParse(text.split(MM)[0]);
    if (value != null) value = value * _1mm;
  } else if (text.endsWith(PC)) {
    value = double.tryParse(text.split(PC)[0]);
    if (value != null) value = value * _1pc;
  } else if (text.endsWith(PT)) {
    value = double.tryParse(text.split(PT)[0]);
    if (value != null) value = value * _1pt;
  } else if (text.endsWith(VMIN)) {
    value = double.tryParse(text.split(VMIN)[0]);
    if (value != null) value = value / 100;
    unit = CSSLengthType.VMIN;
  } else if (text.endsWith(VMAX)) {
    value = double.tryParse(text.split(VMAX)[0]);
    if (value != null) value = value / 100;
    unit = CSSLengthType.VMAX;
  } else if (text.endsWith(IN)) {
    value = double.tryParse(text.split(IN)[0]);
    if (value != null) value = value * _1in;
  } else if (text.endsWith(Q)) {
    value = double.tryParse(text.split(Q)[0]);
    if (value != null) value = value * _1Q;
  } else if (text.endsWith(PERCENTAGE)) {
    value = double.tryParse(text.split(PERCENTAGE)[0]);
    if (value != null) value = value / 100;
    unit = CSSLengthType.PERCENTAGE;
  } else if (CSSFunction.isFunction(text)) {
    if (renderStyle != null) {
      CSSCalcValue? calcValue = CSSCalcValue.tryParse(renderStyle, propertyName ?? '', text);
      if (calcValue != null) {
        return CSSLengthValue.calc(calcValue, renderStyle, propertyName);
      }
    }
  } else {
    value = double.tryParse(text);
  }

  if (value == 0 && unit != CSSLengthType.PERCENTAGE) {
    return CSSLengthValue.zero;
  } else if (value == null) {
    return CSSLengthValue.unknown;
  } else if (unit == CSSLengthType.PX) {
    return CSSLengthValue(value, unit);
  } else {
    return CSSLengthValue(value, unit, renderStyle, propertyName, axisType);
  }
}