在Firefox扩展中验证偏好值的普遍接受的方法是什么,特别是在XUL中使用prefwindow机制时?
我在我的一个扩展中引入了一些新的首选项,我希望在首选项窗口关闭之前进行验证。如果出现错误,应允许用户更正问题,然后继续。我看到prefwindow
元素在这方面有两个可能有用的功能:
前者似乎有一个相关的错误(Bug 474527),阻止prefwindow
在从该函数返回false
时保持打开状态。这很糟糕,因为它不会让用户立即纠正错误。
后者似乎存在以下问题:首选项在退出之前被保存,这使得首选项在内部处于错误状态。
此外,prefwindow
机制支持browser.preferences.instantApply
选项,其中在更新关联控件时立即写入首选项值。这使得验证更加棘手。有没有一种干净的方法来验证Firefox扩展中的自定义首选项,允许用户纠正任何潜在的错误?
答案 0 :(得分:2)
通常,您希望在更改时验证首选项。 onchange
attribute(以及相应的change
事件)适用于:
<preference name="preference.name" onchange="validate(this);"/>
在首选项值更改后触发事件。有两个缺点:
instantApply
新优惠价值已经保存,则验证和拒绝为时已晚。您可以通过拦截实际输入字段的更改事件来解决第一个问题。例如,对于文本字段,您可以执行以下操作:
<input preference="preference.name"
oninput="if (!validate(this)) event.stopPropagation();"
onchange="if (!validate(this)) { event.stopPropagation(); this.focus(); }"/>
因此,未正确验证的更改不会冒泡到<prefpane>
元素,也不会保存。要收听的事件包括:input
和change
用于文本字段,command
用于按钮和复选框,select
用于<colorpicker>
元素。
第二个问题很棘手。您仍然希望在输入发生时验证输入,然后立即显示消息将是错误的UI。我认为最好的解决方案是首先假设每个输入字段仍处于“进行中”状态。当您第一次在该字段上看到blur
事件时,您只需设置一个标记,表示该值已完成。那时您可以在必要时显示验证消息(理想情况下红色文本显示在您的首选项页面中,而不是模态提示)。
所以说明最终解决方案可能是什么样的(未经测试的代码,但过去我使用过类似的代码):
<description id="error" hidden="true">Invalid preference value</description>
<input preference="preference.name"
_errorText="error"
onblur="validate(event);"
oninput="validate(event);"
onchange="validate(event);/>
<script>
function validate(event)
{
// Perform actual validation
var field = event.target;
var valid = isValid(field);
// If this is the blur event then the element is no longer "in progress"
if (event.type == "blur")
{
field._inputDone = true;
if (!valid)
field.focus();
}
// Prevent preferences changing to invalid value
if (!valid)
event.stopPropagation();
// Show or hide error text
var errorText = document.getElementById(field.getAttribute("_errorText"));
errorText.hidden = valid || !field._inputDone;
}
</script>
答案 1 :(得分:1)
如果您希望在字段更改后立即验证值,以便处理instantApply
案例,则可以挂钩各个字段的更改事件(例如oninput
表示{{{3}} 1}})。如果值无效,则显示错误消息并强制将焦点返回到字段。您可以自动将其设置回有效值,也可以阻止用户关闭对话框,直到修复为止。