flushPendingProperties method

void flushPendingProperties()

Implementation

void flushPendingProperties() {
  Element? target = this.target;
  // If style target element not exists, no need to do flush operation.
  if (target == null) return;

  // Display change from none to other value that the renderBoxModel is null.
  if (_pendingProperties.containsKey(DISPLAY) && target.isConnected) {
    CSSPropertyValue? prevValue = _properties[DISPLAY];
    CSSPropertyValue currentValue = _pendingProperties[DISPLAY]!;
    _properties[DISPLAY] = currentValue;
    _pendingProperties.remove(DISPLAY);
    _emitPropertyChanged(DISPLAY, prevValue?.value, currentValue.value, baseHref: currentValue.baseHref);
  }

  if (_pendingProperties.isEmpty) {
    return;
  }

  Map<String, CSSPropertyValue> pendingProperties = _pendingProperties;
  // Reset first avoid set property in flush stage.
  _pendingProperties = {};

  final List<String> pendingKeys = pendingProperties.keys.toList(growable: false);
  final Set<String> remainingKeys = pendingKeys.toSet();

  // Keep ordering behavior consistent with previous implementation:
  // 1. Move properties in `_propertyOrders` to the front.
  // 2. Preserve pending insertion order for the rest.
  final List<String> reorderedKeys = <String>[];
  for (final String propertyName in _propertyOrders.reversed) {
    if (remainingKeys.remove(propertyName)) {
      reorderedKeys.add(propertyName);
    }
  }
  for (final String propertyName in pendingKeys) {
    if (remainingKeys.contains(propertyName)) {
      reorderedKeys.add(propertyName);
    }
  }

  // Stable partition: CSS variables should be flushed first.
  final List<String> propertyNames = <String>[];
  for (final String propertyName in reorderedKeys) {
    if (CSSVariable.isCSSSVariableProperty(propertyName)) {
      propertyNames.add(propertyName);
    }
  }
  for (final String propertyName in reorderedKeys) {
    if (!CSSVariable.isCSSSVariableProperty(propertyName)) {
      propertyNames.add(propertyName);
    }
  }

  final Map<String, CSSPropertyValue?> prevValues = <String, CSSPropertyValue?>{};
  for (final MapEntry<String, CSSPropertyValue> entry in pendingProperties.entries) {
    prevValues[entry.key] = _properties[entry.key];
    _properties[entry.key] = entry.value;
  }

  for (String propertyName in propertyNames) {
    CSSPropertyValue? prevValue = prevValues[propertyName];
    CSSPropertyValue currentValue = pendingProperties[propertyName]!;
    _emitPropertyChanged(propertyName, prevValue?.value, currentValue.value, baseHref: currentValue.baseHref);
  }

  onStyleFlushed?.call(propertyNames);
}