docs: function buildLineContent(cm, lineView) {
      // The padding-right forces the element to have a 'border', which
      // is needed on Webkit to be able to get line-level bounding
      // rectangles for it (in measureChar).
      var content = elt("span", null, null, webkit ? "padding-right: .1px" : null);
      var builder = {pre: elt("pre", [content]), content: content, col: 0, pos: 0, cm: cm};
      lineView.measure = {};
  
      // Iterate over the logical lines that make up this visual line.
      for (var i = 0; i <= (lineView.rest ? lineView.rest.length : 0); i++) {
        var line = i ? lineView.rest[i - 1] : lineView.line, order;
        builder.pos = 0;
        builder.addToken = buildToken;
        // Optionally wire in some hacks into the token-rendering
        // algorithm, to deal with browser quirks.
        if ((ie || webkit) && cm.getOption("lineWrapping"))
          builder.addToken = buildTokenSplitSpaces(builder.addToken);
        if (hasBadBidiRects(cm.display.measure) && (order = getOrder(line)))
          builder.addToken = buildTokenBadBidi(builder.addToken, order);
        builder.map = [];
        var allowFrontierUpdate = lineView != cm.display.externalMeasured && lineNo(line);
        insertLineContent(line, builder, getLineStyles(cm, line, allowFrontierUpdate));
        if (line.styleClasses) {
          if (line.styleClasses.bgClass)
            builder.bgClass = joinClasses(line.styleClasses.bgClass, builder.bgClass || "");
          if (line.styleClasses.textClass)
            builder.textClass = joinClasses(line.styleClasses.textClass, builder.textClass || "");
        }
  
        // Ensure at least a single node is present, for measuring.
        if (builder.map.length == 0)
          builder.map.push(0, 0, builder.content.appendChild(zeroWidthElement(cm.display.measure)));
  
        // Store the map and a cache object for the current logical line
        if (i == 0) {
          lineView.measure.map = builder.map;
          lineView.measure.cache = {};
        } else {
          (lineView.measure.maps || (lineView.measure.maps = [])).push(builder.map);
          (lineView.measure.caches || (lineView.measure.caches = [])).push({});
        }
      }
  
      // See issue #2901
      if (webkit && /\bcm-tab\b/.test(builder.content.lastChild.className))
        builder.content.className = "cm-tab-wrap-hack";
  
      signal(cm, "renderLine", cm, lineView.line, builder.pre);
      if (builder.pre.className)
        builder.textClass = joinClasses(builder.pre.className, builder.textClass || "");
  
      return builder;
    }