mirror of
				https://github.com/node-red/node-red.git
				synced 2025-03-01 10:36:34 +00:00 
			
		
		
		
	Add tooltip input validation msg
This commit is contained in:
		@@ -166,68 +166,74 @@
 | 
			
		||||
        { value: "_session", source: ["websocket out","tcp out"] },
 | 
			
		||||
    ]
 | 
			
		||||
    var allOptions = {
 | 
			
		||||
        msg: {value:"msg",label:"msg.",validate:RED.utils.validatePropertyExpression, autoComplete: autoComplete(msgCompletions)},
 | 
			
		||||
        flow: {value:"flow",label:"flow.",hasValue:true,
 | 
			
		||||
            options:[],
 | 
			
		||||
            validate:RED.utils.validatePropertyExpression,
 | 
			
		||||
        msg: { value: "msg", label: "msg.", validate: RED.utils.validatePropertyExpression, autoComplete: autoComplete(msgCompletions) },
 | 
			
		||||
        flow: {
 | 
			
		||||
            value: "flow", label: "flow.", hasValue: true,
 | 
			
		||||
            options: [],
 | 
			
		||||
            validate: RED.utils.validatePropertyExpression,
 | 
			
		||||
            parse: contextParse,
 | 
			
		||||
            export: contextExport,
 | 
			
		||||
            valueLabel: contextLabel
 | 
			
		||||
        },
 | 
			
		||||
        global: {value:"global",label:"global.",hasValue:true,
 | 
			
		||||
            options:[],
 | 
			
		||||
            validate:RED.utils.validatePropertyExpression,
 | 
			
		||||
        global: {
 | 
			
		||||
            value: "global", label: "global.", hasValue: true,
 | 
			
		||||
            options: [],
 | 
			
		||||
            validate: RED.utils.validatePropertyExpression,
 | 
			
		||||
            parse: contextParse,
 | 
			
		||||
            export: contextExport,
 | 
			
		||||
            valueLabel: contextLabel
 | 
			
		||||
        },
 | 
			
		||||
        str: {value:"str",label:"string",icon:"red/images/typedInput/az.svg"},
 | 
			
		||||
        num: {value:"num",label:"number",icon:"red/images/typedInput/09.svg",validate: function(v) {
 | 
			
		||||
            return (true === RED.utils.validateTypedProperty(v, "num"));
 | 
			
		||||
        str: { value: "str", label: "string", icon: "red/images/typedInput/az.svg" },
 | 
			
		||||
        num: { value: "num", label: "number", icon: "red/images/typedInput/09.svg", validate: function (v, o) {
 | 
			
		||||
            return RED.utils.validateTypedProperty(v, "num", o);
 | 
			
		||||
        } },
 | 
			
		||||
        bool: {value:"bool",label:"boolean",icon:"red/images/typedInput/bool.svg",options:["true","false"]},
 | 
			
		||||
        bool: { value: "bool", label: "boolean", icon: "red/images/typedInput/bool.svg", options: ["true", "false"] },
 | 
			
		||||
        json: {
 | 
			
		||||
            value:"json",
 | 
			
		||||
            label:"JSON",
 | 
			
		||||
            icon:"red/images/typedInput/json.svg",
 | 
			
		||||
            validate: function(v) { try{JSON.parse(v);return true;}catch(e){return false;}},
 | 
			
		||||
            expand: function() {
 | 
			
		||||
            value: "json",
 | 
			
		||||
            label: "JSON",
 | 
			
		||||
            icon: "red/images/typedInput/json.svg",
 | 
			
		||||
            validate: function (v, o) {
 | 
			
		||||
                return RED.utils.validateTypedProperty(v, "json", o);
 | 
			
		||||
            },
 | 
			
		||||
            expand: function () {
 | 
			
		||||
                var that = this;
 | 
			
		||||
                var value = this.value();
 | 
			
		||||
                try {
 | 
			
		||||
                    value = JSON.stringify(JSON.parse(value),null,4);
 | 
			
		||||
                } catch(err) {
 | 
			
		||||
                    value = JSON.stringify(JSON.parse(value), null, 4);
 | 
			
		||||
                } catch (err) {
 | 
			
		||||
                }
 | 
			
		||||
                RED.editor.editJSON({
 | 
			
		||||
                    value: value,
 | 
			
		||||
                    stateId: RED.editor.generateViewStateId("typedInput", that, "json"),
 | 
			
		||||
                    focus: true,
 | 
			
		||||
                    complete: function(v) {
 | 
			
		||||
                    complete: function (v) {
 | 
			
		||||
                        var value = v;
 | 
			
		||||
                        try {
 | 
			
		||||
                            value = JSON.stringify(JSON.parse(v));
 | 
			
		||||
                        } catch(err) {
 | 
			
		||||
                        } catch (err) {
 | 
			
		||||
                        }
 | 
			
		||||
                        that.value(value);
 | 
			
		||||
                    }
 | 
			
		||||
                })
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        re: {value:"re",label:"regular expression",icon:"red/images/typedInput/re.svg"},
 | 
			
		||||
        date: {value:"date",label:"timestamp",icon:"fa fa-clock-o",hasValue:false},
 | 
			
		||||
        re: { value: "re", label: "regular expression", icon: "red/images/typedInput/re.svg" },
 | 
			
		||||
        date: { value: "date", label: "timestamp", icon: "fa fa-clock-o", hasValue: false },
 | 
			
		||||
        jsonata: {
 | 
			
		||||
            value: "jsonata",
 | 
			
		||||
            label: "expression",
 | 
			
		||||
            icon: "red/images/typedInput/expr.svg",
 | 
			
		||||
            validate: function(v) { try{jsonata(v);return true;}catch(e){return false;}},
 | 
			
		||||
            expand:function() {
 | 
			
		||||
            validate: function (v, o) {
 | 
			
		||||
                return RED.utils.validateTypedProperty(v, "jsonata", o);
 | 
			
		||||
            },
 | 
			
		||||
            expand: function () {
 | 
			
		||||
                var that = this;
 | 
			
		||||
                RED.editor.editExpression({
 | 
			
		||||
                    value: this.value().replace(/\t/g,"\n"),
 | 
			
		||||
                    value: this.value().replace(/\t/g, "\n"),
 | 
			
		||||
                    stateId: RED.editor.generateViewStateId("typedInput", that, "jsonata"),
 | 
			
		||||
                    focus: true,
 | 
			
		||||
                    complete: function(v) {
 | 
			
		||||
                        that.value(v.replace(/\n/g,"\t"));
 | 
			
		||||
                    complete: function (v) {
 | 
			
		||||
                        that.value(v.replace(/\n/g, "\t"));
 | 
			
		||||
                    }
 | 
			
		||||
                })
 | 
			
		||||
            }
 | 
			
		||||
@@ -236,13 +242,13 @@
 | 
			
		||||
            value: "bin",
 | 
			
		||||
            label: "buffer",
 | 
			
		||||
            icon: "red/images/typedInput/bin.svg",
 | 
			
		||||
            expand: function() {
 | 
			
		||||
            expand: function () {
 | 
			
		||||
                var that = this;
 | 
			
		||||
                RED.editor.editBuffer({
 | 
			
		||||
                    value: this.value(),
 | 
			
		||||
                    stateId: RED.editor.generateViewStateId("typedInput", that, "bin"),
 | 
			
		||||
                    focus: true,
 | 
			
		||||
                    complete: function(v) {
 | 
			
		||||
                    complete: function (v) {
 | 
			
		||||
                        that.value(v);
 | 
			
		||||
                    }
 | 
			
		||||
                })
 | 
			
		||||
@@ -257,9 +263,9 @@
 | 
			
		||||
            value: "node",
 | 
			
		||||
            label: "node",
 | 
			
		||||
            icon: "red/images/typedInput/target.svg",
 | 
			
		||||
            valueLabel: function(container,value) {
 | 
			
		||||
            valueLabel: function (container, value) {
 | 
			
		||||
                var node = RED.nodes.node(value);
 | 
			
		||||
                var nodeDiv = $('<div>',{class:"red-ui-search-result-node"}).css({
 | 
			
		||||
                var nodeDiv = $('<div>', { class: "red-ui-search-result-node" }).css({
 | 
			
		||||
                    "margin-top": "2px",
 | 
			
		||||
                    "margin-left": "3px"
 | 
			
		||||
                }).appendTo(container);
 | 
			
		||||
@@ -268,117 +274,117 @@
 | 
			
		||||
                    "margin-left": "6px"
 | 
			
		||||
                }).appendTo(container);
 | 
			
		||||
                if (node) {
 | 
			
		||||
                    var colour = RED.utils.getNodeColor(node.type,node._def);
 | 
			
		||||
                    var icon_url = RED.utils.getNodeIcon(node._def,node);
 | 
			
		||||
                    var colour = RED.utils.getNodeColor(node.type, node._def);
 | 
			
		||||
                    var icon_url = RED.utils.getNodeIcon(node._def, node);
 | 
			
		||||
                    if (node.type === 'tab') {
 | 
			
		||||
                        colour = "#C0DEED";
 | 
			
		||||
                    }
 | 
			
		||||
                    nodeDiv.css('backgroundColor',colour);
 | 
			
		||||
                    var iconContainer = $('<div/>',{class:"red-ui-palette-icon-container"}).appendTo(nodeDiv);
 | 
			
		||||
                    nodeDiv.css('backgroundColor', colour);
 | 
			
		||||
                    var iconContainer = $('<div/>', { class: "red-ui-palette-icon-container" }).appendTo(nodeDiv);
 | 
			
		||||
                    RED.utils.createIconElement(icon_url, iconContainer, true);
 | 
			
		||||
                    var l = RED.utils.getNodeLabel(node,node.id);
 | 
			
		||||
                    var l = RED.utils.getNodeLabel(node, node.id);
 | 
			
		||||
                    nodeLabel.text(l);
 | 
			
		||||
                } else {
 | 
			
		||||
                    nodeDiv.css({
 | 
			
		||||
                        'backgroundColor': '#eee',
 | 
			
		||||
                        'border-style' : 'dashed'
 | 
			
		||||
                        'border-style': 'dashed'
 | 
			
		||||
                    });
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            expand: function() {
 | 
			
		||||
            expand: function () {
 | 
			
		||||
                var that = this;
 | 
			
		||||
                RED.tray.hide();
 | 
			
		||||
                RED.view.selectNodes({
 | 
			
		||||
                    single: true,
 | 
			
		||||
                    selected: [that.value()],
 | 
			
		||||
                    onselect: function(selection) {
 | 
			
		||||
                    onselect: function (selection) {
 | 
			
		||||
                        that.value(selection.id);
 | 
			
		||||
                        RED.tray.show();
 | 
			
		||||
                    },
 | 
			
		||||
                    oncancel: function() {
 | 
			
		||||
                    oncancel: function () {
 | 
			
		||||
                        RED.tray.show();
 | 
			
		||||
                    }
 | 
			
		||||
                })
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        cred:{
 | 
			
		||||
            value:"cred",
 | 
			
		||||
            label:"credential",
 | 
			
		||||
            icon:"fa fa-lock",
 | 
			
		||||
        cred: {
 | 
			
		||||
            value: "cred",
 | 
			
		||||
            label: "credential",
 | 
			
		||||
            icon: "fa fa-lock",
 | 
			
		||||
            inputType: "password",
 | 
			
		||||
            valueLabel: function(container,value) {
 | 
			
		||||
            valueLabel: function (container, value) {
 | 
			
		||||
                var that = this;
 | 
			
		||||
                container.css("pointer-events","none");
 | 
			
		||||
                container.css("flex-grow",0);
 | 
			
		||||
                container.css("pointer-events", "none");
 | 
			
		||||
                container.css("flex-grow", 0);
 | 
			
		||||
                this.elementDiv.hide();
 | 
			
		||||
                var buttons = $('<div>').css({
 | 
			
		||||
                    position: "absolute",
 | 
			
		||||
                    right:"6px",
 | 
			
		||||
                    right: "6px",
 | 
			
		||||
                    top: "6px",
 | 
			
		||||
                    "pointer-events":"all"
 | 
			
		||||
                    "pointer-events": "all"
 | 
			
		||||
                }).appendTo(container);
 | 
			
		||||
                var eyeButton = $('<button type="button" class="red-ui-button red-ui-button-small"></button>').css({
 | 
			
		||||
                    width:"20px"
 | 
			
		||||
                }).appendTo(buttons).on("click", function(evt) {
 | 
			
		||||
                    width: "20px"
 | 
			
		||||
                }).appendTo(buttons).on("click", function (evt) {
 | 
			
		||||
                    evt.preventDefault();
 | 
			
		||||
                    var cursorPosition = that.input[0].selectionStart;
 | 
			
		||||
                    var currentType = that.input.attr("type");
 | 
			
		||||
                    if (currentType === "text") {
 | 
			
		||||
                        that.input.attr("type","password");
 | 
			
		||||
                        that.input.attr("type", "password");
 | 
			
		||||
                        eyeCon.removeClass("fa-eye-slash").addClass("fa-eye");
 | 
			
		||||
                        setTimeout(function() {
 | 
			
		||||
                        setTimeout(function () {
 | 
			
		||||
                            that.input.focus();
 | 
			
		||||
                            that.input[0].setSelectionRange(cursorPosition, cursorPosition);
 | 
			
		||||
                        },50);
 | 
			
		||||
                        }, 50);
 | 
			
		||||
                    } else {
 | 
			
		||||
                        that.input.attr("type","text");
 | 
			
		||||
                        that.input.attr("type", "text");
 | 
			
		||||
                        eyeCon.removeClass("fa-eye").addClass("fa-eye-slash");
 | 
			
		||||
                        setTimeout(function() {
 | 
			
		||||
                        setTimeout(function () {
 | 
			
		||||
                            that.input.focus();
 | 
			
		||||
                            that.input[0].setSelectionRange(cursorPosition, cursorPosition);
 | 
			
		||||
                        },50);
 | 
			
		||||
                        }, 50);
 | 
			
		||||
                    }
 | 
			
		||||
                }).hide();
 | 
			
		||||
                var eyeCon = $('<i class="fa fa-eye"></i>').css("margin-left","-2px").appendTo(eyeButton);
 | 
			
		||||
                var eyeCon = $('<i class="fa fa-eye"></i>').css("margin-left", "-2px").appendTo(eyeButton);
 | 
			
		||||
 | 
			
		||||
                if (value === "__PWRD__") {
 | 
			
		||||
                    var innerContainer = $('<div><i class="fa fa-asterisk"></i><i class="fa fa-asterisk"></i><i class="fa fa-asterisk"></i><i class="fa fa-asterisk"></i><i class="fa fa-asterisk"></i></div>').css({
 | 
			
		||||
                        padding:"6px 6px",
 | 
			
		||||
                        borderRadius:"4px"
 | 
			
		||||
                        padding: "6px 6px",
 | 
			
		||||
                        borderRadius: "4px"
 | 
			
		||||
                    }).addClass("red-ui-typedInput-value-label-inactive").appendTo(container);
 | 
			
		||||
                    var editButton = $('<button type="button" class="red-ui-button red-ui-button-small"><i class="fa fa-pencil"></i></button>').appendTo(buttons).on("click", function(evt) {
 | 
			
		||||
                    var editButton = $('<button type="button" class="red-ui-button red-ui-button-small"><i class="fa fa-pencil"></i></button>').appendTo(buttons).on("click", function (evt) {
 | 
			
		||||
                        evt.preventDefault();
 | 
			
		||||
                        innerContainer.hide();
 | 
			
		||||
                        container.css("background","none");
 | 
			
		||||
                        container.css("pointer-events","none");
 | 
			
		||||
                        container.css("background", "none");
 | 
			
		||||
                        container.css("pointer-events", "none");
 | 
			
		||||
                        that.input.val("");
 | 
			
		||||
                        that.element.val("");
 | 
			
		||||
                        that.elementDiv.show();
 | 
			
		||||
                        editButton.hide();
 | 
			
		||||
                        cancelButton.show();
 | 
			
		||||
                        eyeButton.show();
 | 
			
		||||
                        setTimeout(function() {
 | 
			
		||||
                        setTimeout(function () {
 | 
			
		||||
                            that.input.focus();
 | 
			
		||||
                        },50);
 | 
			
		||||
                        }, 50);
 | 
			
		||||
                    });
 | 
			
		||||
                    var cancelButton = $('<button type="button" class="red-ui-button red-ui-button-small"><i class="fa fa-times"></i></button>').css("margin-left","3px").appendTo(buttons).on("click", function(evt) {
 | 
			
		||||
                    var cancelButton = $('<button type="button" class="red-ui-button red-ui-button-small"><i class="fa fa-times"></i></button>').css("margin-left", "3px").appendTo(buttons).on("click", function (evt) {
 | 
			
		||||
                        evt.preventDefault();
 | 
			
		||||
                        innerContainer.show();
 | 
			
		||||
                        container.css("background","");
 | 
			
		||||
                        container.css("background", "");
 | 
			
		||||
                        that.input.val("__PWRD__");
 | 
			
		||||
                        that.element.val("__PWRD__");
 | 
			
		||||
                        that.elementDiv.hide();
 | 
			
		||||
                        editButton.show();
 | 
			
		||||
                        cancelButton.hide();
 | 
			
		||||
                        eyeButton.hide();
 | 
			
		||||
                        that.input.attr("type","password");
 | 
			
		||||
                        that.input.attr("type", "password");
 | 
			
		||||
                        eyeCon.removeClass("fa-eye-slash").addClass("fa-eye");
 | 
			
		||||
 | 
			
		||||
                    }).hide();
 | 
			
		||||
                } else {
 | 
			
		||||
                    container.css("background","none");
 | 
			
		||||
                    container.css("pointer-events","none");
 | 
			
		||||
                    container.css("background", "none");
 | 
			
		||||
                    container.css("pointer-events", "none");
 | 
			
		||||
                    this.elementDiv.show();
 | 
			
		||||
                    eyeButton.show();
 | 
			
		||||
                }
 | 
			
		||||
@@ -1234,25 +1240,41 @@
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        validate: function() {
 | 
			
		||||
            var result;
 | 
			
		||||
            var value = this.value();
 | 
			
		||||
            var type = this.type();
 | 
			
		||||
            let valid = true;
 | 
			
		||||
            const value = this.value();
 | 
			
		||||
            const type = this.type();
 | 
			
		||||
            if (this.typeMap[type] && this.typeMap[type].validate) {
 | 
			
		||||
                var val = this.typeMap[type].validate;
 | 
			
		||||
                if (typeof val === 'function') {
 | 
			
		||||
                    result = val(value);
 | 
			
		||||
                const validate = this.typeMap[type].validate;
 | 
			
		||||
                if (typeof validate === 'function') {
 | 
			
		||||
                    valid = validate(value, {});
 | 
			
		||||
                } else {
 | 
			
		||||
                    result = val.test(value);
 | 
			
		||||
                    // Regex
 | 
			
		||||
                    valid = validate.test(value);
 | 
			
		||||
                    if (!valid) {
 | 
			
		||||
                        valid = RED._("validator.errors.invalid-regexp");
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            if ((typeof valid === "string") || !valid) {
 | 
			
		||||
                this.uiSelect.addClass("input-error");
 | 
			
		||||
                if (typeof valid === "string") {
 | 
			
		||||
                    let tooltip = this.element.data("tooltip");
 | 
			
		||||
                    if (tooltip) {
 | 
			
		||||
                        tooltip.setContent(valid);
 | 
			
		||||
                    } else {
 | 
			
		||||
                        tooltip = RED.popover.tooltip(this.elementDiv, valid);
 | 
			
		||||
                        this.element.data("tooltip", tooltip);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                result = true;
 | 
			
		||||
                this.uiSelect.removeClass("input-error");
 | 
			
		||||
                const tooltip = this.element.data("tooltip");
 | 
			
		||||
                if (tooltip) {
 | 
			
		||||
                    this.element.data("tooltip", null);
 | 
			
		||||
                    tooltip.delete();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            if (result) {
 | 
			
		||||
                this.uiSelect.removeClass('input-error');
 | 
			
		||||
            } else {
 | 
			
		||||
                this.uiSelect.addClass('input-error');
 | 
			
		||||
            }
 | 
			
		||||
            return result;
 | 
			
		||||
            return !!valid;
 | 
			
		||||
        },
 | 
			
		||||
        show: function() {
 | 
			
		||||
            this.uiSelect.show();
 | 
			
		||||
 
 | 
			
		||||
@@ -888,11 +888,25 @@ RED.utils = (function() {
 | 
			
		||||
        return parts;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function validatePropertyExpression(str) {
 | 
			
		||||
    /**
 | 
			
		||||
     * Validate a property expression
 | 
			
		||||
     * @param {*} str - the property value
 | 
			
		||||
     * @returns {boolean|string} whether the node proprty is valid. `true`: valid `false|String`: invalid
 | 
			
		||||
     */
 | 
			
		||||
    function validatePropertyExpression(str, opt) {
 | 
			
		||||
        try {
 | 
			
		||||
            var parts = normalisePropertyExpression(str);
 | 
			
		||||
            const parts = normalisePropertyExpression(str);
 | 
			
		||||
            return true;
 | 
			
		||||
        } catch(err) {
 | 
			
		||||
            // If the validator has opt, it is a 3.x validator that
 | 
			
		||||
            // can return a String to mean 'invalid' and provide a reason
 | 
			
		||||
            if (opt) {
 | 
			
		||||
                if (opt.label) {
 | 
			
		||||
                    return opt.label + ': ' + err.message;
 | 
			
		||||
                }
 | 
			
		||||
                return err.message;
 | 
			
		||||
            }
 | 
			
		||||
            // Otherwise, a 2.x returns a false value
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -906,23 +920,24 @@ RED.utils = (function() {
 | 
			
		||||
     * @returns true if valid, String if invalid
 | 
			
		||||
     */
 | 
			
		||||
    function validateTypedProperty(propertyValue, propertyType, opt) {
 | 
			
		||||
 | 
			
		||||
        let error
 | 
			
		||||
        let error;
 | 
			
		||||
        if (propertyType === 'json') {
 | 
			
		||||
            try {
 | 
			
		||||
                JSON.parse(propertyValue);
 | 
			
		||||
            } catch(err) {
 | 
			
		||||
                error = RED._("validator.errors.invalid-json", {
 | 
			
		||||
                    error: err.message
 | 
			
		||||
                })
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
        } else if (propertyType === 'msg' || propertyType === 'flow' || propertyType === 'global' ) {
 | 
			
		||||
            if (!RED.utils.validatePropertyExpression(propertyValue)) {
 | 
			
		||||
                error = RED._("validator.errors.invalid-prop")
 | 
			
		||||
            // To avoid double label
 | 
			
		||||
            const valid = RED.utils.validatePropertyExpression(propertyValue, opt ? {} : undefined);
 | 
			
		||||
            if (valid !== true) {
 | 
			
		||||
                error = opt ? valid : RED._("validator.errors.invalid-prop");
 | 
			
		||||
            }
 | 
			
		||||
        } else if (propertyType === 'num') {
 | 
			
		||||
            if (!/^NaN$|^[+-]?[0-9]*\.?[0-9]*([eE][-+]?[0-9]+)?$|^[+-]?(0b|0B)[01]+$|^[+-]?(0o|0O)[0-7]+$|^[+-]?(0x|0X)[0-9a-fA-F]+$/.test(propertyValue)) {
 | 
			
		||||
                error = RED._("validator.errors.invalid-num")
 | 
			
		||||
                error = RED._("validator.errors.invalid-num");
 | 
			
		||||
            }
 | 
			
		||||
        } else if (propertyType === 'jsonata') {
 | 
			
		||||
            try { 
 | 
			
		||||
@@ -930,16 +945,16 @@ RED.utils = (function() {
 | 
			
		||||
            } catch(err) {
 | 
			
		||||
                error = RED._("validator.errors.invalid-expr", {
 | 
			
		||||
                    error: err.message
 | 
			
		||||
                })
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (error) {
 | 
			
		||||
            if (opt && opt.label) {
 | 
			
		||||
                return opt.label+': '+error
 | 
			
		||||
                return opt.label + ': ' + error;
 | 
			
		||||
            }
 | 
			
		||||
            return error
 | 
			
		||||
            return error;
 | 
			
		||||
        }
 | 
			
		||||
        return true
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function getMessageProperty(msg,expr) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user