{"version":3,"sources":["webpack:///./node_modules/y-codemirror/src/y-codemirror.js"],"names":["cmOrigin","typeObserver","binding","event","_mux","cmDoc","cm","getEditor","anchor","indexFromPos","getCursor","head","switchSel","tmp","performChange","delta","index","i","length","d","retain","insert","pos","posFromIndex","replaceRange","delete","start","end","operation","setSelection","scroll","targetObserver","changes","doc","transact","hasPaste","yUndoManager","some","change","origin","stopCapturing","type","toString","getValue","remove","from","delLen","removed","map","s","reduce","text","join","_pendingCursorEvent","emit","createRemoteCaret","username","color","caret","document","createElement","classList","add","setAttribute","userDiv","insertBefore","createTextNode","setTimeout","createEmptyLinePlaceholder","placeholder","emptyTxt","sel","updateRemoteSelection","y","cursors","clientId","awareness","aw","getStates","get","m","undefined","clear","forEach","user","name","cursor","JSON","parse","headpos","anchorpos","to","caretEl","awCursor","line","ch","push","markText","Pos","css","inclusiveRight","inclusiveLeft","setBookmark","widget","insertLeft","set","codemirrorCursorActivity","getLocalState","hasFocus","display","wrapper","ownerDocument","newAnchor","newHead","currentAnchor","currentHead","setLocalStateField","stringify","CodemirrorBinding","textType","codeMirror","super","getDoc","this","_onStackItemAdded","stackItem","changedParentTypes","has","_beforeChangeSelection","meta","_onStackItemPopped","_beforeChange","trackedOrigins","editorUndo","endOperation","undo","startOperation","editorRedo","redo","addKeyMap","on","setValue","_typeObserver","_targetObserver","instance","_cursors","Map","_changedCursors","Set","_debounceCursorEvent","_awarenessListener","f","clientID","added","updated","size","_cursorListener","_blurListeer","observe","unobserve","off","destroy"],"mappings":"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","file":"js/group-homework~061f7a98.75e80daa.js","sourcesContent":["/**\n * @module bindings/textarea\n */\n\nimport { createMutex } from 'lib0/mutex'\nimport * as math from 'lib0/math'\nimport * as Y from 'yjs'\nimport * as func from 'lib0/function'\nimport * as eventloop from 'lib0/eventloop'\nimport { Observable } from 'lib0/observable'\nimport * as diff from 'lib0/diff'\nimport CodeMirror from 'codemirror'\n\nexport const cmOrigin = 'y-codemirror'\n\n/**\n * @param {CodemirrorBinding} binding\n * @param {any} event\n */\nconst typeObserver = (binding, event) => {\n binding._mux(() => {\n const cmDoc = binding.cmDoc\n const cm = cmDoc.getEditor()\n // Normally the position is right-associated\n // But when remote changes happen, it looks like the remote user is hijacking your position.\n // Just for remote insertions, we make the collapsed cursor left-associated.\n // If selection is not collapsed, we only make \"to\" left associated\n let anchor = cm.indexFromPos(cm.getCursor('anchor'))\n let head = cm.indexFromPos(cm.getCursor('head'))\n const switchSel = head < anchor\n // normalize selection so that anchor < head, switch back later\n if (switchSel) {\n const tmp = head\n head = anchor\n anchor = tmp\n }\n const performChange = () => {\n const delta = event.delta\n let index = 0\n for (let i = 0; i < event.delta.length; i++) {\n const d = delta[i]\n if (d.retain) {\n index += d.retain\n } else if (d.insert) {\n if (index < anchor || (anchor < head && index === anchor)) {\n anchor += d.insert.length\n }\n if (index < head) {\n head += d.insert.length\n }\n const pos = cmDoc.posFromIndex(index)\n cmDoc.replaceRange(d.insert, pos, pos, cmOrigin)\n index += d.insert.length\n } else if (d.delete) {\n if (index < anchor) {\n anchor = math.max(anchor - d.delete, index)\n }\n if (index < head) {\n head = math.max(head - d.delete, index)\n }\n const start = cmDoc.posFromIndex(index)\n const end = cmDoc.posFromIndex(index + d.delete)\n cmDoc.replaceRange('', start, end, cmOrigin)\n }\n }\n }\n // if possible, bundle the changes using cm.operation\n if (cm) {\n cm.operation(performChange)\n } else {\n performChange()\n }\n if (switchSel) {\n const tmp = head\n head = anchor\n anchor = tmp\n }\n cm.setSelection(cm.posFromIndex(anchor), cm.posFromIndex(head), { scroll: false })\n })\n}\n\n/**\n * @param {CodemirrorBinding} binding\n * @param {Array} changes\n */\nconst targetObserver = (binding, changes) => {\n binding._mux(() => {\n binding.doc.transact(() => {\n const hasPaste = binding.yUndoManager && changes.some(change => change.origin === 'paste')\n if (hasPaste) {\n binding.yUndoManager.stopCapturing()\n }\n\n if (changes.length > 1) {\n // If there are several consecutive changes, we can't reliably compute the positions anymore. See y-codemirror#11\n // Instead, we will compute the diff and apply the changes\n const d = diff.simpleDiffString(binding.type.toString(), binding.cmDoc.getValue())\n binding.type.delete(d.index, d.remove)\n binding.type.insert(d.index, d.insert)\n } else {\n const change = changes[0]\n const start = binding.cmDoc.indexFromPos(change.from)\n const delLen = change.removed.map(s => s.length).reduce(math.add) + change.removed.length - 1\n if (delLen > 0) {\n binding.type.delete(start, delLen)\n }\n if (change.text.length > 0) {\n binding.type.insert(start, change.text.join('\\n'))\n }\n }\n\n if (hasPaste) {\n binding.yUndoManager.stopCapturing()\n }\n }, binding)\n })\n if (binding._pendingCursorEvent) {\n binding._pendingCursorEvent = false\n binding.emit('cursorActivity', [binding])\n }\n}\n\nconst createRemoteCaret = (username, color) => {\n const caret = document.createElement('span')\n caret.classList.add('remote-caret')\n caret.setAttribute('style', `border-color: ${color}`)\n const userDiv = document.createElement('div')\n userDiv.setAttribute('style', `background-color: ${color}`)\n userDiv.insertBefore(document.createTextNode(username), null)\n caret.insertBefore(userDiv, null)\n setTimeout(() => {\n caret.classList.add('hide-name')\n }, 2000)\n return caret\n}\n\nconst createEmptyLinePlaceholder = (color) => {\n const placeholder = document.createElement('span')\n placeholder.setAttribute('style', 'user-select: none;')\n const emptyTxt = document.createElement('span')\n emptyTxt.insertBefore(document.createTextNode(''), null)\n const sel = document.createElement('span')\n sel.setAttribute('class', 'y-line-selection')\n sel.setAttribute('style', `display: inline-block; position: absolute; left: 4px; right: 4px; top: 0; bottom: 0; background-color: ${color}70`)\n placeholder.insertBefore(sel, null)\n placeholder.insertBefore(emptyTxt, null)\n return placeholder\n}\n\nconst updateRemoteSelection = (y, cm, type, cursors, clientId, awareness) => {\n // redraw caret and selection for clientId\n const aw = awareness.getStates().get(clientId)\n // destroy current text mark\n const m = cursors.get(clientId)\n if (m !== undefined) {\n if (m.caret) {\n m.caret.clear()\n }\n m.sel.forEach(sel => sel.clear())\n cursors.delete(clientId)\n }\n if (aw === undefined) {\n return\n }\n const user = aw.user || {}\n if (user.color == null) {\n user.color = '#ffa500'\n }\n if (user.name == null) {\n user.name = `User: ${clientId}`\n }\n const cursor = aw.cursor\n if (cursor == null || cursor.anchor == null || cursor.head == null) {\n return\n }\n const anchor = Y.createAbsolutePositionFromRelativePosition(JSON.parse(cursor.anchor), y)\n const head = Y.createAbsolutePositionFromRelativePosition(JSON.parse(cursor.head), y)\n if (anchor !== null && head !== null && anchor.type === type && head.type === type) {\n const headpos = cm.posFromIndex(head.index)\n const anchorpos = cm.posFromIndex(anchor.index)\n let from, to\n if (head.index < anchor.index) {\n from = headpos\n to = anchorpos\n } else {\n from = anchorpos\n to = headpos\n }\n const caretEl = createRemoteCaret(user.name, user.color)\n // if position was \"relatively\" the same, do not show name again and hide instead\n if (m && func.equalityFlat(aw.cursor.anchor, m.awCursor.anchor) && func.equalityFlat(aw.cursor.head, m.awCursor.head)) {\n caretEl.classList.add('hide-name')\n }\n const sel = []\n\n if (head.index !== anchor.index) {\n if (from.line !== to.line && from.ch !== 0) {\n // start of selection will only be a simple text-selection\n sel.push(cm.markText(from, new CodeMirror.Pos(from.line + 1, 0), { css: `background-color: ${user.color}70;`, inclusiveRight: false, inclusiveLeft: false }))\n from = new CodeMirror.Pos(from.line + 1, 0)\n }\n while (from.line !== to.line) {\n // middle of selection is always a whole-line selection. We add a widget at the first position which will fill the background.\n sel.push(cm.setBookmark(new CodeMirror.Pos(from.line, 0), { widget: createEmptyLinePlaceholder(user.color) }))\n from = new CodeMirror.Pos(from.line + 1, 0)\n }\n sel.push(cm.markText(from, to, { css: `background-color: ${user.color}70;`, inclusiveRight: false, inclusiveLeft: false }))\n }\n // only render caret if not the complete last line was selected (in this case headpos.ch === 0)\n const caret = sel.length > 0 && to === headpos && headpos.ch === 0 ? null : cm.setBookmark(headpos, { widget: caretEl, insertLeft: true })\n cursors.set(clientId, { caret, sel, awCursor: cursor })\n }\n}\n\nconst codemirrorCursorActivity = (y, cm, type, awareness) => {\n const aw = awareness.getLocalState()\n if (!cm.hasFocus() || aw == null || !cm.display.wrapper.ownerDocument.hasFocus()) {\n return\n }\n const newAnchor = Y.createRelativePositionFromTypeIndex(type, cm.indexFromPos(cm.getCursor('anchor')))\n const newHead = Y.createRelativePositionFromTypeIndex(type, cm.indexFromPos(cm.getCursor('head')))\n let currentAnchor = null\n let currentHead = null\n if (aw.cursor != null) {\n currentAnchor = Y.createRelativePositionFromJSON(JSON.parse(aw.cursor.anchor))\n currentHead = Y.createRelativePositionFromJSON(JSON.parse(aw.cursor.head))\n }\n if (aw.cursor == null || !Y.compareRelativePositions(currentAnchor, newAnchor) || !Y.compareRelativePositions(currentHead, newHead)) {\n awareness.setLocalStateField('cursor', {\n anchor: JSON.stringify(newAnchor),\n head: JSON.stringify(newHead)\n })\n }\n}\n\n/**\n * A binding that binds a YText to a CodeMirror editor.\n *\n * @example\n * const ytext = ydocument.define('codemirror', Y.Text)\n * const editor = new CodeMirror(document.querySelector('#container'), {\n * mode: 'javascript',\n * lineNumbers: true\n * })\n * const binding = new CodemirrorBinding(ytext, editor)\n *\n */\nexport class CodemirrorBinding extends Observable {\n /**\n * @param {Y.Text} textType\n * @param {import('codemirror').Editor} codeMirror\n * @param {any | null} [awareness]\n * @param {{ yUndoManager?: Y.UndoManager }} [options]\n */\n constructor (textType, codeMirror, awareness = null, { yUndoManager = null } = {}) {\n super()\n const doc = textType.doc\n const cmDoc = codeMirror.getDoc()\n this.doc = doc\n this.type = textType\n this.cm = codeMirror\n this.cmDoc = cmDoc\n this.awareness = awareness || null\n this.yUndoManager = yUndoManager\n this._onStackItemAdded = ({ stackItem, changedParentTypes }) => {\n // only store metadata if this type was affected\n if (changedParentTypes.has(textType) && this._beforeChangeSelection) {\n stackItem.meta.set(this, this._beforeChangeSelection)\n }\n }\n this._onStackItemPopped = ({ stackItem }) => {\n const sel = stackItem.meta.get(this)\n if (sel) {\n const anchor = Y.createAbsolutePositionFromRelativePosition(sel.anchor, doc).index\n const head = Y.createAbsolutePositionFromRelativePosition(sel.head, doc).index\n codeMirror.setSelection(codeMirror.posFromIndex(anchor), codeMirror.posFromIndex(head))\n this._beforeChange()\n }\n }\n if (yUndoManager) {\n yUndoManager.trackedOrigins.add(this) // track changes performed by this editor binding\n const editorUndo = cm => {\n // Keymaps always start with an active operation.\n // End the current operation so that the event is fired at the correct moment.\n // @todo check cm.curOp in typeListener and endOperation always.\n cm.endOperation()\n yUndoManager.undo()\n cm.startOperation()\n }\n const editorRedo = cm => {\n cm.endOperation()\n yUndoManager.redo()\n cm.startOperation()\n }\n codeMirror.addKeyMap({\n // pc\n 'Ctrl-Z': editorUndo,\n 'Shift-Ctrl-Z': editorRedo,\n 'Ctrl-Y': editorRedo,\n // mac\n 'Cmd-Z': editorUndo,\n 'Shift-Cmd-Z': editorRedo,\n 'Cmd-Y': editorRedo\n })\n\n yUndoManager.on('stack-item-added', this._onStackItemAdded)\n yUndoManager.on('stack-item-popped', this._onStackItemPopped)\n }\n\n this._mux = createMutex()\n // set initial value\n cmDoc.setValue(textType.toString())\n // observe type and target\n this._typeObserver = event => typeObserver(this, event)\n this._targetObserver = (instance, changes) => {\n if (instance.getDoc() === cmDoc) {\n targetObserver(this, changes)\n }\n }\n this._cursors = new Map()\n this._changedCursors = new Set()\n this._debounceCursorEvent = eventloop.createDebouncer(10)\n this._awarenessListener = event => {\n if (codeMirror.getDoc() !== cmDoc) {\n return\n }\n const f = clientId => {\n if (clientId !== doc.clientID) {\n this._changedCursors.add(clientId)\n }\n }\n event.added.forEach(f)\n event.removed.forEach(f)\n event.updated.forEach(f)\n if (this._changedCursors.size > 0) {\n this._debounceCursorEvent(() => {\n this._changedCursors.forEach(clientId => {\n updateRemoteSelection(doc, codeMirror, textType, this._cursors, clientId, awareness)\n })\n this._changedCursors.clear()\n })\n }\n }\n this._pendingCursorEvent = false\n this._cursorListener = () => {\n if (codeMirror.getDoc() === cmDoc) {\n this._pendingCursorEvent = true\n setTimeout(() => {\n if (this._pendingCursorEvent) {\n this._pendingCursorEvent = false\n this.emit('cursorActivity', [codeMirror])\n }\n }, 0)\n }\n }\n this.on('cursorActivity', () => {\n codemirrorCursorActivity(doc, codeMirror, textType, awareness)\n })\n this._blurListeer = () => awareness.setLocalStateField('cursor', null)\n\n textType.observe(this._typeObserver)\n // @ts-ignore\n codeMirror.on('changes', this._targetObserver)\n /**\n * @type {{ anchor: Y.RelativePosition, head: Y.RelativePosition } | null}\n */\n this._beforeChangeSelection = null\n this._beforeChange = () => {\n // update the the beforeChangeSelection that is stored befor each change to the editor (except when applying remote changes)\n this._mux(() => {\n // store the selection before the change is applied so we can restore it with the undo manager.\n const anchor = Y.createRelativePositionFromTypeIndex(textType, codeMirror.indexFromPos(codeMirror.getCursor('anchor')))\n const head = Y.createRelativePositionFromTypeIndex(textType, codeMirror.indexFromPos(codeMirror.getCursor('head')))\n this._beforeChangeSelection = { anchor, head }\n })\n }\n codeMirror.on('beforeChange', this._beforeChange)\n if (awareness) {\n codeMirror.on('swapDoc', this._blurListeer)\n awareness.on('change', this._awarenessListener)\n // @ts-ignore\n codeMirror.on('cursorActivity', this._cursorListener)\n codeMirror.on('blur', this._blurListeer)\n codeMirror.on('focus', this._cursorListener)\n }\n }\n\n destroy () {\n this.type.unobserve(this._typeObserver)\n this.cm.off('swapDoc', this._blurListeer)\n // @ts-ignore\n this.cm.off('changes', this._targetObserver)\n this.cm.off('beforeChange', this._beforeChange)\n // @ts-ignore\n this.cm.off('cursorActivity', this._cursorListener)\n this.cm.off('focus', this._cursorListener)\n this.cm.off('blur', this._blurListeer)\n if (this.awareness) {\n this.awareness.off('change', this._awarenessListener)\n }\n if (this.yUndoManager) {\n this.yUndoManager.off('stack-item-added', this._onStackItemAdded)\n this.yUndoManager.off('stack-item-popped', this._onStackItemPopped)\n this.yUndoManager.trackedOrigins.delete(this)\n }\n this.type = null\n this.cm = null\n this.cmDoc = null\n super.destroy()\n }\n}\n\nexport const CodeMirrorBinding = CodemirrorBinding\n"],"sourceRoot":""}