Files
wdi-dashboard/node_modules/quilljs/lib/modules/multi-cursor.js
2024-08-16 15:06:52 +05:30

227 lines
7.2 KiB
JavaScript

var EventEmitter2, MultiCursor, Quill, dom, _,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
Quill = require('../quill');
EventEmitter2 = require('eventemitter2').EventEmitter2;
_ = Quill.require('lodash');
dom = Quill.require('dom');
MultiCursor = (function(_super) {
__extends(MultiCursor, _super);
MultiCursor.DEFAULTS = {
template: '<span class="cursor-flag"> <span class="cursor-name"></span> </span> <span class="cursor-caret"></span>',
timeout: 2500
};
MultiCursor.events = {
CURSOR_ADDED: 'cursor-addded',
CURSOR_MOVED: 'cursor-moved',
CURSOR_REMOVED: 'cursor-removed'
};
function MultiCursor(quill, options) {
this.quill = quill;
this.options = options;
this.cursors = {};
this.container = this.quill.addContainer('cursor-container', true);
this.quill.addStyles({
'.cursor-container': {
'position': 'absolute',
'left': '0',
'top': '0',
'z-index': '1000'
},
'.cursor': {
'margin-left': '-1px',
'position': 'absolute'
},
'.cursor-flag': {
'bottom': '100%',
'position': 'absolute',
'white-space': 'nowrap'
},
'.cursor-name': {
'display': 'inline-block',
'color': 'white',
'padding': '2px 8px'
},
'.cursor-caret': {
'height': '100%',
'position': 'absolute',
'width': '2px'
},
'.cursor.hidden .cursor-flag': {
'display': 'none'
},
'.cursor.top > .cursor-flag': {
'bottom': 'auto',
'top': '100%'
},
'.cursor.right > .cursor-flag': {
'right': '-2px'
}
});
this.quill.on(this.quill.constructor.events.TEXT_CHANGE, _.bind(this._applyDelta, this));
}
MultiCursor.prototype.clearCursors = function() {
_.each(_.keys(this.cursors), _.bind(this.removeCursor, this));
return this.cursors = {};
};
MultiCursor.prototype.moveCursor = function(userId, index) {
var cursor;
cursor = this.cursors[userId];
cursor.index = index;
dom(cursor.elem).removeClass('hidden');
clearTimeout(cursor.timer);
cursor.timer = setTimeout((function(_this) {
return function() {
dom(cursor.elem).addClass('hidden');
return cursor.timer = null;
};
})(this), this.options.timeout);
this._updateCursor(cursor);
return cursor;
};
MultiCursor.prototype.removeCursor = function(userId) {
var cursor;
cursor = this.cursors[userId];
this.emit(MultiCursor.events.CURSOR_REMOVED, cursor);
if (cursor != null) {
cursor.elem.parentNode.removeChild(cursor.elem);
}
return delete this.cursors[userId];
};
MultiCursor.prototype.setCursor = function(userId, index, name, color) {
var cursor;
if (this.cursors[userId] == null) {
this.cursors[userId] = cursor = {
userId: userId,
index: index,
color: color,
elem: this._buildCursor(name, color)
};
this.emit(MultiCursor.events.CURSOR_ADDED, cursor);
}
_.defer((function(_this) {
return function() {
return _this.moveCursor(userId, index);
};
})(this));
return this.cursors[userId];
};
MultiCursor.prototype.shiftCursors = function(index, length, authorId) {
if (authorId == null) {
authorId = null;
}
return _.each(this.cursors, (function(_this) {
return function(cursor, id) {
if (!(cursor && (cursor.index > index || cursor.userId === authorId))) {
return;
}
return cursor.index += Math.max(length, index - cursor.index);
};
})(this));
};
MultiCursor.prototype.update = function() {
return _.each(this.cursors, (function(_this) {
return function(cursor, id) {
if (cursor == null) {
return;
}
_this._updateCursor(cursor);
return true;
};
})(this));
};
MultiCursor.prototype._applyDelta = function(delta) {
var index;
index = 0;
_.each(delta.ops, (function(_this) {
return function(op) {
var length, _ref;
length = 0;
if (op.insert != null) {
length = op.insert.length || 1;
_this.shiftCursors(index, length, (_ref = op.attributes) != null ? _ref['author'] : void 0);
} else if (op["delete"] != null) {
_this.shiftCursors(index, -1 * op["delete"], null);
} else if (op.retain != null) {
_this.shiftCursors(index, 0, null);
length = op.retain;
}
return index += length;
};
})(this));
return this.update();
};
MultiCursor.prototype._buildCursor = function(name, color) {
var cursor, cursorCaret, cursorFlag, cursorName;
cursor = this.container.ownerDocument.createElement('span');
dom(cursor).addClass('cursor');
cursor.innerHTML = this.options.template;
cursorFlag = cursor.querySelector('.cursor-flag');
cursorName = cursor.querySelector('.cursor-name');
dom(cursorName).text(name);
cursorCaret = cursor.querySelector('.cursor-caret');
cursorCaret.style.backgroundColor = cursorName.style.backgroundColor = color;
this.container.appendChild(cursor);
return cursor;
};
MultiCursor.prototype._moveCursor = function(cursor, reference, side) {
var bounds, flag, win;
if (side == null) {
side = 'left';
}
win = dom(reference).window();
bounds = reference.getBoundingClientRect();
cursor.elem.style.top = bounds.top + win.pageYOffset + 'px';
cursor.elem.style.left = bounds[side] + 'px';
cursor.elem.style.height = bounds.height + 'px';
flag = cursor.elem.querySelector('.cursor-flag');
dom(cursor.elem).toggleClass('top', parseInt(cursor.elem.style.top) <= flag.offsetHeight).toggleClass('left', parseInt(cursor.elem.style.left) <= flag.offsetWidth).toggleClass('right', this.quill.root.offsetWidth - parseInt(cursor.elem.style.left) <= flag.offsetWidth);
return this.emit(MultiCursor.events.CURSOR_MOVED, cursor);
};
MultiCursor.prototype._updateCursor = function(cursor) {
var didSplit, guide, leaf, leftNode, offset, rightNode, _ref, _ref1;
this.quill.editor.checkUpdate();
_ref = this.quill.editor.doc.findLeafAt(cursor.index, true), leaf = _ref[0], offset = _ref[1];
guide = this.container.ownerDocument.createElement('span');
if (leaf != null) {
_ref1 = dom(leaf.node).split(offset), leftNode = _ref1[0], rightNode = _ref1[1], didSplit = _ref1[2];
dom(guide).text(dom.ZERO_WIDTH_NOBREAK_SPACE);
leaf.node.parentNode.insertBefore(guide, rightNode);
} else {
dom(guide).text(dom.NOBREAK_SPACE);
this.quill.root.appendChild(guide);
}
this._moveCursor(cursor, guide);
dom(guide).remove();
if (didSplit) {
dom(leaf.node.parentNode).normalize();
}
return this.quill.editor.selection.update(Quill.sources.SILENT);
};
return MultiCursor;
})(EventEmitter2);
Quill.registerModule('multi-cursor', MultiCursor);
module.exports = MultiCursor;