Quill link 处理程序不工作
Quill link handler not working
我正在尝试为 link 输入值编写自定义处理程序。如果用户输入没有自定义协议的 link,我希望在输入值之前添加一个 http:
。这是因为如果 link 值缺少 http:,则不会解释 link,而是显示 about:blank
。 (https://github.com/quilljs/quill/issues/1268#issuecomment-272959998)
下面是我写的(类似于官方的例子here):
toolbar.addHandler("link", function sanitizeLinkInput(linkValueInput) {
console.log(linkValueInput); // debugging
if (linkValueInput === "")
this.quill.format(false);
// do nothing, since it implies user has just clicked the icon
// for link, hasn't entered url yet
else if (linkValueInput == true);
// do nothing, since this implies user's already using a custom protocol
else if (/^\w+:/.test(linkValueInput));
else if (!/^https?:/.test(linkValueInput)) {
linkValueInput = "http:" + linkValueInput;
this.quill.format("link", linkValueInput);
}
});
每次用户单击 link 图标时,没有任何反应,并且 true
会记录到控制台。我实际上希望当人们在按下 link 图标后显示的工具提示上单击 "save" 时执行此处理程序。
知道怎么做吗?也欢迎提示或建议。
谢谢!
据我所知,创建和更新 links 的处理有点分散在 Quill 的源代码中。默认的 Snow 主题在某种程度上处理编辑 links:它跟踪用户选择和内部最后选择的 link。因此,我认为仅使用自定义处理程序不可能在 Quill 中实现您当前想要的。
你可能想打开一个问题来报告这个,作者可能愿意添加这样的处理程序。
与此同时,我想出了一种更新 link 的方法,只需监听导致编辑工具提示关闭的事件。有一些复杂性,因为可以编辑 link,然后主题依赖于其内部跟踪来更新它。但是,总而言之,我认为这个解决方案还不错。您可能想在这里和那里添加一些错误检查,但总的来说它似乎工作得很好并且可以做您想做的事。我创建了一个 Fiddle 来证明这一点。为了完整起见,我也将其作为代码片段包含在此处。
var quill = new Quill('#editor', {
modules: {
toolbar: true
},
theme: 'snow'
}),
editor = document.getElementById('editor'),
lastLinkRange = null;
/**
* Add protocol to link if it is missing. Considers the current selection in Quill.
*/
function updateLink() {
var selection = quill.getSelection(),
selectionChanged = false;
if (selection === null) {
var tooltip = quill.theme.tooltip;
if (tooltip.hasOwnProperty('linkRange')) {
// user started to edit a link
lastLinkRange = tooltip.linkRange;
return;
} else {
// user finished editing a link
var format = quill.getFormat(lastLinkRange),
link = format.link;
quill.setSelection(lastLinkRange.index, lastLinkRange.length, 'silent');
selectionChanged = true;
}
} else {
var format = quill.getFormat();
if (!format.hasOwnProperty('link')) {
return; // not a link after all
}
var link = format.link;
}
// add protocol if not there yet
if (!/^https?:/.test(link)) {
link = 'http:' + link;
quill.format('link', link);
// reset selection if we changed it
if (selectionChanged) {
if (selection === null) {
quill.setSelection(selection, 0, 'silent');
} else {
quill.setSelection(selection.index, selection.length, 'silent');
}
}
}
}
// listen for clicking 'save' button
editor.addEventListener('click', function(event) {
// only respond to clicks on link save action
if (event.target === editor.querySelector('.ql-tooltip[data-mode="link"] .ql-action')) {
updateLink();
}
});
// listen for 'enter' button to save URL
editor.addEventListener('keydown', function(event) {
// only respond to clicks on link save action
var key = (event.which || event.keyCode);
if (key === 13 && event.target === editor.querySelector('.ql-tooltip[data-mode="link"] input')) {
updateLink();
}
});
<link href="https://cdn.quilljs.com/1.1.10/quill.snow.css" rel="stylesheet" />
<script src="https://cdn.quilljs.com/1.1.10/quill.min.js"></script>
<div id="editor"></div>
如果您有任何问题,请告诉我。
单击工具栏中的按钮时,工具栏处理程序将调用您给定的函数。传入的 value
取决于该格式在用户选择中的状态。因此,如果用户只突出显示纯文本,并单击 link 按钮,您将得到 false
。如果用户突出显示 link,您将获得 link 的值,默认情况下为 url。这里用一个例子来解释:http://quilljs.com/docs/modules/toolbar/#handlers.
雪花主题使用工具栏的 addHandler 本身来显示工具提示,看起来您正在尝试连接到此,目前无法实现。
看起来您真正想做的是控制 link 的清理逻辑。清理存在于 Quill 的较低级别,因为有许多方法可以插入 link,例如从工具提示 UI、粘贴、不同的 API 等等。因此,为了涵盖它们,所有逻辑都在 link 格式本身中。 link 的自定义格式的示例具体包含在 http://quilljs.com/guides/cloning-medium-with-parchment/#links 中。您也可以只修改 Quill 自己的 sanitize 方法,但不推荐这样做,因为它没有记录也没有被 semver 涵盖。
let Link = Quill.import('formats/link');
Link.sanitize = function(value) {
return 'customsanitizedvalue';
}
汇总所有信息
雪花主题本身使用工具栏的 addHandler 来显示工具提示,因此无法使用 addHandler 方法来实现我们想要的。
因此,我们可以执行以下操作:
var Link = Quill.import('formats/link');
var builtInFunc = Link.sanitize;
Link.sanitize = function customSanitizeLinkInput(linkValueInput) {
var val = linkValueInput;
// do nothing, since this implies user's already using a custom protocol
if (/^\w+:/.test(val));
else if (!/^https?:/.test(val))
val = "http:" + val;
return builtInFunc.call(this, val); // retain the built-in logic
};
此方法不会挂接到处理程序,而是会修改 built-in 清理逻辑本身。我们还保留了清理的原始行为,因此不会修改编辑器的原始行为。
或者,我们实际上可以使用 钩住工具提示的保存按钮。但与上面的方法相比,它是一种太长的方法。
半小时后
找到这个解决方案
htmlEditorModuleConfig = {
toolbar: [
['link']
],
bounds: document.body
}
在配置中添加'bounds: document.body'
我必须做同样的事情,(在发送到服务器之前验证 url)所以我最终得到了这样的东西。
const editor = new DOMParser().parseFromString(value,
'text/html');
const body = qlEditor.getElementsByTagName('body');
const data = document.createElement('div');
data.innerHTML = body[0].innerHTML;
Array.from(data.querySelectorAll('a')).forEach((ele) => {
let href = ele.getAttribute('href');
if (!href.includes('http') && !href.includes('https')) {
href = `https://${href}`;
ele.setAttribute('href', href);
}
});
body[0].innerHTML = data.innerHTML;
也许这是一个老问题,但这是我让它工作的方式。
首先,它将其他自定义协议列入白名单以作为有效协议接受。
然后,我们 运行 已经包含在 Quill 核心中的 sanitize
方法,并且基于自定义协议列表它将 return URL 或 about:blank
.
然后,如果这是一个 about:blank
是因为它没有通过消毒方法。如果我们得到 URL 然后我们验证它是否有列表中的协议,如果没有,那么我们附加 http://
这样我们就不会得到相对 URL 或空白除非它没有被列入白名单:
https://your-site.com/www.apple.com
about:blank
希望它能帮助遇到同样问题的其他人。
const Link = Quill.import('formats/link')
// Override the existing property on the Quill global object and add custom protocols
Link.PROTOCOL_WHITELIST = ['http', 'https', 'mailto', 'tel', 'radar', 'rdar', 'smb', 'sms']
class CustomLinkSanitizer extends Link {
static sanitize(url) {
// Run default sanitize method from Quill
const sanitizedUrl = super.sanitize(url)
// Not whitelisted URL based on protocol so, let's return `blank`
if (!sanitizedUrl || sanitizedUrl === 'about:blank') return sanitizedUrl
// Verify if the URL already have a whitelisted protocol
const hasWhitelistedProtocol = this.PROTOCOL_WHITELIST.some(function(protocol) {
return sanitizedUrl.startsWith(protocol)
})
if (hasWhitelistedProtocol) return sanitizedUrl
// if not, then append only 'http' to not to be a relative URL
return `http://${sanitizedUrl}`
}
}
Quill.register(CustomLinkSanitizer, true)
我正在尝试为 link 输入值编写自定义处理程序。如果用户输入没有自定义协议的 link,我希望在输入值之前添加一个 http:
。这是因为如果 link 值缺少 http:,则不会解释 link,而是显示 about:blank
。 (https://github.com/quilljs/quill/issues/1268#issuecomment-272959998)
下面是我写的(类似于官方的例子here):
toolbar.addHandler("link", function sanitizeLinkInput(linkValueInput) {
console.log(linkValueInput); // debugging
if (linkValueInput === "")
this.quill.format(false);
// do nothing, since it implies user has just clicked the icon
// for link, hasn't entered url yet
else if (linkValueInput == true);
// do nothing, since this implies user's already using a custom protocol
else if (/^\w+:/.test(linkValueInput));
else if (!/^https?:/.test(linkValueInput)) {
linkValueInput = "http:" + linkValueInput;
this.quill.format("link", linkValueInput);
}
});
每次用户单击 link 图标时,没有任何反应,并且 true
会记录到控制台。我实际上希望当人们在按下 link 图标后显示的工具提示上单击 "save" 时执行此处理程序。
知道怎么做吗?也欢迎提示或建议。
谢谢!
据我所知,创建和更新 links 的处理有点分散在 Quill 的源代码中。默认的 Snow 主题在某种程度上处理编辑 links:它跟踪用户选择和内部最后选择的 link。因此,我认为仅使用自定义处理程序不可能在 Quill 中实现您当前想要的。
你可能想打开一个问题来报告这个,作者可能愿意添加这样的处理程序。
与此同时,我想出了一种更新 link 的方法,只需监听导致编辑工具提示关闭的事件。有一些复杂性,因为可以编辑 link,然后主题依赖于其内部跟踪来更新它。但是,总而言之,我认为这个解决方案还不错。您可能想在这里和那里添加一些错误检查,但总的来说它似乎工作得很好并且可以做您想做的事。我创建了一个 Fiddle 来证明这一点。为了完整起见,我也将其作为代码片段包含在此处。
var quill = new Quill('#editor', {
modules: {
toolbar: true
},
theme: 'snow'
}),
editor = document.getElementById('editor'),
lastLinkRange = null;
/**
* Add protocol to link if it is missing. Considers the current selection in Quill.
*/
function updateLink() {
var selection = quill.getSelection(),
selectionChanged = false;
if (selection === null) {
var tooltip = quill.theme.tooltip;
if (tooltip.hasOwnProperty('linkRange')) {
// user started to edit a link
lastLinkRange = tooltip.linkRange;
return;
} else {
// user finished editing a link
var format = quill.getFormat(lastLinkRange),
link = format.link;
quill.setSelection(lastLinkRange.index, lastLinkRange.length, 'silent');
selectionChanged = true;
}
} else {
var format = quill.getFormat();
if (!format.hasOwnProperty('link')) {
return; // not a link after all
}
var link = format.link;
}
// add protocol if not there yet
if (!/^https?:/.test(link)) {
link = 'http:' + link;
quill.format('link', link);
// reset selection if we changed it
if (selectionChanged) {
if (selection === null) {
quill.setSelection(selection, 0, 'silent');
} else {
quill.setSelection(selection.index, selection.length, 'silent');
}
}
}
}
// listen for clicking 'save' button
editor.addEventListener('click', function(event) {
// only respond to clicks on link save action
if (event.target === editor.querySelector('.ql-tooltip[data-mode="link"] .ql-action')) {
updateLink();
}
});
// listen for 'enter' button to save URL
editor.addEventListener('keydown', function(event) {
// only respond to clicks on link save action
var key = (event.which || event.keyCode);
if (key === 13 && event.target === editor.querySelector('.ql-tooltip[data-mode="link"] input')) {
updateLink();
}
});
<link href="https://cdn.quilljs.com/1.1.10/quill.snow.css" rel="stylesheet" />
<script src="https://cdn.quilljs.com/1.1.10/quill.min.js"></script>
<div id="editor"></div>
如果您有任何问题,请告诉我。
单击工具栏中的按钮时,工具栏处理程序将调用您给定的函数。传入的 value
取决于该格式在用户选择中的状态。因此,如果用户只突出显示纯文本,并单击 link 按钮,您将得到 false
。如果用户突出显示 link,您将获得 link 的值,默认情况下为 url。这里用一个例子来解释:http://quilljs.com/docs/modules/toolbar/#handlers.
雪花主题使用工具栏的 addHandler 本身来显示工具提示,看起来您正在尝试连接到此,目前无法实现。
看起来您真正想做的是控制 link 的清理逻辑。清理存在于 Quill 的较低级别,因为有许多方法可以插入 link,例如从工具提示 UI、粘贴、不同的 API 等等。因此,为了涵盖它们,所有逻辑都在 link 格式本身中。 link 的自定义格式的示例具体包含在 http://quilljs.com/guides/cloning-medium-with-parchment/#links 中。您也可以只修改 Quill 自己的 sanitize 方法,但不推荐这样做,因为它没有记录也没有被 semver 涵盖。
let Link = Quill.import('formats/link');
Link.sanitize = function(value) {
return 'customsanitizedvalue';
}
汇总所有信息
雪花主题本身使用工具栏的 addHandler 来显示工具提示,因此无法使用 addHandler 方法来实现我们想要的。
因此,我们可以执行以下操作:
var Link = Quill.import('formats/link');
var builtInFunc = Link.sanitize;
Link.sanitize = function customSanitizeLinkInput(linkValueInput) {
var val = linkValueInput;
// do nothing, since this implies user's already using a custom protocol
if (/^\w+:/.test(val));
else if (!/^https?:/.test(val))
val = "http:" + val;
return builtInFunc.call(this, val); // retain the built-in logic
};
此方法不会挂接到处理程序,而是会修改 built-in 清理逻辑本身。我们还保留了清理的原始行为,因此不会修改编辑器的原始行为。
或者,我们实际上可以使用
半小时后
找到这个解决方案
htmlEditorModuleConfig = {
toolbar: [
['link']
],
bounds: document.body
}
在配置中添加'bounds: document.body'
我必须做同样的事情,(在发送到服务器之前验证 url)所以我最终得到了这样的东西。
const editor = new DOMParser().parseFromString(value,
'text/html');
const body = qlEditor.getElementsByTagName('body');
const data = document.createElement('div');
data.innerHTML = body[0].innerHTML;
Array.from(data.querySelectorAll('a')).forEach((ele) => {
let href = ele.getAttribute('href');
if (!href.includes('http') && !href.includes('https')) {
href = `https://${href}`;
ele.setAttribute('href', href);
}
});
body[0].innerHTML = data.innerHTML;
也许这是一个老问题,但这是我让它工作的方式。
首先,它将其他自定义协议列入白名单以作为有效协议接受。
然后,我们 运行 已经包含在 Quill 核心中的 sanitize
方法,并且基于自定义协议列表它将 return URL 或 about:blank
.
然后,如果这是一个 about:blank
是因为它没有通过消毒方法。如果我们得到 URL 然后我们验证它是否有列表中的协议,如果没有,那么我们附加 http://
这样我们就不会得到相对 URL 或空白除非它没有被列入白名单:
https://your-site.com/www.apple.com
about:blank
希望它能帮助遇到同样问题的其他人。
const Link = Quill.import('formats/link')
// Override the existing property on the Quill global object and add custom protocols
Link.PROTOCOL_WHITELIST = ['http', 'https', 'mailto', 'tel', 'radar', 'rdar', 'smb', 'sms']
class CustomLinkSanitizer extends Link {
static sanitize(url) {
// Run default sanitize method from Quill
const sanitizedUrl = super.sanitize(url)
// Not whitelisted URL based on protocol so, let's return `blank`
if (!sanitizedUrl || sanitizedUrl === 'about:blank') return sanitizedUrl
// Verify if the URL already have a whitelisted protocol
const hasWhitelistedProtocol = this.PROTOCOL_WHITELIST.some(function(protocol) {
return sanitizedUrl.startsWith(protocol)
})
if (hasWhitelistedProtocol) return sanitizedUrl
// if not, then append only 'http' to not to be a relative URL
return `http://${sanitizedUrl}`
}
}
Quill.register(CustomLinkSanitizer, true)