Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

quill-mention

Package Overview
Dependencies
Maintainers
1
Versions
64
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

quill-mention - npm Package Compare versions

Comparing version 2.2.7 to 3.0.0

307

dist/quill.mention.csj.js

@@ -271,3 +271,8 @@ 'use strict';

this.values = [];
this.suspendMouseEnter = false;
this.suspendMouseEnter = false; //this token is an object that may contains one key "abandoned", set to
//true when the previous source call should be ignored in favor or a
//more recent execution. This token will be null unless a source call
//is in progress.
this.existingSourceExecutionToken = null;
this.quill = quill;

@@ -279,2 +284,5 @@ this.options = {

},
renderLoading: function renderLoading() {
return null;
},
onSelect: function onSelect(item, insertItem) {

@@ -292,5 +300,6 @@ insertItem(item);

fixMentionsToQuill: false,
positioningStrategy: "normal",
defaultMenuOrientation: "bottom",
blotName: "mention",
dataAttributes: ["id", "value", "denotationChar", "link", "target"],
dataAttributes: ["id", "value", "denotationChar", "link", "target", "disabled"],
linkTarget: "_blank",

@@ -312,4 +321,5 @@ onOpen: function onOpen() {

dataAttributes: Array.isArray(options.dataAttributes) ? this.options.dataAttributes.concat(options.dataAttributes) : this.options.dataAttributes
});
}); //create mention container
this.mentionContainer = document.createElement("div");

@@ -327,3 +337,2 @@ this.mentionContainer.className = this.options.mentionContainerClass ? this.options.mentionContainerClass : "";

this.mentionContainer.appendChild(this.mentionList);
this.quill.container.appendChild(this.mentionContainer);
quill.on("text-change", this.onTextChange.bind(this));

@@ -353,3 +362,3 @@ quill.on("selection-change", this.onSelectionChange.bind(this));

