Quill использует класс Delta для описания формата расширенного текста, и мы можем использовать метод Quill getContents
для получения всех записей содержимого, которые будут в следующем формате:
Delta {
ops: [
insert: "↵↵↵Hello↵world!↵↵"
]
}
Мы должны создать логи c, используя al oop через все эти записи, обнаруживать и исключать начало и конец строки.
Мы используем два массива, один массив, который мы Мы будем хранить новые дельта-записи и одну для хранения ожидающих окончания строки, которые мы можем или не можем добавить к массиву новых дельта-записей. У нас также будет флаг, указывающий, зафиксировали ли мы лидирующие переводы строки.
Это решение использует этот метод "обработка события размытия" для обнаружения события размытия.
Код и фрагмент кода Quill Blur ( запустить, чтобы увидеть его в действии ):
Пожалуйста, прочитайте встроенные комментарии
let quills = [];
[...document.getElementsByClassName('quill-editor')].forEach((el, idx) => {
const quill = new Quill(el, {
modules: {
toolbar: [
[{ header: [1, 2, false] }],
['bold', 'italic', 'underline'],
['image', 'code-block']
]
},
placeholder: 'Compose an epic...',
theme: 'snow' // or 'bubble'
});
quill.on('selection-change', function(range, oldRange, source) {
if (range === null && oldRange !== null) {
const delta = quill.getContents();
let leadingFixed = false;
let newDelta = [];
let tempDelta = [];
if(delta.ops.length === 1) {
// If there is only one entry, check if it's a string and trim leading and ending LF
let { insert, attributes } = delta.ops[0];
if(typeof(insert) === 'string') {
insert = insert.replace(/^\n+|\n+$/g, '');
}
newDelta = [{ insert, attributes }];
} else {
// Else go through all the insert entries
delta.ops.forEach(({ insert, attributes }, idx) => {
// Create a boolean to indicate if we're at the last entry
const isLast = idx === delta.ops.length - 1;
// If the entry is a string (not image/asset)
if(typeof(insert) === 'string') {
// If we haven't fixed the leading
if(!leadingFixed) {
// If the entry begins with LFs
if(/^\n+/.test(insert)) {
// Create a string witrh clean leading LFs
let cleanText = insert.replace(/^\n+/, '');
// If there is text after cleaning the LFs
if(cleanText.length > 0) {
// Add the text to the newDelta
newDelta.push({
insert: cleanText,
attributes
});
// Set leading flag to indicate we've fixed the leading
leadingFixed = true;
}
// Else if the entry does not start with LFs
} else {
// If the entry does not begin with LFs
// Add any pending entries that may exists in tempDelta to the newDelta
newDelta = newDelta.concat(tempDelta);
// Add the existing entry
newDelta.push({
insert,
attributes
});
// Clean the any pending entries
tempDelta = [];
// And set the leading flag to indicate we've fixed the leading
leadingFixed = true;
}
// Else if we have fixed the leading
} else {
// If there an entry with ending LFs
if(/\n+$/.test(insert)) {
// Create a string witrh clean ending LFs
let cleanText = insert.replace(/\n+$/, '');
// If this is the last entry
if(isLast) {
// If there is text after cleaning the LFs
if(cleanText.length > 0) {
// Add any pending entries that may exists in tempDelta to the newDelta
newDelta = newDelta.concat(tempDelta);
// Add the cleaned entry
newDelta.push({
insert: cleanText,
attributes
});
}
// Else if this is not the last entry
} else {
// If there is text after cleaning the LFs
if(cleanText.length > 0) {
// Add any pending entries that may exists in tempDelta to the newDelta
newDelta = newDelta.concat(tempDelta);
// Add the existing entry
newDelta.push({
insert,
attributes
});
// Clean the any pending entries
tempDelta = [];
// Else if there is no text after cleaning the LFs
} else {
// Add the entry to the temp deltas so to use them later if its needed
tempDelta.push({ insert, attributes });
}
}
// Else if the entry does not end with LFs
} else {
// Add any pending entries that may exists in tempDelta to the newDelta
newDelta = newDelta.concat(tempDelta);
// Add the existing entry
newDelta.push({
insert,
attributes
});
// Clean the any pending entries
tempDelta = [];
}
}
// If the entry is not a string
} else {
// Then all leading text/line feeds have been cleared if there were any
// so, it's safe to set the leading flag
leadingFixed = true;
// Add any pending entries that may exists in tempDelta to the newDelta
newDelta = newDelta.concat(tempDelta);
// Add the existing entry
newDelta.push({
insert,
attributes
})
// Clean the any pending entries
tempDelta = [];
}
});
}
quill.setContents(newDelta);
} /*else if (range !== null && oldRange === null) {
console.log('focus');
}*/
});
quills.push(quill);
});
.editors {
display: flex;
}
.quill-editor-container {
flex: 1;
}
.quill-editor {
height: 100px !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/quill/1.3.7/quill.core.js" integrity="sha256-jvauzib5XGeoiDyHV6mlZnpuKsEAcjhruilbo0e+L6k=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/quill/1.3.7/quill.js" integrity="sha256-CN8TogJAzCcMj0uYishm9mmawPUFKJeJh//zR/CfCO8=" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/quill/1.3.7/quill.core.css" integrity="sha256-2kIq+5smyR4blGwdXXCCVrPLENwavLyrG8+kLPfDPJk=" crossorigin="anonymous" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/quill/1.3.7/quill.bubble.css" integrity="sha256-2hxHujXw890GumwDHPWrwJCtdZZdrJanlGsrOTSfXnc=" crossorigin="anonymous" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/quill/1.3.7/quill.snow.css" integrity="sha256-jyIuRMWD+rz7LdpWfybO8U6DA65JCVkjgrt31FFsnAE=" crossorigin="anonymous" />
<div class="editors">
<div class="quill-editor-container"><div class="quill-editor"></div></div>
<div class="quill-editor-container"><div class="quill-editor"></div></div>
</div>
Я протестировал его с активами изображений и форматированием, и, похоже, он работает довольно хорошо. Конечно, код можно дополнительно оптимизировать и, возможно, упростить.
Вы также можете проверить этот проект Stackblitz , если хотите его разветвить и провести несколько тестов.