Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
createEditorView(node) {
// Creates the editor-view from this.editorState. If an editor has been mounted
// previously, this will contain the previous state of the editor.
this.view = new EditorView(
{ mount: node },
{
state: this.state,
dispatchTransaction: (transaction: Transaction) => {
if (!this.view) {
return
}
const nodes: Node[] = findChangedNodesFromTransaction(transaction)
if (validateNodes(nodes)) {
// go ahead and update the state now we know the transaction is good
const editorState = this.view.state.apply(transaction)
this.view.updateState(editorState)
if (transaction.docChanged) {
this.viewChange.emit(this)
}
schema: pubSchema,
plugins: plugins,
...config
};
const state = EditorState.create(stateConfig);
const reactMenu = document.createElement('div');
const editorView = document.createElement('div');
editorView.className = 'pub-body';
// place.appendChild(reactMenu);
place.appendChild(editorView);
this.menuElem = reactMenu;
this.view = new EditorView(editorView, {
state: state,
dispatchTransaction: this._onAction,
spellcheck: true,
clipboardParser: markdownParser,
clipboardSerializer: clipboardSerializer,
// handleContextMenu: (evt, thing, thing2)=> {
// console.log(evt, thing, thing2);
// },
transformPastedHTML: transformPastedHTML,
handleDOMEvents: {
dragstart: (view, evt) => {
evt.preventDefault();
return true;
},
},
viewHandlers: {
// console.timeEnd('redner2');
const selectionFrom = selection.from;
const selectionTo = selection.to;
const selectionHead = selection.head;
const decorations = [];
decorations.push(
Decoration.widget(selectionHead, elem, {
key: `cursor-widget-${cursorData.id}`,
lastActive: cursorData.lastActive,
}),
);
if (selectionFrom !== selectionTo) {
decorations.push(
Decoration.inline(
selectionFrom,
selectionTo,
{
class: `cursor-range ${formattedDataId}`,
style: `background-color: ${cursorData.backgroundColor ||
'rgba(0, 25, 150, 0.2)'};`,
},
{ key: `cursor-inline-${cursorData.id}`, lastActive: cursorData.lastActive },
),
);
}
return decorations;
};
// style.innerHTML = innerStyle;
/* This custom Decoration funkiness is because we don't want the cursor to */
/* be contenteditable="false". This will break spellcheck. So instead */
/* we do a bunch of specific :after elements and custom styles */
/* to build the rich cursor UI */
// return new Decoration(from, from, new CursorType(elem, {}));
// return new Decoration.widget(from, elem);
// return Decoration.widget(from, elem, {
// stopEvent: (event)=> {
// console.log('Heyo', event);
// },
// key: `cursor-${data.id}`,
// });
}
return Decoration.inline(from, to, {
class: `collab-selection ${data.id}`,
style: `background-color: ${data.backgroundColor || 'rgba(0, 25, 150, 0.2)'};`,
});
}).filter((dec) => {
return !!dec;
/* If cursor color provided - override defaults */
if (cursorData.cursorColor) {
innerChildBar.style.backgroundColor = cursorData.cursorColor;
innerChildCircleSmall.style.backgroundColor = cursorData.cursorColor;
innerChildCircleBig.style.backgroundColor = cursorData.cursorColor;
innerStyle += `.name.${formattedDataId}::after { background-color: ${cursorData.cursorColor} !important; } `;
}
style.innerHTML = innerStyle;
// console.timeEnd('redner2');
const selectionFrom = selection.from;
const selectionTo = selection.to;
const selectionHead = selection.head;
const decorations = [];
decorations.push(
Decoration.widget(selectionHead, elem, {
key: `cursor-widget-${cursorData.id}`,
lastActive: cursorData.lastActive,
}),
);
if (selectionFrom !== selectionTo) {
decorations.push(
Decoration.inline(
selectionFrom,
selectionTo,
{
class: `cursor-range ${formattedDataId}`,
style: `background-color: ${cursorData.backgroundColor ||
'rgba(0, 25, 150, 0.2)'};`,
},
{ key: `cursor-inline-${cursorData.id}`, lastActive: cursorData.lastActive },
editorState.doc.forEach((node, offset)=> {
// console.log(node.attrs);
if (node.attrs.trackChangesData.userId) {
const decoration = Decoration.node(
offset,
offset + node.nodeSize,
{ class: 'wow' }
);
decorations.push(decoration);
}
});
return DecorationSet.create(editorState.doc, decorations);
base Plugin state?
*/
/*
Doesn't need to be a plugin??
*/
/*
How to create a 'current' merged commit?
- Always merge current steps?
- Only show up to last steps?
*/
var _require6 = require('prosemirror-view'),
DecorationSet = _require6.DecorationSet,
Decoration = _require6.Decoration;
function stringToColor(string) {
var alpha = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;
var hue = string.split('').reduce(function (sum, char) {
return sum + char.charCodeAt(0);
}, 0) % 360;
return 'hsla(' + hue + ', 100%, 50%, ' + alpha + ')';
}
// Checkpoint a document every 100 steps
var SAVE_EVERY_N_STEPS = 100;
// healDatabase - In case a step corrupts the document (happens surpsiginly often), apply each step individually to find errors
// and then delete all of those steps
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _prosemirrorState = require('prosemirror-state');
var _plugins = require('../plugins');
var _pluginKeys = require('./pluginKeys');
var _schema = require('../schema');
var _require = require('prosemirror-view'),
DecorationSet = _require.DecorationSet,
Decoration = _require.Decoration;
var mentionsPlugin = new _prosemirrorState.Plugin({
state: {
init: function init(config, instance) {
// const set = DecorationSet.empty;
return { decos: DecorationSet.empty, start: null };
},
apply: function apply(transaction, state, prevEditorState, editorState) {
var sel = editorState.selection;
var updateMentions = this.spec.editorView.props.viewHandlers.updateMentions;
if (!sel.empty) {
updateMentions('');
return { decos: DecorationSet.empty, start: null };
decorations = (state) => {
if (!this.document) { return null; }
/* Remove inactive cursor bubbles */
const selectionKeys = Object.keys(this.document.selections);
const existingElements = document.getElementsByClassName('left-cursor');
for (let index = 0; index < existingElements.length; index++) {
const domItemClientId = existingElements[index].id.replace('cursor-', '');
const itemIndex = selectionKeys.indexOf(domItemClientId);
if (itemIndex === -1) {
existingElements[index].remove();
}
}
return DecorationSet.create(state.doc, selectionKeys.map((clientId)=> {
const selection = this.document.selections[clientId];
const data = selection.data || {};
if (!selection) {
return null;
}
const { from, to } = selection;
if (clientId === this.localClientId) {
return null;
}
if (from === to) {
const toPos = selection.$to.pos;
if (!toPos) { return null; }
const cursorCoords = this.view.coordsAtPos(toPos);
const rootElem = document.getElementById(`cursor-container-${this.editorKey}`);
if (!rootElem) { return null; }
const nextChIndex = currentPos.parentOffset;
const nextCh = currentLine.length > nextChIndex ? currentLine.charAt(nextChIndex) : ' ';
const prevChars = currentLine.substring(0, currentPos.parentOffset);
// const startIndex = Math.max(prevChars.lastIndexOf(' ') + 1, prevChars.lastIndexOf(' ') + 1);
const startIndex = prevChars.lastIndexOf(' ') + 1;
const startLetter = currentLine.charAt(startIndex);
// const shouldMark = startLetter === '@' && (nextCh.charCodeAt(0) === 32 || nextCh.charCodeAt(0) === 160);
const shouldMark = startLetter === '@' && nextCh.charCodeAt(0) === 32;
if (shouldMark) {
const substring = currentLine.substring(startIndex + 1, nextChIndex) || ' ';
const start = currentPos.pos - currentPos.parentOffset + startIndex;
const end = currentPos.pos - currentPos.parentOffset + startIndex + 1 + substring.length;
const decorations = [Decoration.inline(start, end, { class: 'mention-marker' })];
const decos = DecorationSet.create(editorState.doc, decorations);
// updateMentions(currentLine.substring(start - 1, currentPos.pos) || ' ');
updateMentions(substring);
return { decos: decos, start, end };
}
}
updateMentions('');
return { decos: DecorationSet.empty, start: null, end: null };
}
},