value: function selectHandler() {
if (this.isOpen) {
if (this.isOpen && !this.existingSourceExecutionToken) {
this.selectItem();

@@ -365,2 +374,6 @@ return false;

if (this.isOpen) {
if (this.existingSourceExecutionToken) {
this.existingSourceExecutionToken.abandoned = true;
}
this.hideMentionList();

@@ -375,3 +388,3 @@ return false;

value: function upHandler() {
if (this.isOpen) {
if (this.isOpen && !this.existingSourceExecutionToken) {
this.prevItem();

@@ -386,3 +399,3 @@ return false;

value: function downHandler() {
if (this.isOpen) {
if (this.isOpen && !this.existingSourceExecutionToken) {
this.nextItem();

@@ -397,4 +410,11 @@ return false;

value: function showMentionList() {
if (this.options.positioningStrategy === "fixed") {
document.body.appendChild(this.mentionContainer);
} else {
this.quill.container.appendChild(this.mentionContainer);
}
this.mentionContainer.style.visibility = "hidden";
this.mentionContainer.style.display = "";
this.mentionContainer.scrollTop = 0;
this.setMentionContainerPosition();

@@ -407,2 +427,3 @@ this.setIsOpen(true);

this.mentionContainer.style.display = "none";
this.mentionContainer.remove();
this.setIsOpen(false);

@@ -419,2 +440,6 @@ }

if (this.itemIndex === -1 || this.mentionList.childNodes[this.itemIndex].dataset.disabled === "true") {
return;
}
this.mentionList.childNodes[this.itemIndex].classList.add("selected");

@@ -424,3 +449,3 @@

var itemHeight = this.mentionList.childNodes[this.itemIndex].offsetHeight;
var itemPos = this.itemIndex * itemHeight;
var itemPos = this.mentionList.childNodes[this.itemIndex].offsetTop;
var containerTop = this.mentionContainer.scrollTop;

@@ -461,3 +486,12 @@ var containerBottom = containerTop + this.mentionContainer.offsetHeight;

if (this.itemIndex === -1) {
return;
}
var data = this.getItemData();
if (data.disabled) {
return;
}
this.options.onSelect(data, function (asyncData) {

@@ -470,3 +504,3 @@ _this.insertItem(asyncData);

key: "insertItem",
value: function insertItem(data) {
value: function insertItem(data, programmaticInsert) {
var render = data;

@@ -482,12 +516,19 @@

var prevMentionCharPos = this.mentionCharPos;
this.quill.deleteText(this.mentionCharPos, this.cursorPos - this.mentionCharPos, Quill.sources.USER);
this.quill.insertEmbed(prevMentionCharPos, this.options.blotName, render, Quill.sources.USER);
var insertAtPos;
if (!programmaticInsert) {
insertAtPos = this.mentionCharPos;
this.quill.deleteText(this.mentionCharPos, this.cursorPos - this.mentionCharPos, Quill.sources.USER);
} else {
insertAtPos = this.cursorPos;
}
this.quill.insertEmbed(insertAtPos, this.options.blotName, render, Quill.sources.USER);
if (this.options.spaceAfterInsert) {
this.quill.insertText(prevMentionCharPos + 1, " ", Quill.sources.USER); // setSelection here sets cursor position
this.quill.insertText(insertAtPos + 1, " ", Quill.sources.USER); // setSelection here sets cursor position
this.quill.setSelection(prevMentionCharPos + 2, Quill.sources.USER);
this.quill.setSelection(insertAtPos + 2, Quill.sources.USER);
} else {
this.quill.setSelection(prevMentionCharPos + 1, Quill.sources.USER);
this.quill.setSelection(insertAtPos + 1, Quill.sources.USER);
}

@@ -512,4 +553,18 @@

}, {
key: "onDisabledItemMouseEnter",
value: function onDisabledItemMouseEnter(e) {
if (this.suspendMouseEnter) {
return;
}
this.itemIndex = -1;
this.highlightItem(false);
}
}, {
key: "onItemClick",
value: function onItemClick(e) {
if (e.button !== 0) {
return;
}
e.preventDefault();

@@ -522,7 +577,45 @@ e.stopImmediatePropagation();

}, {
key: "onItemMouseDown",
value: function onItemMouseDown(e) {
e.preventDefault();
e.stopImmediatePropagation();
}
}, {
key: "renderLoading",
value: function renderLoading() {
var renderedLoading = this.options.renderLoading();
if (!renderedLoading) {
return;
}
if (this.mentionContainer.getElementsByClassName("ql-mention-loading").length > 0) {
this.showMentionList();
return;
}
this.mentionList.innerHTML = "";
var loadingDiv = document.createElement("div");
loadingDiv.className = "ql-mention-loading";
loadingDiv.innerHTML = this.options.renderLoading();
this.mentionContainer.append(loadingDiv);
this.showMentionList();
}
}, {
key: "removeLoading",
value: function removeLoading() {
var loadingDiv = this.mentionContainer.getElementsByClassName("ql-mention-loading");
if (loadingDiv.length > 0) {
loadingDiv[0].remove();
}
}
}, {
key: "renderList",
value: function renderList(mentionChar, data, searchTerm) {
if (data && data.length > 0) {
this.removeLoading();
this.values = data;
this.mentionList.innerHTML = "";
var initialSelection = -1;

@@ -532,11 +625,25 @@ for (var i = 0; i < data.length; i += 1) {

li.className = this.options.listItemClass ? this.options.listItemClass : "";
if (data[i].disabled) {
li.className += " disabled";
} else if (initialSelection === -1) {
initialSelection = i;
}
li.dataset.index = i;
li.innerHTML = this.options.renderItem(data[i], searchTerm);
li.onmouseenter = this.onItemMouseEnter.bind(this);
if (!data[i].disabled) {
li.onmouseenter = this.onItemMouseEnter.bind(this);
li.onmouseup = this.onItemClick.bind(this);
li.onmousedown = this.onItemMouseDown.bind(this);
} else {
li.onmouseenter = this.onDisabledItemMouseEnter.bind(this);
}
li.dataset.denotationChar = mentionChar;
li.onclick = this.onItemClick.bind(this);
this.mentionList.appendChild(attachDataValues(li, data[i], this.options.dataAttributes));
}
this.itemIndex = 0;
this.itemIndex = initialSelection;
this.highlightItem();

@@ -551,3 +658,18 @@ this.showMentionList();

value: function nextItem() {
this.itemIndex = (this.itemIndex + 1) % this.values.length;
var increment = 0;
var newIndex;
do {
increment++;
newIndex = (this.itemIndex + increment) % this.values.length;
var disabled = this.mentionList.childNodes[newIndex].dataset.disabled === "true";
if (increment === this.values.length + 1) {
//we've wrapped around w/o finding an enabled item
newIndex = -1;
break;
}
} while (disabled);
this.itemIndex = newIndex;
this.suspendMouseEnter = true;

@@ -559,3 +681,18 @@ this.highlightItem();

value: function prevItem() {
this.itemIndex = (this.itemIndex + this.values.length - 1) % this.values.length;
var decrement = 0;
var newIndex;
do {
decrement++;
newIndex = (this.itemIndex + this.values.length - decrement) % this.values.length;
var disabled = this.mentionList.childNodes[newIndex].dataset.disabled === "true";
if (decrement === this.values.length + 1) {
//we've wrapped around w/o finding an enabled item
newIndex = -1;
break;
}
} while (disabled);
this.itemIndex = newIndex;
this.suspendMouseEnter = true;

@@ -597,2 +734,11 @@ this.highlightItem();

value: function setMentionContainerPosition() {
if (this.options.positioningStrategy === "fixed") {
this.setMentionContainerPosition_Fixed();
} else {
this.setMentionContainerPosition_Normal();
}
}
}, {
key: "setMentionContainerPosition_Normal",
value: function setMentionContainerPosition_Normal() {
var _this2 = this;

@@ -679,2 +825,83 @@

}, {
key: "setMentionContainerPosition_Fixed",
value: function setMentionContainerPosition_Fixed() {
var _this3 = this;
this.mentionContainer.style.position = "fixed";
this.mentionContainer.style.height = null;
var containerPos = this.quill.container.getBoundingClientRect();
var mentionCharPos = this.quill.getBounds(this.mentionCharPos);
var mentionCharPosAbsolute = {
left: containerPos.left + mentionCharPos.left,
top: containerPos.top + mentionCharPos.top,
width: 0,
height: mentionCharPos.height
}; //Which rectangle should it be relative to
var relativeToPos = this.options.fixMentionsToQuill ? containerPos : mentionCharPosAbsolute;
var topPos = this.options.offsetTop;
var leftPos = this.options.offsetLeft; // handle horizontal positioning
if (this.options.fixMentionsToQuill) {
var rightPos = relativeToPos.right;
this.mentionContainer.style.right = "".concat(rightPos, "px");
} else {
leftPos += relativeToPos.left; //if its off the righ edge, push it back
if (leftPos + this.mentionContainer.offsetWidth > document.documentElement.clientWidth) {
leftPos -= leftPos + this.mentionContainer.offsetWidth - document.documentElement.clientWidth;
}
}
var availableSpaceTop = relativeToPos.top;
var availableSpaceBottom = document.documentElement.clientHeight - (relativeToPos.top + relativeToPos.height);
var fitsBottom = this.mentionContainer.offsetHeight <= availableSpaceBottom;
var fitsTop = this.mentionContainer.offsetHeight <= availableSpaceTop;
var placement;
if (this.options.defaultMenuOrientation === "top" && fitsTop) {
placement = "top";
} else if (this.options.defaultMenuOrientation === "bottom" && fitsBottom) {
placement = "bottom";
} else {
//it doesnt fit either so put it where there's the most space
placement = availableSpaceBottom > availableSpaceTop ? "bottom" : "top";
}
if (placement === "bottom") {
topPos = relativeToPos.top + relativeToPos.height;
if (!fitsBottom) {
//shrink it to fit
//3 is a bit of a fudge factor so it doesnt touch the edge of the screen
this.mentionContainer.style.height = availableSpaceBottom - 3 + "px";
}
this.options.mentionContainerClass.split(" ").forEach(function (className) {
_this3.mentionContainer.classList.add("".concat(className, "-bottom"));
_this3.mentionContainer.classList.remove("".concat(className, "-top"));
});
} else {
topPos = relativeToPos.top - this.mentionContainer.offsetHeight;
if (!fitsTop) {
//shrink it to fit
//3 is a bit of a fudge factor so it doesnt touch the edge of the screen
this.mentionContainer.style.height = availableSpaceTop - 3 + "px";
topPos = 3;
}
this.options.mentionContainerClass.split(" ").forEach(function (className) {
_this3.mentionContainer.classList.add("".concat(className, "-top"));
_this3.mentionContainer.classList.remove("".concat(className, "-bottom"));
});
}
this.mentionContainer.style.top = "".concat(topPos, "px");
this.mentionContainer.style.left = "".concat(leftPos, "px");
this.mentionContainer.style.visibility = "visible";
}
}, {
key: "getTextBeforeCursor",

@@ -689,2 +916,4 @@ value: function getTextBeforeCursor() {

value: function onSomethingChange() {
var _this4 = this;
var range = this.quill.getSelection();

@@ -704,4 +933,21 @@ if (range == null) return;

if (textAfter.length >= this.options.minChars && hasValidChars(textAfter, this.options.allowedChars)) {
this.options.source(textAfter, this.renderList.bind(this, mentionChar), mentionChar);
if (textAfter.length >= this.options.minChars && hasValidChars(textAfter, this.getAllowedCharsRegex(mentionChar))) {
if (this.existingSourceExecutionToken) {
this.existingSourceExecutionToken.abandoned = true;
}
this.renderLoading();
var sourceRequestToken = {
abandoned: false
};
this.existingSourceExecutionToken = sourceRequestToken;
this.options.source(textAfter, function (data, searchTerm) {
if (sourceRequestToken.abandoned) {
return;
}
_this4.existingSourceExecutionToken = null;
_this4.renderList(mentionChar, data, searchTerm);
}, mentionChar);
} else {

@@ -715,2 +961,11 @@ this.hideMentionList();

}, {
key: "getAllowedCharsRegex",
value: function getAllowedCharsRegex(denotationChar) {
if (this.options.allowedChars instanceof RegExp) {
return this.options.allowedChars;
} else {
return this.options.allowedChars(denotationChar);
}
}
}, {
key: "onTextChange",

@@ -731,2 +986,10 @@ value: function onTextChange(delta, oldDelta, source) {

}
}, {
key: "openMenu",
value: function openMenu(denotationChar) {
var selection = this.quill.getSelection(true);
this.quill.insertText(selection.index, denotationChar);
this.quill.blur();
this.quill.focus();
}
}]);

@@ -733,0 +996,0 @@

@@ -267,3 +267,8 @@ import Quill from 'quill';

this.values = [];
this.suspendMouseEnter = false;
this.suspendMouseEnter = false; //this token is an object that may contains one key "abandoned", set to
//true when the previous source call should be ignored in favor or a
//more recent execution. This token will be null unless a source call
//is in progress.
this.existingSourceExecutionToken = null;
this.quill = quill;

@@ -275,2 +280,5 @@ this.options = {

},
renderLoading: function renderLoading() {
return null;
},
onSelect: function onSelect(item, insertItem) {

@@ -288,5 +296,6 @@ insertItem(item);

fixMentionsToQuill: false,
positioningStrategy: "normal",
defaultMenuOrientation: "bottom",
blotName: "mention",
dataAttributes: ["id", "value", "denotationChar", "link", "target"],
dataAttributes: ["id", "value", "denotationChar", "link", "target", "disabled"],
linkTarget: "_blank",

@@ -308,4 +317,5 @@ onOpen: function onOpen() {

dataAttributes: Array.isArray(options.dataAttributes) ? this.options.dataAttributes.concat(options.dataAttributes) : this.options.dataAttributes
});
}); //create mention container
this.mentionContainer = document.createElement("div");

@@ -323,3 +333,2 @@ this.mentionContainer.className = this.options.mentionContainerClass ? this.options.mentionContainerClass : "";

this.mentionContainer.appendChild(this.mentionList);
this.quill.container.appendChild(this.mentionContainer);
quill.on("text-change", this.onTextChange.bind(this));

@@ -349,3 +358,3 @@ quill.on("selection-change", this.onSelectionChange.bind(this));

value: function selectHandler() {
if (this.isOpen) {
if (this.isOpen && !this.existingSourceExecutionToken) {
this.selectItem();

@@ -361,2 +370,6 @@ return false;

if (this.isOpen) {
if (this.existingSourceExecutionToken) {
this.existingSourceExecutionToken.abandoned = true;
}
this.hideMentionList();

@@ -371,3 +384,3 @@ return false;

value: function upHandler() {
if (this.isOpen) {
if (this.isOpen && !this.existingSourceExecutionToken) {
this.prevItem();

@@ -382,3 +395,3 @@ return false;

value: function downHandler() {
if (this.isOpen) {
if (this.isOpen && !this.existingSourceExecutionToken) {
this.nextItem();

@@ -393,4 +406,11 @@ return false;

value: function showMentionList() {
if (this.options.positioningStrategy === "fixed") {
document.body.appendChild(this.mentionContainer);
} else {
this.quill.container.appendChild(this.mentionContainer);
}
this.mentionContainer.style.visibility = "hidden";
this.mentionContainer.style.display = "";
this.mentionContainer.scrollTop = 0;
this.setMentionContainerPosition();

@@ -403,2 +423,3 @@ this.setIsOpen(true);

this.mentionContainer.style.display = "none";
this.mentionContainer.remove();
this.setIsOpen(false);

@@ -415,2 +436,6 @@ }

if (this.itemIndex === -1 || this.mentionList.childNodes[this.itemIndex].dataset.disabled === "true") {
return;
}
this.mentionList.childNodes[this.itemIndex].classList.add("selected");

@@ -420,3 +445,3 @@

var itemHeight = this.mentionList.childNodes[this.itemIndex].offsetHeight;
var itemPos = this.itemIndex * itemHeight;
var itemPos = this.mentionList.childNodes[this.itemIndex].offsetTop;
var containerTop = this.mentionContainer.scrollTop;

@@ -457,3 +482,12 @@ var containerBottom = containerTop + this.mentionContainer.offsetHeight;

if (this.itemIndex === -1) {
return;
}
var data = this.getItemData();
if (data.disabled) {
return;
}
this.options.onSelect(data, function (asyncData) {

@@ -466,3 +500,3 @@ _this.insertItem(asyncData);

key: "insertItem",
value: function insertItem(data) {
value: function insertItem(data, programmaticInsert) {
var render = data;

@@ -478,12 +512,19 @@

var prevMentionCharPos = this.mentionCharPos;
this.quill.deleteText(this.mentionCharPos, this.cursorPos - this.mentionCharPos, Quill.sources.USER);
this.quill.insertEmbed(prevMentionCharPos, this.options.blotName, render, Quill.sources.USER);
var insertAtPos;
if (!programmaticInsert) {
insertAtPos = this.mentionCharPos;
this.quill.deleteText(this.mentionCharPos, this.cursorPos - this.mentionCharPos, Quill.sources.USER);
} else {
insertAtPos = this.cursorPos;
}
this.quill.insertEmbed(insertAtPos, this.options.blotName, render, Quill.sources.USER);
if (this.options.spaceAfterInsert) {
this.quill.insertText(prevMentionCharPos + 1, " ", Quill.sources.USER); // setSelection here sets cursor position
this.quill.insertText(insertAtPos + 1, " ", Quill.sources.USER); // setSelection here sets cursor position
this.quill.setSelection(prevMentionCharPos + 2, Quill.sources.USER);
this.quill.setSelection(insertAtPos + 2, Quill.sources.USER);
} else {
this.quill.setSelection(prevMentionCharPos + 1, Quill.sources.USER);
this.quill.setSelection(insertAtPos + 1, Quill.sources.USER);
}

@@ -508,4 +549,18 @@

}, {
key: "onDisabledItemMouseEnter",
value: function onDisabledItemMouseEnter(e) {
if (this.suspendMouseEnter) {
return;
}
this.itemIndex = -1;
this.highlightItem(false);
}
}, {
key: "onItemClick",
value: function onItemClick(e) {
if (e.button !== 0) {
return;
}
e.preventDefault();

@@ -518,7 +573,45 @@ e.stopImmediatePropagation();

}, {
key: "onItemMouseDown",
value: function onItemMouseDown(e) {
e.preventDefault();
e.stopImmediatePropagation();
}
}, {
key: "renderLoading",
value: function renderLoading() {
var renderedLoading = this.options.renderLoading();
if (!renderedLoading) {
return;
}
if (this.mentionContainer.getElementsByClassName("ql-mention-loading").length > 0) {
this.showMentionList();
return;
}
this.mentionList.innerHTML = "";
var loadingDiv = document.createElement("div");
loadingDiv.className = "ql-mention-loading";
loadingDiv.innerHTML = this.options.renderLoading();
this.mentionContainer.append(loadingDiv);
this.showMentionList();
}
}, {
key: "removeLoading",
value: function removeLoading() {
var loadingDiv = this.mentionContainer.getElementsByClassName("ql-mention-loading");
if (loadingDiv.length > 0) {
loadingDiv[0].remove();
}
}
}, {
key: "renderList",
value: function renderList(mentionChar, data, searchTerm) {
if (data && data.length > 0) {
this.removeLoading();
this.values = data;
this.mentionList.innerHTML = "";
var initialSelection = -1;

@@ -528,11 +621,25 @@ for (var i = 0; i < data.length; i += 1) {

li.className = this.options.listItemClass ? this.options.listItemClass : "";
if (data[i].disabled) {
li.className += " disabled";
} else if (initialSelection === -1) {
initialSelection = i;
}
li.dataset.index = i;
li.innerHTML = this.options.renderItem(data[i], searchTerm);
li.onmouseenter = this.onItemMouseEnter.bind(this);
if (!data[i].disabled) {
li.onmouseenter = this.onItemMouseEnter.bind(this);
li.onmouseup = this.onItemClick.bind(this);
li.onmousedown = this.onItemMouseDown.bind(this);
} else {
li.onmouseenter = this.onDisabledItemMouseEnter.bind(this);
}
li.dataset.denotationChar = mentionChar;
li.onclick = this.onItemClick.bind(this);
this.mentionList.appendChild(attachDataValues(li, data[i], this.options.dataAttributes));
}
this.itemIndex = 0;
this.itemIndex = initialSelection;
this.highlightItem();

@@ -547,3 +654,18 @@ this.showMentionList();

value: function nextItem() {
this.itemIndex = (this.itemIndex + 1) % this.values.length;
var increment = 0;
var newIndex;
do {
increment++;
newIndex = (this.itemIndex + increment) % this.values.length;
var disabled = this.mentionList.childNodes[newIndex].dataset.disabled === "true";
if (increment === this.values.length + 1) {
//we've wrapped around w/o finding an enabled item
newIndex = -1;
break;
}
} while (disabled);
this.itemIndex = newIndex;
this.suspendMouseEnter = true;

@@ -555,3 +677,18 @@ this.highlightItem();

value: function prevItem() {
this.itemIndex = (this.itemIndex + this.values.length - 1) % this.values.length;
var decrement = 0;
var newIndex;
do {
decrement++;
newIndex = (this.itemIndex + this.values.length - decrement) % this.values.length;
var disabled = this.mentionList.childNodes[newIndex].dataset.disabled === "true";
if (decrement === this.values.length + 1) {
//we've wrapped around w/o finding an enabled item
newIndex = -1;
break;
}
} while (disabled);
this.itemIndex = newIndex;
this.suspendMouseEnter = true;

@@ -593,2 +730,11 @@ this.highlightItem();

value: function setMentionContainerPosition() {
if (this.options.positioningStrategy === "fixed") {
this.setMentionContainerPosition_Fixed();
} else {
this.setMentionContainerPosition_Normal();
}
}
}, {
key: "setMentionContainerPosition_Normal",
value: function setMentionContainerPosition_Normal() {
var _this2 = this;

@@ -675,2 +821,83 @@

}, {
key: "setMentionContainerPosition_Fixed",
value: function setMentionContainerPosition_Fixed() {
var _this3 = this;
this.mentionContainer.style.position = "fixed";
this.mentionContainer.style.height = null;
var containerPos = this.quill.container.getBoundingClientRect();
var mentionCharPos = this.quill.getBounds(this.mentionCharPos);
var mentionCharPosAbsolute = {
left: containerPos.left + mentionCharPos.left,
top: containerPos.top + mentionCharPos.top,
width: 0,
height: mentionCharPos.height
}; //Which rectangle should it be relative to
var relativeToPos = this.options.fixMentionsToQuill ? containerPos : mentionCharPosAbsolute;
var topPos = this.options.offsetTop;
var leftPos = this.options.offsetLeft; // handle horizontal positioning
if (this.options.fixMentionsToQuill) {
var rightPos = relativeToPos.right;
this.mentionContainer.style.right = "".concat(rightPos, "px");
} else {
leftPos += relativeToPos.left; //if its off the righ edge, push it back
if (leftPos + this.mentionContainer.offsetWidth > document.documentElement.clientWidth) {
leftPos -= leftPos + this.mentionContainer.offsetWidth - document.documentElement.clientWidth;
}
}
var availableSpaceTop = relativeToPos.top;
var availableSpaceBottom = document.documentElement.clientHeight - (relativeToPos.top + relativeToPos.height);
var fitsBottom = this.mentionContainer.offsetHeight <= availableSpaceBottom;
var fitsTop = this.mentionContainer.offsetHeight <= availableSpaceTop;
var placement;
if (this.options.defaultMenuOrientation === "top" && fitsTop) {
placement = "top";
} else if (this.options.defaultMenuOrientation === "bottom" && fitsBottom) {
placement = "bottom";
} else {
//it doesnt fit either so put it where there's the most space
placement = availableSpaceBottom > availableSpaceTop ? "bottom" : "top";
}
if (placement === "bottom") {
topPos = relativeToPos.top + relativeToPos.height;
if (!fitsBottom) {
//shrink it to fit
//3 is a bit of a fudge factor so it doesnt touch the edge of the screen
this.mentionContainer.style.height = availableSpaceBottom - 3 + "px";
}
this.options.mentionContainerClass.split(" ").forEach(function (className) {
_this3.mentionContainer.classList.add("".concat(className, "-bottom"));
_this3.mentionContainer.classList.remove("".concat(className, "-top"));
});
} else {
topPos = relativeToPos.top - this.mentionContainer.offsetHeight;
if (!fitsTop) {
//shrink it to fit
//3 is a bit of a fudge factor so it doesnt touch the edge of the screen
this.mentionContainer.style.height = availableSpaceTop - 3 + "px";
topPos = 3;
}
this.options.mentionContainerClass.split(" ").forEach(function (className) {
_this3.mentionContainer.classList.add("".concat(className, "-top"));
_this3.mentionContainer.classList.remove("".concat(className, "-bottom"));
});
}
this.mentionContainer.style.top = "".concat(topPos, "px");
this.mentionContainer.style.left = "".concat(leftPos, "px");
this.mentionContainer.style.visibility = "visible";
}
}, {
key: "getTextBeforeCursor",

@@ -685,2 +912,4 @@ value: function getTextBeforeCursor() {

value: function onSomethingChange() {
var _this4 = this;
var range = this.quill.getSelection();

@@ -700,4 +929,21 @@ if (range == null) return;

if (textAfter.length >= this.options.minChars && hasValidChars(textAfter, this.options.allowedChars)) {
this.options.source(textAfter, this.renderList.bind(this, mentionChar), mentionChar);
if (textAfter.length >= this.options.minChars && hasValidChars(textAfter, this.getAllowedCharsRegex(mentionChar))) {
if (this.existingSourceExecutionToken) {
this.existingSourceExecutionToken.abandoned = true;
}
this.renderLoading();
var sourceRequestToken = {
abandoned: false
};
this.existingSourceExecutionToken = sourceRequestToken;
this.options.source(textAfter, function (data, searchTerm) {
if (sourceRequestToken.abandoned) {
return;
}
_this4.existingSourceExecutionToken = null;
_this4.renderList(mentionChar, data, searchTerm);
}, mentionChar);
} else {

@@ -711,2 +957,11 @@ this.hideMentionList();

}, {
key: "getAllowedCharsRegex",
value: function getAllowedCharsRegex(denotationChar) {
if (this.options.allowedChars instanceof RegExp) {
return this.options.allowedChars;
} else {
return this.options.allowedChars(denotationChar);
}
}
}, {
key: "onTextChange",

@@ -727,2 +982,10 @@ value: function onTextChange(delta, oldDelta, source) {

}
}, {
key: "openMenu",
value: function openMenu(denotationChar) {
var selection = this.quill.getSelection(true);
this.quill.insertText(selection.index, denotationChar);
this.quill.blur();
this.quill.focus();
}
}]);

@@ -729,0 +992,0 @@

2

dist/quill.mention.min.js

@@ -1,1 +0,1 @@

var quillMention=function(t){"use strict";function e(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function n(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}function i(t,e,i){return e&&n(t.prototype,e),i&&n(t,i),t}function o(){return(o=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])}return t}).apply(this,arguments)}function s(t){return(s=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)})(t)}function r(t,e){return(r=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t})(t,e)}function a(t,e){return!e||"object"!=typeof e&&"function"!=typeof e?function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}(t):e}function h(t){var e=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(t){return!1}}();return function(){var n,i=s(t);if(e){var o=s(this).constructor;n=Reflect.construct(i,arguments,o)}else n=i.apply(this,arguments);return a(this,n)}}function l(t,e,n){return(l="undefined"!=typeof Reflect&&Reflect.get?Reflect.get:function(t,e,n){var i=function(t,e){for(;!Object.prototype.hasOwnProperty.call(t,e)&&null!==(t=s(t)););return t}(t,e);if(i){var o=Object.getOwnPropertyDescriptor(i,e);return o.get?o.get.call(n):o.value}})(t,e,n||t)}t=t&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t;var u=9,c=13,d=27,f=38,m=40;function p(t,e,n){var i=t;return Object.keys(e).forEach((function(t){n.indexOf(t)>-1?i.dataset[t]=e[t]:delete i.dataset[t]})),i}var C=function(t){!function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),e&&r(t,e)}(o,t);var n=h(o);function o(){return e(this,o),n.apply(this,arguments)}return i(o,null,[{key:"create",value:function(t){var e=l(s(o),"create",this).call(this),n=document.createElement("span");return n.className="ql-mention-denotation-char",n.innerHTML=t.denotationChar,e.appendChild(n),e.innerHTML+=t.value,o.setDataValues(e,t)}},{key:"setDataValues",value:function(t,e){var n=t;return Object.keys(e).forEach((function(t){n.dataset[t]=e[t]})),n}},{key:"value",value:function(t){return t.dataset}}]),o}(t.import("blots/embed"));C.blotName="mention",C.tagName="span",C.className="mention",t.register(C);var v=function(){function n(t,i){e(this,n),this.isOpen=!1,this.itemIndex=0,this.mentionCharPos=null,this.cursorPos=null,this.values=[],this.suspendMouseEnter=!1,this.quill=t,this.options={source:null,renderItem:function(t){return"".concat(t.value)},onSelect:function(t,e){e(t)},mentionDenotationChars:["@"],showDenotationChar:!0,allowedChars:/^[a-zA-Z0-9_]*$/,minChars:0,maxChars:31,offsetTop:2,offsetLeft:0,isolateCharacter:!1,fixMentionsToQuill:!1,defaultMenuOrientation:"bottom",blotName:"mention",dataAttributes:["id","value","denotationChar","link","target"],linkTarget:"_blank",onOpen:function(){return!0},onClose:function(){return!0},listItemClass:"ql-mention-list-item",mentionContainerClass:"ql-mention-list-container",mentionListClass:"ql-mention-list",spaceAfterInsert:!0},o(this.options,i,{dataAttributes:Array.isArray(i.dataAttributes)?this.options.dataAttributes.concat(i.dataAttributes):this.options.dataAttributes}),this.mentionContainer=document.createElement("div"),this.mentionContainer.className=this.options.mentionContainerClass?this.options.mentionContainerClass:"",this.mentionContainer.style.cssText="display: none; position: absolute;",this.mentionContainer.onmousemove=this.onContainerMouseMove.bind(this),this.options.fixMentionsToQuill&&(this.mentionContainer.style.width="auto"),this.mentionList=document.createElement("ul"),this.mentionList.className=this.options.mentionListClass?this.options.mentionListClass:"",this.mentionContainer.appendChild(this.mentionList),this.quill.container.appendChild(this.mentionContainer),t.on("text-change",this.onTextChange.bind(this)),t.on("selection-change",this.onSelectionChange.bind(this)),t.keyboard.addBinding({key:u},this.selectHandler.bind(this)),t.keyboard.bindings[u].unshift(t.keyboard.bindings[u].pop()),t.keyboard.addBinding({key:c},this.selectHandler.bind(this)),t.keyboard.bindings[c].unshift(t.keyboard.bindings[c].pop()),t.keyboard.addBinding({key:d},this.escapeHandler.bind(this)),t.keyboard.addBinding({key:f},this.upHandler.bind(this)),t.keyboard.addBinding({key:m},this.downHandler.bind(this))}return i(n,[{key:"selectHandler",value:function(){return!this.isOpen||(this.selectItem(),!1)}},{key:"escapeHandler",value:function(){return!this.isOpen||(this.hideMentionList(),!1)}},{key:"upHandler",value:function(){return!this.isOpen||(this.prevItem(),!1)}},{key:"downHandler",value:function(){return!this.isOpen||(this.nextItem(),!1)}},{key:"showMentionList",value:function(){this.mentionContainer.style.visibility="hidden",this.mentionContainer.style.display="",this.setMentionContainerPosition(),this.setIsOpen(!0)}},{key:"hideMentionList",value:function(){this.mentionContainer.style.display="none",this.setIsOpen(!1)}},{key:"highlightItem",value:function(){for(var t=!(arguments.length>0&&void 0!==arguments[0])||arguments[0],e=0;e<this.mentionList.childNodes.length;e+=1)this.mentionList.childNodes[e].classList.remove("selected");if(this.mentionList.childNodes[this.itemIndex].classList.add("selected"),t){var n=this.mentionList.childNodes[this.itemIndex].offsetHeight,i=this.itemIndex*n,o=this.mentionContainer.scrollTop,s=o+this.mentionContainer.offsetHeight;i<o?this.mentionContainer.scrollTop=i:i>s-n&&(this.mentionContainer.scrollTop+=i-s+n)}}},{key:"getItemData",value:function(){var t=this.mentionList.childNodes[this.itemIndex].dataset.link,e=void 0!==t,n=this.mentionList.childNodes[this.itemIndex].dataset.target;return e&&(this.mentionList.childNodes[this.itemIndex].dataset.value='<a href="'.concat(t,'" target=').concat(n||this.options.linkTarget,">").concat(this.mentionList.childNodes[this.itemIndex].dataset.value)),this.mentionList.childNodes[this.itemIndex].dataset}},{key:"onContainerMouseMove",value:function(){this.suspendMouseEnter=!1}},{key:"selectItem",value:function(){var t=this,e=this.getItemData();this.options.onSelect(e,(function(e){t.insertItem(e)})),this.hideMentionList()}},{key:"insertItem",value:function(e){var n=e;if(null!==n){this.options.showDenotationChar||(n.denotationChar="");var i=this.mentionCharPos;this.quill.deleteText(this.mentionCharPos,this.cursorPos-this.mentionCharPos,t.sources.USER),this.quill.insertEmbed(i,this.options.blotName,n,t.sources.USER),this.options.spaceAfterInsert?(this.quill.insertText(i+1," ",t.sources.USER),this.quill.setSelection(i+2,t.sources.USER)):this.quill.setSelection(i+1,t.sources.USER),this.hideMentionList()}}},{key:"onItemMouseEnter",value:function(t){if(!this.suspendMouseEnter){var e=Number(t.target.dataset.index);Number.isNaN(e)||e===this.itemIndex||(this.itemIndex=e,this.highlightItem(!1))}}},{key:"onItemClick",value:function(t){t.preventDefault(),t.stopImmediatePropagation(),this.itemIndex=t.currentTarget.dataset.index,this.highlightItem(),this.selectItem()}},{key:"renderList",value:function(t,e,n){if(e&&e.length>0){this.values=e,this.mentionList.innerHTML="";for(var i=0;i<e.length;i+=1){var o=document.createElement("li");o.className=this.options.listItemClass?this.options.listItemClass:"",o.dataset.index=i,o.innerHTML=this.options.renderItem(e[i],n),o.onmouseenter=this.onItemMouseEnter.bind(this),o.dataset.denotationChar=t,o.onclick=this.onItemClick.bind(this),this.mentionList.appendChild(p(o,e[i],this.options.dataAttributes))}this.itemIndex=0,this.highlightItem(),this.showMentionList()}else this.hideMentionList()}},{key:"nextItem",value:function(){this.itemIndex=(this.itemIndex+1)%this.values.length,this.suspendMouseEnter=!0,this.highlightItem()}},{key:"prevItem",value:function(){this.itemIndex=(this.itemIndex+this.values.length-1)%this.values.length,this.suspendMouseEnter=!0,this.highlightItem()}},{key:"containerBottomIsNotVisible",value:function(t,e){return t+this.mentionContainer.offsetHeight+e.top>window.pageYOffset+window.innerHeight}},{key:"containerRightIsNotVisible",value:function(t,e){return!this.options.fixMentionsToQuill&&t+this.mentionContainer.offsetWidth+e.left>window.pageXOffset+document.documentElement.clientWidth}},{key:"setIsOpen",value:function(t){this.isOpen!==t&&(t?this.options.onOpen():this.options.onClose(),this.isOpen=t)}},{key:"setMentionContainerPosition",value:function(){var t=this,e=this.quill.container.getBoundingClientRect(),n=this.quill.getBounds(this.mentionCharPos),i=this.mentionContainer.offsetHeight,o=this.options.offsetTop,s=this.options.offsetLeft;if(this.options.fixMentionsToQuill){this.mentionContainer.style.right="".concat(0,"px")}else s+=n.left;if(this.containerRightIsNotVisible(s,e)){var r=this.mentionContainer.offsetWidth+this.options.offsetLeft;s=e.width-r}if("top"===this.options.defaultMenuOrientation){if((o=this.options.fixMentionsToQuill?-1*(i+this.options.offsetTop):n.top-(i+this.options.offsetTop))+e.top<=0){var a=this.options.offsetTop;this.options.fixMentionsToQuill?a+=e.height:a+=n.bottom,o=a}}else if(this.options.fixMentionsToQuill?o+=e.height:o+=n.bottom,this.containerBottomIsNotVisible(o,e)){var h=-1*this.options.offsetTop;this.options.fixMentionsToQuill||(h+=n.top),o=h-i}o>=0?this.options.mentionContainerClass.split(" ").forEach((function(e){t.mentionContainer.classList.add("".concat(e,"-bottom")),t.mentionContainer.classList.remove("".concat(e,"-top"))})):this.options.mentionContainerClass.split(" ").forEach((function(e){t.mentionContainer.classList.add("".concat(e,"-top")),t.mentionContainer.classList.remove("".concat(e,"-bottom"))})),this.mentionContainer.style.top="".concat(o,"px"),this.mentionContainer.style.left="".concat(s,"px"),this.mentionContainer.style.visibility="visible"}},{key:"getTextBeforeCursor",value:function(){var t=Math.max(0,this.cursorPos-this.options.maxChars);return this.quill.getText(t,this.cursorPos-t)}},{key:"onSomethingChange",value:function(){var t=this.quill.getSelection();if(null!=t){this.cursorPos=t.index;var e,n=this.getTextBeforeCursor(),i=(e=n,this.options.mentionDenotationChars.reduce((function(t,n){var i=e.lastIndexOf(n);return i>t.mentionCharIndex?{mentionChar:n,mentionCharIndex:i}:{mentionChar:t.mentionChar,mentionCharIndex:t.mentionCharIndex}}),{mentionChar:null,mentionCharIndex:-1})),o=i.mentionChar,s=i.mentionCharIndex;if(function(t,e,n){return t>-1&&!(n&&0!==t&&!e[t-1].match(/\s/g))}(s,n,this.options.isolateCharacter)){var r=this.cursorPos-(n.length-s);this.mentionCharPos=r;var a=n.substring(s+o.length);a.length>=this.options.minChars&&function(t,e){return e.test(t)}(a,this.options.allowedChars)?this.options.source(a,this.renderList.bind(this,o),o):this.hideMentionList()}else this.hideMentionList()}}},{key:"onTextChange",value:function(t,e,n){"user"===n&&this.onSomethingChange()}},{key:"onSelectionChange",value:function(t){t&&0===t.length?this.onSomethingChange():this.hideMentionList()}}]),n}();return t.register("modules/mention",v),v}(Quill);
var quillMention=function(t){"use strict";function e(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function n(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}function i(t,e,i){return e&&n(t.prototype,e),i&&n(t,i),t}function o(){return(o=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])}return t}).apply(this,arguments)}function s(t){return(s=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)})(t)}function a(t,e){return(a=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t})(t,e)}function r(t,e){return!e||"object"!=typeof e&&"function"!=typeof e?function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}(t):e}function h(t){var e=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(t){return!1}}();return function(){var n,i=s(t);if(e){var o=s(this).constructor;n=Reflect.construct(i,arguments,o)}else n=i.apply(this,arguments);return r(this,n)}}function l(t,e,n){return(l="undefined"!=typeof Reflect&&Reflect.get?Reflect.get:function(t,e,n){var i=function(t,e){for(;!Object.prototype.hasOwnProperty.call(t,e)&&null!==(t=s(t)););return t}(t,e);if(i){var o=Object.getOwnPropertyDescriptor(i,e);return o.get?o.get.call(n):o.value}})(t,e,n||t)}t=t&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t;var u=9,c=13,d=27,m=38,f=40;function p(t,e,n){var i=t;return Object.keys(e).forEach((function(t){n.indexOf(t)>-1?i.dataset[t]=e[t]:delete i.dataset[t]})),i}var g=function(t){!function(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function");t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,writable:!0,configurable:!0}}),e&&a(t,e)}(o,t);var n=h(o);function o(){return e(this,o),n.apply(this,arguments)}return i(o,null,[{key:"create",value:function(t){var e=l(s(o),"create",this).call(this),n=document.createElement("span");return n.className="ql-mention-denotation-char",n.innerHTML=t.denotationChar,e.appendChild(n),e.innerHTML+=t.value,o.setDataValues(e,t)}},{key:"setDataValues",value:function(t,e){var n=t;return Object.keys(e).forEach((function(t){n.dataset[t]=e[t]})),n}},{key:"value",value:function(t){return t.dataset}}]),o}(t.import("blots/embed"));g.blotName="mention",g.tagName="span",g.className="mention",t.register(g);var C=function(){function n(t,i){e(this,n),this.isOpen=!1,this.itemIndex=0,this.mentionCharPos=null,this.cursorPos=null,this.values=[],this.suspendMouseEnter=!1,this.existingSourceExecutionToken=null,this.quill=t,this.options={source:null,renderItem:function(t){return"".concat(t.value)},renderLoading:function(){return null},onSelect:function(t,e){e(t)},mentionDenotationChars:["@"],showDenotationChar:!0,allowedChars:/^[a-zA-Z0-9_]*$/,minChars:0,maxChars:31,offsetTop:2,offsetLeft:0,isolateCharacter:!1,fixMentionsToQuill:!1,positioningStrategy:"normal",defaultMenuOrientation:"bottom",blotName:"mention",dataAttributes:["id","value","denotationChar","link","target","disabled"],linkTarget:"_blank",onOpen:function(){return!0},onClose:function(){return!0},listItemClass:"ql-mention-list-item",mentionContainerClass:"ql-mention-list-container",mentionListClass:"ql-mention-list",spaceAfterInsert:!0},o(this.options,i,{dataAttributes:Array.isArray(i.dataAttributes)?this.options.dataAttributes.concat(i.dataAttributes):this.options.dataAttributes}),this.mentionContainer=document.createElement("div"),this.mentionContainer.className=this.options.mentionContainerClass?this.options.mentionContainerClass:"",this.mentionContainer.style.cssText="display: none; position: absolute;",this.mentionContainer.onmousemove=this.onContainerMouseMove.bind(this),this.options.fixMentionsToQuill&&(this.mentionContainer.style.width="auto"),this.mentionList=document.createElement("ul"),this.mentionList.className=this.options.mentionListClass?this.options.mentionListClass:"",this.mentionContainer.appendChild(this.mentionList),t.on("text-change",this.onTextChange.bind(this)),t.on("selection-change",this.onSelectionChange.bind(this)),t.keyboard.addBinding({key:u},this.selectHandler.bind(this)),t.keyboard.bindings[u].unshift(t.keyboard.bindings[u].pop()),t.keyboard.addBinding({key:c},this.selectHandler.bind(this)),t.keyboard.bindings[c].unshift(t.keyboard.bindings[c].pop()),t.keyboard.addBinding({key:d},this.escapeHandler.bind(this)),t.keyboard.addBinding({key:m},this.upHandler.bind(this)),t.keyboard.addBinding({key:f},this.downHandler.bind(this))}return i(n,[{key:"selectHandler",value:function(){return!(this.isOpen&&!this.existingSourceExecutionToken)||(this.selectItem(),!1)}},{key:"escapeHandler",value:function(){return!this.isOpen||(this.existingSourceExecutionToken&&(this.existingSourceExecutionToken.abandoned=!0),this.hideMentionList(),!1)}},{key:"upHandler",value:function(){return!(this.isOpen&&!this.existingSourceExecutionToken)||(this.prevItem(),!1)}},{key:"downHandler",value:function(){return!(this.isOpen&&!this.existingSourceExecutionToken)||(this.nextItem(),!1)}},{key:"showMentionList",value:function(){"fixed"===this.options.positioningStrategy?document.body.appendChild(this.mentionContainer):this.quill.container.appendChild(this.mentionContainer),this.mentionContainer.style.visibility="hidden",this.mentionContainer.style.display="",this.mentionContainer.scrollTop=0,this.setMentionContainerPosition(),this.setIsOpen(!0)}},{key:"hideMentionList",value:function(){this.mentionContainer.style.display="none",this.mentionContainer.remove(),this.setIsOpen(!1)}},{key:"highlightItem",value:function(){for(var t=!(arguments.length>0&&void 0!==arguments[0])||arguments[0],e=0;e<this.mentionList.childNodes.length;e+=1)this.mentionList.childNodes[e].classList.remove("selected");if(-1!==this.itemIndex&&"true"!==this.mentionList.childNodes[this.itemIndex].dataset.disabled&&(this.mentionList.childNodes[this.itemIndex].classList.add("selected"),t)){var n=this.mentionList.childNodes[this.itemIndex].offsetHeight,i=this.mentionList.childNodes[this.itemIndex].offsetTop,o=this.mentionContainer.scrollTop,s=o+this.mentionContainer.offsetHeight;i<o?this.mentionContainer.scrollTop=i:i>s-n&&(this.mentionContainer.scrollTop+=i-s+n)}}},{key:"getItemData",value:function(){var t=this.mentionList.childNodes[this.itemIndex].dataset.link,e=void 0!==t,n=this.mentionList.childNodes[this.itemIndex].dataset.target;return e&&(this.mentionList.childNodes[this.itemIndex].dataset.value='<a href="'.concat(t,'" target=').concat(n||this.options.linkTarget,">").concat(this.mentionList.childNodes[this.itemIndex].dataset.value)),this.mentionList.childNodes[this.itemIndex].dataset}},{key:"onContainerMouseMove",value:function(){this.suspendMouseEnter=!1}},{key:"selectItem",value:function(){var t=this;if(-1!==this.itemIndex){var e=this.getItemData();e.disabled||(this.options.onSelect(e,(function(e){t.insertItem(e)})),this.hideMentionList())}}},{key:"insertItem",value:function(e,n){var i,o=e;null!==o&&(this.options.showDenotationChar||(o.denotationChar=""),n?i=this.cursorPos:(i=this.mentionCharPos,this.quill.deleteText(this.mentionCharPos,this.cursorPos-this.mentionCharPos,t.sources.USER)),this.quill.insertEmbed(i,this.options.blotName,o,t.sources.USER),this.options.spaceAfterInsert?(this.quill.insertText(i+1," ",t.sources.USER),this.quill.setSelection(i+2,t.sources.USER)):this.quill.setSelection(i+1,t.sources.USER),this.hideMentionList())}},{key:"onItemMouseEnter",value:function(t){if(!this.suspendMouseEnter){var e=Number(t.target.dataset.index);Number.isNaN(e)||e===this.itemIndex||(this.itemIndex=e,this.highlightItem(!1))}}},{key:"onDisabledItemMouseEnter",value:function(t){this.suspendMouseEnter||(this.itemIndex=-1,this.highlightItem(!1))}},{key:"onItemClick",value:function(t){0===t.button&&(t.preventDefault(),t.stopImmediatePropagation(),this.itemIndex=t.currentTarget.dataset.index,this.highlightItem(),this.selectItem())}},{key:"onItemMouseDown",value:function(t){t.preventDefault(),t.stopImmediatePropagation()}},{key:"renderLoading",value:function(){if(this.options.renderLoading())if(this.mentionContainer.getElementsByClassName("ql-mention-loading").length>0)this.showMentionList();else{this.mentionList.innerHTML="";var t=document.createElement("div");t.className="ql-mention-loading",t.innerHTML=this.options.renderLoading(),this.mentionContainer.append(t),this.showMentionList()}}},{key:"removeLoading",value:function(){var t=this.mentionContainer.getElementsByClassName("ql-mention-loading");t.length>0&&t[0].remove()}},{key:"renderList",value:function(t,e,n){if(e&&e.length>0){this.removeLoading(),this.values=e,this.mentionList.innerHTML="";for(var i=-1,o=0;o<e.length;o+=1){var s=document.createElement("li");s.className=this.options.listItemClass?this.options.listItemClass:"",e[o].disabled?s.className+=" disabled":-1===i&&(i=o),s.dataset.index=o,s.innerHTML=this.options.renderItem(e[o],n),e[o].disabled?s.onmouseenter=this.onDisabledItemMouseEnter.bind(this):(s.onmouseenter=this.onItemMouseEnter.bind(this),s.onmouseup=this.onItemClick.bind(this),s.onmousedown=this.onItemMouseDown.bind(this)),s.dataset.denotationChar=t,this.mentionList.appendChild(p(s,e[o],this.options.dataAttributes))}this.itemIndex=i,this.highlightItem(),this.showMentionList()}else this.hideMentionList()}},{key:"nextItem",value:function(){var t,e=0;do{e++,t=(this.itemIndex+e)%this.values.length;var n="true"===this.mentionList.childNodes[t].dataset.disabled;if(e===this.values.length+1){t=-1;break}}while(n);this.itemIndex=t,this.suspendMouseEnter=!0,this.highlightItem()}},{key:"prevItem",value:function(){var t,e=0;do{e++,t=(this.itemIndex+this.values.length-e)%this.values.length;var n="true"===this.mentionList.childNodes[t].dataset.disabled;if(e===this.values.length+1){t=-1;break}}while(n);this.itemIndex=t,this.suspendMouseEnter=!0,this.highlightItem()}},{key:"containerBottomIsNotVisible",value:function(t,e){return t+this.mentionContainer.offsetHeight+e.top>window.pageYOffset+window.innerHeight}},{key:"containerRightIsNotVisible",value:function(t,e){return!this.options.fixMentionsToQuill&&t+this.mentionContainer.offsetWidth+e.left>window.pageXOffset+document.documentElement.clientWidth}},{key:"setIsOpen",value:function(t){this.isOpen!==t&&(t?this.options.onOpen():this.options.onClose(),this.isOpen=t)}},{key:"setMentionContainerPosition",value:function(){"fixed"===this.options.positioningStrategy?this.setMentionContainerPosition_Fixed():this.setMentionContainerPosition_Normal()}},{key:"setMentionContainerPosition_Normal",value:function(){var t=this,e=this.quill.container.getBoundingClientRect(),n=this.quill.getBounds(this.mentionCharPos),i=this.mentionContainer.offsetHeight,o=this.options.offsetTop,s=this.options.offsetLeft;if(this.options.fixMentionsToQuill){this.mentionContainer.style.right="".concat(0,"px")}else s+=n.left;if(this.containerRightIsNotVisible(s,e)){var a=this.mentionContainer.offsetWidth+this.options.offsetLeft;s=e.width-a}if("top"===this.options.defaultMenuOrientation){if((o=this.options.fixMentionsToQuill?-1*(i+this.options.offsetTop):n.top-(i+this.options.offsetTop))+e.top<=0){var r=this.options.offsetTop;this.options.fixMentionsToQuill?r+=e.height:r+=n.bottom,o=r}}else if(this.options.fixMentionsToQuill?o+=e.height:o+=n.bottom,this.containerBottomIsNotVisible(o,e)){var h=-1*this.options.offsetTop;this.options.fixMentionsToQuill||(h+=n.top),o=h-i}o>=0?this.options.mentionContainerClass.split(" ").forEach((function(e){t.mentionContainer.classList.add("".concat(e,"-bottom")),t.mentionContainer.classList.remove("".concat(e,"-top"))})):this.options.mentionContainerClass.split(" ").forEach((function(e){t.mentionContainer.classList.add("".concat(e,"-top")),t.mentionContainer.classList.remove("".concat(e,"-bottom"))})),this.mentionContainer.style.top="".concat(o,"px"),this.mentionContainer.style.left="".concat(s,"px"),this.mentionContainer.style.visibility="visible"}},{key:"setMentionContainerPosition_Fixed",value:function(){var t=this;this.mentionContainer.style.position="fixed",this.mentionContainer.style.height=null;var e=this.quill.container.getBoundingClientRect(),n=this.quill.getBounds(this.mentionCharPos),i={left:e.left+n.left,top:e.top+n.top,width:0,height:n.height},o=this.options.fixMentionsToQuill?e:i,s=this.options.offsetTop,a=this.options.offsetLeft;if(this.options.fixMentionsToQuill){var r=o.right;this.mentionContainer.style.right="".concat(r,"px")}else(a+=o.left)+this.mentionContainer.offsetWidth>document.documentElement.clientWidth&&(a-=a+this.mentionContainer.offsetWidth-document.documentElement.clientWidth);var h=o.top,l=document.documentElement.clientHeight-(o.top+o.height),u=this.mentionContainer.offsetHeight<=l,c=this.mentionContainer.offsetHeight<=h;"bottom"===("top"===this.options.defaultMenuOrientation&&c?"top":"bottom"===this.options.defaultMenuOrientation&&u||l>h?"bottom":"top")?(s=o.top+o.height,u||(this.mentionContainer.style.height=l-3+"px"),this.options.mentionContainerClass.split(" ").forEach((function(e){t.mentionContainer.classList.add("".concat(e,"-bottom")),t.mentionContainer.classList.remove("".concat(e,"-top"))}))):(s=o.top-this.mentionContainer.offsetHeight,c||(this.mentionContainer.style.height=h-3+"px",s=3),this.options.mentionContainerClass.split(" ").forEach((function(e){t.mentionContainer.classList.add("".concat(e,"-top")),t.mentionContainer.classList.remove("".concat(e,"-bottom"))}))),this.mentionContainer.style.top="".concat(s,"px"),this.mentionContainer.style.left="".concat(a,"px"),this.mentionContainer.style.visibility="visible"}},{key:"getTextBeforeCursor",value:function(){var t=Math.max(0,this.cursorPos-this.options.maxChars);return this.quill.getText(t,this.cursorPos-t)}},{key:"onSomethingChange",value:function(){var t=this,e=this.quill.getSelection();if(null!=e){this.cursorPos=e.index;var n,i=this.getTextBeforeCursor(),o=(n=i,this.options.mentionDenotationChars.reduce((function(t,e){var i=n.lastIndexOf(e);return i>t.mentionCharIndex?{mentionChar:e,mentionCharIndex:i}:{mentionChar:t.mentionChar,mentionCharIndex:t.mentionCharIndex}}),{mentionChar:null,mentionCharIndex:-1})),s=o.mentionChar,a=o.mentionCharIndex;if(function(t,e,n){return t>-1&&!(n&&0!==t&&!e[t-1].match(/\s/g))}(a,i,this.options.isolateCharacter)){var r=this.cursorPos-(i.length-a);this.mentionCharPos=r;var h=i.substring(a+s.length);if(h.length>=this.options.minChars&&function(t,e){return e.test(t)}(h,this.getAllowedCharsRegex(s))){this.existingSourceExecutionToken&&(this.existingSourceExecutionToken.abandoned=!0),this.renderLoading();var l={abandoned:!1};this.existingSourceExecutionToken=l,this.options.source(h,(function(e,n){l.abandoned||(t.existingSourceExecutionToken=null,t.renderList(s,e,n))}),s)}else this.hideMentionList()}else this.hideMentionList()}}},{key:"getAllowedCharsRegex",value:function(t){return this.options.allowedChars instanceof RegExp?this.options.allowedChars:this.options.allowedChars(t)}},{key:"onTextChange",value:function(t,e,n){"user"===n&&this.onSomethingChange()}},{key:"onSelectionChange",value:function(t){t&&0===t.length?this.onSomethingChange():this.hideMentionList()}},{key:"openMenu",value:function(t){var e=this.quill.getSelection(!0);this.quill.insertText(e.index,t),this.quill.blur(),this.quill.focus()}}]),n}();return t.register("modules/mention",C),C}(Quill);
{
"name": "quill-mention",
"version": "2.2.7",
"version": "3.0.0",
"description": "@mentions for the Quill rich text editor",

@@ -5,0 +5,0 @@ "main": "dist/quill.mention.csj.js",

@@ -141,27 +141,38 @@ ![Quill Mention](docs/static/quill-mention.png "Quill Mention")

| Property | Default | Description |
| --------------------------------------------- | ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `source(searchTerm, renderList, mentionChar)` | `null` | Required callback function to handle the search term and connect it to a data source for matches. The data source can be a local source or an AJAX request. The callback should call `renderList(matches, searchTerm);` with matches of JSON Objects in an array to show the result for the user. The JSON Objects should have `id` and `value` but can also have other values to be used in `renderItem` for custom display. |
| `renderItem(item, searchTerm)` | `function` | A function that gives you control over how matches from source are displayed. You can use this function to highlight the search term or change the design with custom HTML. |
| `allowedChars` | `[a-zA-Z0-9_]` | Allowed characters in search term triggering a search request using regular expressions |
| `minChars` | `0` | Minimum number of characters after the @ symbol triggering a search request |
| `maxChars` | `31` | Maximum number of characters after the @ symbol triggering a search request |
| `offsetTop` | `2` | Additional top offset of the mention container position |
| `offsetLeft` | `0` | Additional left offset of the mention container position |
| `mentionDenotationChars` | `["@"]` | Specifies which characters will cause the mention autocomplete to open |
| `isolateCharacter` | `false` | Whether or not the denotation character(s) should be isolated. For example, to avoid mentioning in an email. |
| `fixMentionsToQuill` | `false` | When set to true, the mentions menu will be rendered above or below the quill container. Otherwise, the mentions menu will track the denotation character(s); |
| `showDenotationChar` | `true` | Whether to show the used denotation character in the mention item or not |
| `defaultMenuOrientation` | `'bottom'` | Options are `'bottom'` and `'top'`. Determines what the default orientation of the menu will be. Quill-mention will attempt to render the menu either above or below the editor. If `'top'` is provided as a value, and there is not enough space above the editor, the menu will be rendered below. Vice versa, if there is not enough space below the editor, and `'bottom'` is provided as a value (or no value is provided at all), the menu will be rendered above the editor. |
| `blotName` | `'mention'` | The name of the [Quill Blot](https://github.com/quilljs/parchment#blots) to be used for inserted mentions. A default implementation is provided named 'mention', which may be overidden with a custom blot.
| `dataAttributes` | `['id', 'value', 'denotationChar', 'link', 'target']` | A list of data values you wish to be passed from your list data to the html node. (`id, value, denotationChar, link, target` are included by default). |
| `onOpen` | `function` | Callback when mention dropdown is open. |
| `onClose` | `function` | Callback when mention dropdown is closed. |
| `onSelect(item, insertItem)` | `function` | Callback for a selected item. When overriding this method, `insertItem` should be used to insert `item` to the editor. This makes async requests possible. |
| `linkTarget` | `'_blank'` | Link target for mentions with a link |
| `listItemClass` | `'ql-mention-list-item'` | Style class to be used for list items (may be null) |
| `mentionContainerClass` | `'ql-mention-list-container'` | Style class to be used for the mention list container (may be null) |
| `mentionListClass` | `'ql-mention-list'` | Style class to be used for the mention list (may be null) |
| `spaceAfterInsert` | `true` | Whether or not insert 1 space after mention block in text |
| Property | Default | Description |
| --------------------------------------------- | ---------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `source(searchTerm, renderList, mentionChar)` | `null` | Required callback function to handle the search term and connect it to a data source for matches. The data source can be a local source or an AJAX request. The callback should call `renderList(matches, searchTerm);` with matches of JSON Objects in an array to show the result for the user. The JSON Objects should have `id` and `value` but can also have other values to be used in `renderItem` for custom display. |
| `renderItem(item, searchTerm)` | `function` | A function that gives you control over how matches from source are displayed. You can use this function to highlight the search term or change the design with custom HTML. |
| `allowedChars` | `[a-zA-Z0-9_]` (or `function`) | Allowed characters in search term triggering a search request using regular expressions. Can be a function that takes the denotationChar and returns a regex. |
| `minChars` | `0` | Minimum number of characters after the @ symbol triggering a search request |
| `maxChars` | `31` | Maximum number of characters after the @ symbol triggering a search request |
| `offsetTop` | `2` | Additional top offset of the mention container position |
| `offsetLeft` | `0` | Additional left offset of the mention container position |
| `mentionDenotationChars` | `["@"]` | Specifies which characters will cause the mention autocomplete to open |
| `isolateCharacter` | `false` | Whether or not the denotation character(s) should be isolated. For example, to avoid mentioning in an email. |
| `fixMentionsToQuill` | `false` | When set to true, the mentions menu will be rendered above or below the quill container. Otherwise, the mentions menu will track the denotation character(s); |
| `showDenotationChar` | `true` | Whether to show the used denotation character in the mention item or not |
| `defaultMenuOrientation` | `'bottom'` | Options are `'bottom'` and `'top'`. Determines what the default orientation of the menu will be. Quill-mention will attempt to render the menu either above or below the editor. If `'top'` is provided as a value, and there is not enough space above the editor, the menu will be rendered below. Vice versa, if there is not enough space below the editor, and `'bottom'` is provided as a value (or no value is provided at all), the menu will be rendered above the editor. |
| `blotName` | `'mention'` | The name of the [Quill Blot](https://github.com/quilljs/parchment#blots) to be used for inserted mentions. A default implementation is provided named 'mention', which may be overidden with a custom blot. |
| `dataAttributes` | `['id', 'value', 'denotationChar', 'link', 'target','disabled']` | A list of data values you wish to be passed from your list data to the html node. (`id, value, denotationChar, link, target` are included by default). |
| `onOpen` | `function` | Callback when mention dropdown is open. |
| `onClose` | `function` | Callback when mention dropdown is closed. |
| `onSelect(item, insertItem)` | `function` | Callback for a selected item. When overriding this method, `insertItem` should be used to insert `item` to the editor. This makes async requests possible. |
| `linkTarget` | `'_blank'` | Link target for mentions with a link |
| `listItemClass` | `'ql-mention-list-item'` | Style class to be used for list items (may be null) |
| `mentionContainerClass` | `'ql-mention-list-container'` | Style class to be used for the mention list container (may be null) |
| `mentionListClass` | `'ql-mention-list'` | Style class to be used for the mention list (may be null) |
| `spaceAfterInsert` | `true` | Whether or not insert 1 space after mention block in text |
| `positioningStrategy` | `'absolute'` | Options are `'normal'` and `'fixed'`. When `'fixed'`, the menu will be appended to the body and use fixed positioning. Use this if the menu is clipped by a parent element that's using `overflow:hidden|scroll`. |
| `renderLoading` | `function` | A function that returns the HTML for a loading message during async calls from `source`. The default functions returns `null` to prevent a loading message. |
### Methods
You may retrieve the module from Quill like `quill.getModule('mention')` then call one of the imperative methdos below.
| Method | Example | Description |
| -------------------------------------- | ------------------------------------------------ | ----------------------------------------------------------- |
| `insertItem(data, programmaticInsert)` | `insertItem({id:'123',value:'My Mention'},true)` | Inserts the given mention into the editor. |
| `openMenu(denotationChar)` | `openMenu('@')` | Opens the mentions menu for the given denotation character. |
### Styling

@@ -171,2 +182,6 @@

### Headers and Informational Items
Sometimes you may want to display a menu item that should not be selectable. These items may be group headers, hint text, or even a message saying there were no matching results. To show items like these, add `disabled:true` to items passed to `renderList` from your `source` method. Disabled items are shown but not selectable with the mouse or keyboard. If you need to style the disabled items differently, you will need to override the `renderItem` method.
## Authors

@@ -173,0 +188,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc