insertStyleProperty method

void insertStyleProperty(
  1. StylePropertyOperation op
)

Adds a style-property to the current selection of text. If there is an existing tag around the exact selection, the property gets added to this tag. A -tag will be created otherwise.

Implementation

void insertStyleProperty(StylePropertyOperation op) {
  _cache();

  int opStart = max(0, selection.start);
  int opEnd = max(0, selection.end);

  NodeV3 tree = LightHtmlParserV3().parse(text);

  if (opStart == opEnd) {
    var startTag = "<span style=\"${op.propertyKey}:${op.propertyValue}\">";
    var endTag = "</span>";

    print(text);
    print(opStart);
    print(opEnd);

    text = text.substring(0, opStart) +
        "$startTag$endTag" +
        text.substring(opStart);
    opStart += startTag.length;
    opEnd += startTag.length;
    tree = LightHtmlParserV3().parse(text);
  } else {
    bool wasOffset2 = false, wasOffset = false;

    // pass 1: split only partly affected nodes into new simple nodes
    List<NodeV3> affectedNodes = tree.select(opStart, opEnd);
    affectedNodes.forEach((element) {
      element.splitForSelection(opStart, opEnd);
    });
    affectedNodes = tree.select(opStart, opEnd);

    // pass 2: insert spans for not fully selected nodes
    affectedNodes
        .where((element) =>
            element.parent!.isRoot ||
            !element.parent!.isFullySelected(opStart, opEnd))
        .forEach((element) {
      var tag = Tag.decodeTag("<span>");
      element.insertTagNodeAbove(tag);

      if (!wasOffset) {
        opStart += tag.size;
        wasOffset = true;
      }

      opEnd += tag.endTagSize + tag.size;
    });

    // pass 2: insert/append style tags into selected nodes
    for (NodeV3 affectedNode in affectedNodes) {
      NodeV3 affectedParent = affectedNode.parent!;

      // 2.1 - fully selected parent: add the property to the parent tag
      if (affectedParent.isTag) {
        Tag parentTag = affectedParent.tag!;

        var lengthBefore = parentTag.rawTag.length;
        parentTag.putStyleProperty(op.propertyKey, op.propertyValue);

        int offset = parentTag.rawTag.length - lengthBefore;

        // move the start value to the start of the piece of content that gets wrapped with the style
        if (!wasOffset2) {
          opStart += offset;
          opEnd = opStart + affectedNode.content!.length;
          wasOffset2 = true;
        }
      }
    }
  }

  if (editorFocusNode != null) {
    editorFocusNode!.requestFocus();
  }

  value = value.copyWith(
    text: tree.toHtml(),
    selection: TextSelection(baseOffset: opStart, extentOffset: opEnd),
  );
}