renderElement method

void renderElement(
  1. Element element,
  2. CodeBuffer buffer,
  3. SymbolTable scope,
  4. bool html5
)

Implementation

void renderElement(
    Element element, CodeBuffer buffer, SymbolTable scope, bool html5) {
  var childScope = scope.createChild();

  if (element.attributes.any((a) => a.name == 'for-each')) {
    renderForeach(element, buffer, childScope, html5);
    return;
  } else if (element.attributes.any((a) => a.name == 'if')) {
    renderIf(element, buffer, childScope, html5);
    return;
  } else if (element.tagName.name == 'declare') {
    renderDeclare(element, buffer, childScope, html5);
    return;
  } else if (element.tagName.name == 'switch') {
    renderSwitch(element, buffer, childScope, html5);
    return;
  } else if (element.tagName.name == 'element') {
    registerCustomElement(element, buffer, childScope, html5);
    return;
  } else {
    var customElementValue =
        scope.resolve(customElementName(element.tagName.name))?.value;

    if (customElementValue is Element) {
      renderCustomElement(element, buffer, childScope, html5);
      return;
    }
  }

  buffer
    ..write('<')
    ..write(element.tagName.name);

  for (var attribute in element.attributes) {
    var value = attribute.value?.compute(childScope);

    if (value == false || value == null) continue;

    buffer.write(' ${attribute.name}');

    if (value == true) {
      continue;
    } else {
      buffer.write('="');
    }

    String msg;

    if (value is Iterable) {
      msg = value.join(' ');
    } else if (value is Map) {
      msg = value.keys.fold<StringBuffer>(StringBuffer(), (buf, k) {
        var v = value[k];
        if (v == null) return buf;
        return buf..write('$k: $v;');
      }).toString();
    } else {
      msg = value.toString();
    }

    buffer.write(attribute.isRaw ? msg : htmlEscape.convert(msg));
    buffer.write('"');
  }

  if (element is SelfClosingElement) {
    if (html5) {
      buffer.writeln('>');
    } else {
      buffer.writeln('/>');
    }
  } else {
    buffer.writeln('>');
    buffer.indent();

    for (var i = 0; i < element.children.length; i++) {
      var child = element.children.elementAt(i);
      renderElementChild(element, child, buffer, childScope, html5, i,
          element.children.length);
    }

    buffer.writeln();
    buffer.outdent();
    buffer.writeln('</${element.tagName.name}>');
  }
}