/* Authors: * Petr Vobornik * * Copyright (C) 2014 Red Hat * see file 'COPYING' for use and warranty information * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ define([ 'dojo/_base/lang', './text' ], function(lang, text) { function equals_obj_def(a, b, options) { var same = true; var checked = {}; var check_same = function(a, b, skip) { var same = true; skip = skip || {}; for (var key in a) { if (a.hasOwnProperty(key) && !(key in skip)) { var va = a[key]; var vb = b[key]; if (!equals(va, vb, options)) { same = false; skip[a] = true; break; } } } return same; }; same = check_same(a,b, checked); same = same && check_same(b,a, checked); return same; } function equals_obj(a, b, options) { if (options.comparator) { return options.comparator(a, b, options); } else { return equals_obj_def(a, b, options); } } function equals_array(a1, b1, options) { var a = a1, b = b1; if (!a || !b) return false; if (a1.length !== b1.length) return false; if (options.unordered) { a = a1.slice(0); b = b1.slice(0); a.sort(); b.sort(); } for (var i=0; i -1) { return false; } else if (a === null || b === null) { return false; } else if (lang.isArray(a)) { return equals_array(a, b, options); } else if (a instanceof Date) { return a.getTime() === b.getTime(); } else { // objects return equals_obj(a, b, options); } } function is_empty(value) { var empty = false; if (!value) empty = true; if (lang.isArray(value)) { empty = empty || value.length === 0 || (value.length === 1) && (value[0] === ''); } else if (typeof value === 'object') { var has_p = false; for (var p in value) { if (value.hasOwnProperty(p)) { has_p = true; break; } } empty = !has_p; } else if (value === '') empty = true; return empty; } function dirty(value, pristine, options) { // check for empty value: null, [''], '', [] var orig_empty = is_empty(pristine); var new_empty= is_empty(value); if (orig_empty && new_empty) return false; if (orig_empty != new_empty) return true; // strict equality - checks object's ref equality, numbers, strings if (value === pristine) return false; return !equals(value, pristine, options); } function format_single(formatter, value, error_text, method) { var val = value, ok = true, msg = null; try { if (method === 'format') { val = formatter.format(val); } else { val = formatter.parse(val); } } catch (e) { if (e.reason !== method) throw e; ok = false; value = e.value; msg = e.message || error_text; } return { ok: ok, value: val, message: msg }; } function format_core(formatter, value, error_text, method) { if (!formatter) return { ok: true, value: value }; if (lang.isArray(value)) { var res = { ok: true, value: [], messages: [] }; for (var i=0, l=value.length; i 1) res.message = error_text; else res.message = res.messages[0]; } } return res; } else { return format_single(formatter, value, error_text, method); } } function format(formatter, value, error_text) { var err = error_text || text.get('@i18n:widget.validation.format'); return format_core(formatter, value, err, 'format'); } function parse(formatter, value, error_text) { var err = error_text || text.get('@i18n:widget.validation.parse'); return format_core(formatter, value, err, 'parse'); } function normalize_value(value) { if (!(value instanceof Array)) { value = value !== undefined ? [value] : []; } return value; } function emit_delayed(target, type, event, delay) { delay = delay || 0; window.setTimeout(function() { target.emit(type, event); }, 0); } function beautify_message(message) { var els = []; var lines = message.split(/\n/g); var line_span; for (var i=0,l=lines.length; i', { 'class': 'error-message-hinted', text: lines[i].substr(1) }); els.push(line_span); } else { line_span = $('

', { text: lines[i] }); els.push(line_span); } } return els; } /** * Module with utility functions * @class * @singleton */ var util = { /** * Checks if two variables have equal value * * - `string`, `number`, `function`, `boolean`, `null`, * `undefined` are compared with strict equality * - 'object' and arrays are compared by values * * Available options: * * - `unordered` - boolean, sort arrays before value comparison. Does * not modify original values. * - `comparator`- function(a,b), returns bool - custom object comparator * * @param {Mixed} a * @param {Mixed} b * @param {String[]} [options] * @return {boolean} `a` and `b` are value-equal */ equals: equals, /** * Check if value is empty. * * True when: * * - value is undefined or `null` or `''` * - value is empty Array * - value is Array with an empty string (`''`) * - value is empty Object- `{}` * @param value - value to check * @return {boolean} */ is_empty: is_empty, /** * Special kind of negative `equals` where variants of `empty_value` are * considered same. * * @param {Mixed} value New value * @param {Mixed} pristine Pristine value * @param {String[]} [options] control options, same as in `equals` * @return {boolean} `value` and `pristine` differs */ dirty: dirty, /** * Format value or values using a formatter * * Output format for single values: * * { * ok: true|false, * value: null | formatted value, * message: null | string * } * * Output form for array: * * { * ok: true|false, * value: array of formatted values, * messages: array of error messages * message: null | string * } * * @param {IPA.formatter} formatter * @param {Mixed} value * @param {string} error Default error message * @return {Object} */ format: format, /** * Basically the same as format method, just uses formatter's `parse` * method instead of `format` method. * * @param {IPA.formatter} formatter * @param {Mixed} value * @param {string} error Default error message * @return {Object} */ parse: parse, /** * Encapsulates value into array if it's not already an array. * * @param {Mixed} value * @returns {Array} normalized value */ normalize_value: normalize_value, /** * Emit delayed event * * Uses timer in order to wait for current processing to finish. * * @param {Evented} object Source object which emits the event * @param {String} type Name of the event to emit * @param {Object} event Event object * @param {Number} [delay=0] */ emit_delayed: emit_delayed, /** * Beautify message * * Converts text value into array of HTML

elements. One additional * paragraph for each line break. * * Multi-lined text may contain TAB character as first char of the line * to hint at marking the whole line differently. * @param {string} text * @return {Array} array of jQuery elements */ beautify_message: beautify_message }; return util; });