<commit_before>import {TextSelection, NodeSelection} from "prosemirror-state"

import browser from "./browser"
import {selectionCollapsed, isEquivalentPosition} from "./dom"

export function selectionFromDOM(view, origin) {
  let domSel = view.root.getSelection(), doc = view.state.doc
  let nearestDesc = view.docView.nearestDesc(domSel.focusNode), inWidget = nearestDesc && nearestDesc.size == 0
  let head = view.docView.posFromDOM(domSel.focusNode, domSel.focusOffset)
  let $head = doc.resolve(head), $anchor, selection
  if (selectionCollapsed(domSel)) {
    $anchor = $head
    while (nearestDesc && !nearestDesc.node) nearestDesc = nearestDesc.parent
    if (nearestDesc && nearestDesc.node.isAtom && NodeSelection.isSelectable(nearestDesc.node) && nearestDesc.parent) {
      let pos = nearestDesc.posBefore
      selection = new NodeSelection(head == pos ? $head : doc.resolve(pos))
    }
  } else {
    $anchor = doc.resolve(view.docView.posFromDOM(domSel.anchorNode, domSel.anchorOffset))
  }

  if (!selection) {
    let bias = origin == "pointer" || (view.state.selection.head < $head.pos && !inWidget) ? 1 : -1
    selection = selectionBetween(view, $anchor, $head, bias)
  }
  return selection
}

export function selectionToDOM(view, takeFocus, force) {
  let sel = view.state.selection
  syncNodeSelection(view, sel)

  if (view.editable && !view.hasFocus()) {
    if (!takeFocus) return
    // See https://bugzilla.mozilla.org/show_bug.cgi?id=921444
    if (browser.gecko && browser.gecko_version <= 55) {
      view.domObserver.disconnectSelection()
      view.dom.focus()
      view.domObserver.connectSelection()
    }
  } else if (!view.editable && !hasSelection(view) && !takeFocus) {
    return
  }

  view.domObserver.disconnectSelection()

  if (view.cursorWrapper) {
    selectCursorWrapper(view)
  } else {
    let {anchor, head} = sel, resetEditableFrom, resetEditableTo
    if (brokenSelectBetweenUneditable && !(sel instanceof TextSelection)) {
      if (!sel.$from.parent.inlineContent)
        resetEditableFrom = temporarilyEditableNear(view, sel.from)
      if (!sel.empty && !sel.$from.parent.inlineContent)
        resetEditableTo = temporarilyEditableNear(view, sel.to)
    }
    view.docView.setSelection(anchor, head, view.root, force)
    if (brokenSelectBetweenUneditable) {<commit_msg>Don't update DOM selection in uneditable editors when the focus is elsewhere<commit_after>import {TextSelection, NodeSelection} from "prosemirror-state"

import browser from "./browser"
import {selectionCollapsed, isEquivalentPosition} from "./dom"

export function selectionFromDOM(view, origin) {
  let domSel = view.root.getSelection(), doc = view.state.doc
  let nearestDesc = view.docView.nearestDesc(domSel.focusNode), inWidget = nearestDesc && nearestDesc.size == 0
  let head = view.docView.posFromDOM(domSel.focusNode, domSel.focusOffset)
  let $head = doc.resolve(head), $anchor, selection
  if (selectionCollapsed(domSel)) {
    $anchor = $head
    while (nearestDesc && !nearestDesc.node) nearestDesc = nearestDesc.parent
    if (nearestDesc && nearestDesc.node.isAtom && NodeSelection.isSelectable(nearestDesc.node) && nearestDesc.parent) {
      let pos = nearestDesc.posBefore
      selection = new NodeSelection(head == pos ? $head : doc.resolve(pos))
    }
  } else {
    $anchor = doc.resolve(view.docView.posFromDOM(domSel.anchorNode, domSel.anchorOffset))
  }

  if (!selection) {
    let bias = origin == "pointer" || (view.state.selection.head < $head.pos && !inWidget) ? 1 : -1
    selection = selectionBetween(view, $anchor, $head, bias)
  }
  return selection
}

export function selectionToDOM(view, takeFocus, force) {
  let sel = view.state.selection
  syncNodeSelection(view, sel)

  if (view.editable && !view.hasFocus()) {
    if (!takeFocus) return
    // See https://bugzilla.mozilla.org/show_bug.cgi?id=921444
    if (browser.gecko && browser.gecko_version <= 55) {
      view.domObserver.disconnectSelection()
      view.dom.focus()
      view.domObserver.connectSelection()
    }
  } else if (!view.editable && !(hasSelection(view) && document.activeElement.contains(view.dom)) && !takeFocus) {
    return
  }

  view.domObserver.disconnectSelection()

  if (view.cursorWrapper) {
    selectCursorWrapper(view)
  } else {
    let {anchor, head} = sel, resetEditableFrom, resetEditableTo
    if (brokenSelectBetweenUneditable && !(sel instanceof TextSelection)) {
      if (!sel.$from.parent.inlineContent)
        resetEditableFrom = temporarilyEditableNear(view, sel.from)
      if (!sel.empty && !sel.$from.parent.inlineContent)
        resetEditableTo = temporarilyEditableNear(view, sel.to)
    }
    view.docView.setSelection(anchor, head, view.root, force)
    if (brokenSelectBetweenUneditable) {
{'fraction_non_alphanumeric': 0.1263113722198909, 'fraction_numerical': 0.004616030214015947, 'mean_word_length': 4.131324004305705, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 3, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '758881', 'n_tokens_mistral': 1513, 'n_tokens_neox': 1453, 'n_words': 308}