Skip to content

Commit

Permalink
add utility setMeta function
Browse files Browse the repository at this point in the history
  • Loading branch information
dmonad committed May 14, 2020
1 parent e4cfa03 commit 407c243
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 11 deletions.
32 changes: 32 additions & 0 deletions src/lib.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,39 @@
import { ProsemirrorMapping } from './plugins/sync-plugin.js' // eslint-disable-line

import * as Y from 'yjs'
// eslint-disable-next-line
import { EditorView } from 'prosemirror-view'
import * as error from 'lib0/error.js'
import * as map from 'lib0/map.js'
import * as eventloop from 'lib0/eventloop.js'

/**
* Is null if no timeout is in progress.
* Is defined if a timeout is in progress.
* Maps from view
* @type {Map<EditorView, Map<any, any>>|null}
*/
let viewsToUpdate = null

const updateMetas = () => {
const ups = /** @type {Map<EditorView, Map<any, any>>} */ (viewsToUpdate)
viewsToUpdate = null
ups.forEach((metas, view) => {
const tr = view.state.tr
metas.forEach((val, key) => {
tr.setMeta(key, val)
})
view.dispatch(tr)
})
}

export const setMeta = (view, key, value) => {
if (!viewsToUpdate) {
viewsToUpdate = new Map()
eventloop.timeout(0, updateMetas)
}
map.setIfUndefined(viewsToUpdate, view, map.create).set(key, value)
}

/**
* Transforms a Prosemirror based absolute position to a Yjs Cursor (relative position in the Yjs model).
Expand Down
20 changes: 10 additions & 10 deletions src/plugins/cursor-plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Decoration, DecorationSet } from 'prosemirror-view' // eslint-disable-l
import { Plugin, PluginKey } from 'prosemirror-state' // eslint-disable-line
import { Awareness } from 'y-protocols/awareness.js' // eslint-disable-line
import { ySyncPluginKey } from './sync-plugin.js'
import { absolutePositionToRelativePosition, relativePositionToAbsolutePosition } from '../lib.js'
import { absolutePositionToRelativePosition, relativePositionToAbsolutePosition, setMeta } from '../lib.js'

import * as math from 'lib0/math.js'

Expand Down Expand Up @@ -81,9 +81,10 @@ export const createDecorations = (state, awareness, createCursor) => {
* @param {Awareness} awareness
* @param {object} [opts]
* @param {function(any):HTMLElement} [opts.cursorBuilder]
* @param {function(any):any} [opts.getSelection]
* @return {any}
*/
export const yCursorPlugin = (awareness, { cursorBuilder = defaultCursorBuilder } = {}) => new Plugin({
export const yCursorPlugin = (awareness, { cursorBuilder = defaultCursorBuilder, getSelection = state => state.selection } = {}) => new Plugin({
key: yCursorPluginKey,
state: {
init (_, state) {
Expand All @@ -105,26 +106,25 @@ export const yCursorPlugin = (awareness, { cursorBuilder = defaultCursorBuilder
},
view: view => {
const awarenessListener = () => {
setTimeout(() => {
// @ts-ignore
if (view.docView) {
view.dispatch(view.state.tr.setMeta(yCursorPluginKey, { awarenessUpdated: true }))
}
})
// @ts-ignore
if (view.docView) {
setMeta(view, yCursorPluginKey, { awarenessUpdated: true })
}
}
const updateCursorInfo = () => {
const ystate = ySyncPluginKey.getState(view.state)
// @note We make implicit checks when checking for the cursor property
const current = awareness.getLocalState() || {}
if (view.hasFocus() && ystate.binding !== null) {
const selection = getSelection(view.state)
/**
* @type {Y.RelativePosition}
*/
const anchor = absolutePositionToRelativePosition(view.state.selection.anchor, ystate.type, ystate.binding.mapping)
const anchor = absolutePositionToRelativePosition(selection.anchor, ystate.type, ystate.binding.mapping)
/**
* @type {Y.RelativePosition}
*/
const head = absolutePositionToRelativePosition(view.state.selection.head, ystate.type, ystate.binding.mapping)
const head = absolutePositionToRelativePosition(selection.head, ystate.type, ystate.binding.mapping)
if (current.cursor == null || !Y.compareRelativePositions(Y.createRelativePositionFromJSON(current.cursor.anchor), anchor) || !Y.compareRelativePositions(Y.createRelativePositionFromJSON(current.cursor.head), head)) {
awareness.setLocalStateField('cursor', {
anchor, head
Expand Down
2 changes: 1 addition & 1 deletion src/y-prosemirror.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export * from './plugins/cursor-plugin.js'
export * from './plugins/sync-plugin.js'
export * from './plugins/undo-plugin.js'
export { absolutePositionToRelativePosition, relativePositionToAbsolutePosition } from './lib.js'
export { absolutePositionToRelativePosition, relativePositionToAbsolutePosition, setMeta } from './lib.js'

0 comments on commit 407c243

Please sign in to comment.