Liferay.Loader.define("journal-web$codemirror@5.65.12/src/model/mark_text", ['module', 'exports', 'require'], function (module, exports, require) {
  var define = undefined;
  var global = window;
  {
    import { eltP } from "../util/dom.js";
    import { eventMixin, hasHandler, on } from "../util/event.js";
    import { endOperation, operation, runInOp, startOperation } from "../display/operations.js";
    import { clipPos, cmp, Pos } from "../line/pos.js";
    import { lineNo, updateLineHeight } from "../line/utils_line.js";
    import { clearLineMeasurementCacheFor, findViewForLine, textHeight } from "../measurement/position_measurement.js";
    import { seeReadOnlySpans, seeCollapsedSpans } from "../line/saw_special_spans.js";
    import { addMarkedSpan, conflictingCollapsedRange, getMarkedSpanFor, lineIsHidden, lineLength, MarkedSpan, removeMarkedSpan, visualLine } from "../line/spans.js";
    import { copyObj, indexOf, lst } from "../util/misc.js";
    import { signalLater } from "../util/operation_group.js";
    import { widgetHeight } from "../measurement/widgets.js";
    import { regChange, regLineChange } from "../display/view_tracking.js";

    import { linkedDocs } from "./document_data.js";
    import { addChangeToHistory } from "./history.js";
    import { reCheckSelection } from "./selection_updates.js";

    // TEXTMARKERS

    // Created with markText and setBookmark methods. A TextMarker is a
    // handle that can be used to clear or find a marked position in the
    // document. Line objects hold arrays (markedSpans) containing
    // {from, to, marker} object pointing to such marker objects, and
    // indicating that such a marker is present on that line. Multiple
    // lines may point to the same marker when it spans across lines.
    // The spans will have null for their from/to properties when the
    // marker continues beyond the start/end of the line. Markers have
    // links back to the lines they currently touch.

    // Collapsed markers have unique ids, in order to be able to order
    // them, which is needed for uniquely determining an outer marker
    // when they overlap (they may nest, but not partially overlap).
    let nextMarkerId = 0;

    export class TextMarker {
      constructor(doc, type) {
        this.lines = [];
        this.type = type;
        this.doc = doc;
        this.id = ++nextMarkerId;
      }

      // Clear the marker.
      clear() {
        if (this.explicitlyCleared) return;
        let cm = this.doc.cm,
            withOp = cm && !cm.curOp;
        if (withOp) startOperation(cm);
        if (hasHandler(this, "clear")) {
          let found = this.find();
          if (found) signalLater(this, "clear", found.from, found.to);
        }
        let min = null,
            max = null;
        for (let i = 0; i < this.lines.length; ++i) {
          let line = this.lines[i];
          let span = getMarkedSpanFor(line.markedSpans, this);
          if (cm && !this.collapsed) regLineChange(cm, lineNo(line), "text");else if (cm) {
            if (span.to != null) max = lineNo(line);
            if (span.from != null) min = lineNo(line);
          }
          line.markedSpans = removeMarkedSpan(line.markedSpans, span);
          if (span.from == null && this.collapsed && !lineIsHidden(this.doc, line) && cm) updateLineHeight(line, textHeight(cm.display));
        }
        if (cm && this.collapsed && !cm.options.lineWrapping) for (let i = 0; i < this.lines.length; ++i) {
          let visual = visualLine(this.lines[i]),
              len = lineLength(visual);
          if (len > cm.display.maxLineLength) {
            cm.display.maxLine = visual;
            cm.display.maxLineLength = len;
            cm.display.maxLineChanged = true;
          }
        }

        if (min != null && cm && this.collapsed) regChange(cm, min, max + 1);
        this.lines.length = 0;
        this.explicitlyCleared = true;
        if (this.atomic && this.doc.cantEdit) {
          this.doc.cantEdit = false;
          if (cm) reCheckSelection(cm.doc);
        }
        if (cm) signalLater(cm, "markerCleared", cm, this, min, max);
        if (withOp) endOperation(cm);
        if (this.parent) this.parent.clear();
      }

      // Find the position of the marker in the document. Returns a {from,
      // to} object by default. Side can be passed to get a specific side
      // -- 0 (both), -1 (left), or 1 (right). When lineObj is true, the
      // Pos objects returned contain a line object, rather than a line
      // number (used to prevent looking up the same line twice).
      find(side, lineObj) {
        if (side == null && this.type == "bookmark") side = 1;
        let from, to;
        for (let i = 0; i < this.lines.length; ++i) {
          let line = this.lines[i];
          let span = getMarkedSpanFor(line.markedSpans, this);
          if (span.from != null) {
            from = Pos(lineObj ? line : lineNo(line), span.from);
            if (side == -1) return from;
          }
          if (span.to != null) {
            to = Pos(lineObj ? line : lineNo(line), span.to);
            if (side == 1) return to;
          }
        }
        return from && { from: from, to: to };
      }

      // Signals that the marker's widget changed, and surrounding layout
      // should be recomputed.
      changed() {
        let pos = this.find(-1, true),
            widget = this,
            cm = this.doc.cm;
        if (!pos || !cm) return;
        runInOp(cm, () => {
          let line = pos.line,
              lineN = lineNo(pos.line);
          let view = findViewForLine(cm, lineN);
          if (view) {
            clearLineMeasurementCacheFor(view);
            cm.curOp.selectionChanged = cm.curOp.forceUpdate = true;
          }
          cm.curOp.updateMaxLine = true;
          if (!lineIsHidden(widget.doc, line) && widget.height != null) {
            let oldHeight = widget.height;
            widget.height = null;
            let dHeight = widgetHeight(widget) - oldHeight;
            if (dHeight) updateLineHeight(line, line.height + dHeight);
          }
          signalLater(cm, "markerChanged", cm, this);
        });
      }

      attachLine(line) {
        if (!this.lines.length && this.doc.cm) {
          let op = this.doc.cm.curOp;
          if (!op.maybeHiddenMarkers || indexOf(op.maybeHiddenMarkers, this) == -1) (op.maybeUnhiddenMarkers || (op.maybeUnhiddenMarkers = [])).push(this);
        }
        this.lines.push(line);
      }

      detachLine(line) {
        this.lines.splice(indexOf(this.lines, line), 1);
        if (!this.lines.length && this.doc.cm) {
          let op = this.doc.cm.curOp;(op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this);
        }
      }
    }
    eventMixin(TextMarker);

    // Create a marker, wire it up to the right lines, and
    export function markText(doc, from, to, options, type) {
      // Shared markers (across linked documents) are handled separately
      // (markTextShared will call out to this again, once per
      // document).
      if (options && options.shared) return markTextShared(doc, from, to, options, type);
      // Ensure we are in an operation.
      if (doc.cm && !doc.cm.curOp) return operation(doc.cm, markText)(doc, from, to, options, type);

      let marker = new TextMarker(doc, type),
          diff = cmp(from, to);
      if (options) copyObj(options, marker, false);
      // Don't connect empty markers unless clearWhenEmpty is false
      if (diff > 0 || diff == 0 && marker.clearWhenEmpty !== false) return marker;
      if (marker.replacedWith) {
        // Showing up as a widget implies collapsed (widget replaces text)
        marker.collapsed = true;
        marker.widgetNode = eltP("span", [marker.replacedWith], "CodeMirror-widget");
        if (!options.handleMouseEvents) marker.widgetNode.setAttribute("cm-ignore-events", "true");
        if (options.insertLeft) marker.widgetNode.insertLeft = true;
      }
      if (marker.collapsed) {
        if (conflictingCollapsedRange(doc, from.line, from, to, marker) || from.line != to.line && conflictingCollapsedRange(doc, to.line, from, to, marker)) throw new Error("Inserting collapsed marker partially overlapping an existing one");
        seeCollapsedSpans();
      }

      if (marker.addToHistory) addChangeToHistory(doc, { from: from, to: to, origin: "markText" }, doc.sel, NaN);

      let curLine = from.line,
          cm = doc.cm,
          updateMaxLine;
      doc.iter(curLine, to.line + 1, line => {
        if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(line) == cm.display.maxLine) updateMaxLine = true;
        if (marker.collapsed && curLine != from.line) updateLineHeight(line, 0);
        addMarkedSpan(line, new MarkedSpan(marker, curLine == from.line ? from.ch : null, curLine == to.line ? to.ch : null), doc.cm && doc.cm.curOp);
        ++curLine;
      });
      // lineIsHidden depends on the presence of the spans, so needs a second pass
      if (marker.collapsed) doc.iter(from.line, to.line + 1, line => {
        if (lineIsHidden(doc, line)) updateLineHeight(line, 0);
      });

      if (marker.clearOnEnter) on(marker, "beforeCursorEnter", () => marker.clear());

      if (marker.readOnly) {
        seeReadOnlySpans();
        if (doc.history.done.length || doc.history.undone.length) doc.clearHistory();
      }
      if (marker.collapsed) {
        marker.id = ++nextMarkerId;
        marker.atomic = true;
      }
      if (cm) {
        // Sync editor state
        if (updateMaxLine) cm.curOp.updateMaxLine = true;
        if (marker.collapsed) regChange(cm, from.line, to.line + 1);else if (marker.className || marker.startStyle || marker.endStyle || marker.css || marker.attributes || marker.title) for (let i = from.line; i <= to.line; i++) regLineChange(cm, i, "text");
        if (marker.atomic) reCheckSelection(cm.doc);
        signalLater(cm, "markerAdded", cm, marker);
      }
      return marker;
    }

    // SHARED TEXTMARKERS

    // A shared marker spans multiple linked documents. It is
    // implemented as a meta-marker-object controlling multiple normal
    // markers.
    export class SharedTextMarker {
      constructor(markers, primary) {
        this.markers = markers;
        this.primary = primary;
        for (let i = 0; i < markers.length; ++i) markers[i].parent = this;
      }

      clear() {
        if (this.explicitlyCleared) return;
        this.explicitlyCleared = true;
        for (let i = 0; i < this.markers.length; ++i) this.markers[i].clear();
        signalLater(this, "clear");
      }

      find(side, lineObj) {
        return this.primary.find(side, lineObj);
      }
    }
    eventMixin(SharedTextMarker);

    function markTextShared(doc, from, to, options, type) {
      options = copyObj(options);
      options.shared = false;
      let markers = [markText(doc, from, to, options, type)],
          primary = markers[0];
      let widget = options.widgetNode;
      linkedDocs(doc, doc => {
        if (widget) options.widgetNode = widget.cloneNode(true);
        markers.push(markText(doc, clipPos(doc, from), clipPos(doc, to), options, type));
        for (let i = 0; i < doc.linked.length; ++i) if (doc.linked[i].isParent) return;
        primary = lst(markers);
      });
      return new SharedTextMarker(markers, primary);
    }

    export function findSharedMarkers(doc) {
      return doc.findMarks(Pos(doc.first, 0), doc.clipPos(Pos(doc.lastLine())), m => m.parent);
    }

    export function copySharedMarkers(doc, markers) {
      for (let i = 0; i < markers.length; i++) {
        let marker = markers[i],
            pos = marker.find();
        let mFrom = doc.clipPos(pos.from),
            mTo = doc.clipPos(pos.to);
        if (cmp(mFrom, mTo)) {
          let subMark = markText(doc, mFrom, mTo, marker.primary, marker.primary.type);
          marker.markers.push(subMark);
          subMark.parent = marker;
        }
      }
    }

    export function detachSharedMarkers(markers) {
      for (let i = 0; i < markers.length; i++) {
        let marker = markers[i],
            linked = [marker.primary.doc];
        linkedDocs(marker.primary.doc, d => linked.push(d));
        for (let j = 0; j < marker.markers.length; j++) {
          let subMarker = marker.markers[j];
          if (indexOf(linked, subMarker.doc) == -1) {
            subMarker.parent = null;
            marker.markers.splice(j--, 1);
          }
        }
      }
    }
  }
});
//# sourceMappingURL=mark_text.js.map